1 package org.sourceforge.jemm.database.memory;
2
3 import java.util.Collections;
4 import java.util.HashSet;
5 import java.util.Iterator;
6 import java.util.Set;
7
8 import org.sourceforge.jemm.database.ClientId;
9 import org.sourceforge.jemm.database.components.se.StorageEngineClientRefIF;
10 import org.sourceforge.jemm.types.ID;
11 import org.sourceforge.jemm.util.ManagedItem;
12 import org.sourceforge.jemm.util.ManagedItemStore;
13
14 public class ClientRefIFImpl implements StorageEngineClientRefIF {
15
16 class ClientRefStore extends ManagedItemStore<ClientId, ClientRefInfo> {
17 @Override
18 protected ClientRefInfo createValueElement(ClientId clientId) {
19 return new ClientRefInfo(clientId);
20 }
21 }
22
23 static class ClientRefInfo extends ManagedItem<ClientId> {
24 Set<ID> referencedIds = new HashSet<ID>();
25
26 public ClientRefInfo(ClientId clientId) {
27 super(clientId);
28 }
29
30 public synchronized boolean addReference(ID id) {
31 if(referencedIds.contains(id))
32 return false;
33
34 referencedIds.add(id);
35 return true;
36 }
37
38 public synchronized boolean clearReference(ID id) {
39 if(!referencedIds.contains(id))
40 return false;
41
42 referencedIds.remove(id);
43 return true;
44 }
45
46
47
48
49 public synchronized boolean isEmpty() {
50 return referencedIds.size() == 0;
51 }
52
53
54
55
56
57 public synchronized boolean hasReference(ID id) {
58 return referencedIds.contains(id);
59 }
60
61 @Override
62 public boolean isUnused() {
63 return isEmpty();
64 }
65
66 public void clearAll() {
67 referencedIds.clear();
68 }
69 }
70
71 private ClientRefStore clientRefStore = new ClientRefStore();
72
73 @Override
74 public boolean recordReference(ClientId clientId, ID id) {
75 ClientRefInfo info = clientRefStore.acquire(clientId);
76 boolean refAdded = info.addReference(id);
77 clientRefStore.release(clientId);
78 return refAdded;
79 }
80
81 @Override
82 public void clearReference(ClientId clientId, ID id) {
83
84 ClientRefInfo info = clientRefStore.acquire(clientId,false);
85 if(info == null)
86 throw new IllegalStateException("Illegal reference clear on " + id + " by "
87 + clientId + " reference not held");
88 try {
89 if(!info.clearReference(id))
90 throw new IllegalStateException("Illegal reference clear on " + id + " by "
91 + clientId + " reference not held");
92 } finally {
93 clientRefStore.release(clientId);
94 }
95 }
96
97 @Override
98 public boolean hasReference(ClientId clientId, ID id) {
99 ClientRefInfo handler = clientRefStore.acquire(clientId,false);
100 if(handler == null)
101 return false;
102
103 boolean hasReference = handler.hasReference(id);
104 clientRefStore.release(clientId);
105
106 return hasReference;
107 }
108
109 @Override
110 public Iterator<ID> referenceIterator(ClientId clientId) {
111 ClientRefInfo handler = clientRefStore.acquire(clientId,false);
112 if(handler == null)
113 return Collections.<ID>emptySet().iterator();
114 else
115 return Collections.unmodifiableSet(handler.referencedIds).iterator();
116 }
117
118 @Override
119 public void removeAllRefs(ClientId clientId) {
120 ClientRefInfo info = clientRefStore.acquire(clientId,false);
121 if(info == null)
122 return;
123 try {
124 info.clearAll();
125 } finally {
126 clientRefStore.release(clientId);
127 }
128 }
129 }