View Javadoc

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           * @return true if no references are held, false otherwise.
48           */
49          public synchronized boolean isEmpty() {
50              return referencedIds.size() == 0;
51          }
52  
53          /**
54           * @param id
55           * @return true if this client holds a reference to the given object, false otherwise.
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 }