1 package org.sourceforge.jemm.database.persistent.berkeley;
2
3 import java.util.HashSet;
4 import java.util.Iterator;
5 import java.util.Set;
6
7 import com.sleepycat.je.DatabaseException;
8 import com.sleepycat.persist.EntityCursor;
9 import com.sleepycat.persist.EntityStore;
10 import com.sleepycat.persist.PrimaryIndex;
11 import com.sleepycat.persist.SecondaryIndex;
12
13 import org.sourceforge.jemm.database.ClientId;
14 import org.sourceforge.jemm.database.ClientThreadId;
15 import org.sourceforge.jemm.database.components.ClientThreadIdRef;
16 import org.sourceforge.jemm.database.components.StorageEngineException;
17 import org.sourceforge.jemm.database.components.UserLockInfo;
18 import org.sourceforge.jemm.database.components.se.StorageEngineUserLockIF;
19 import org.sourceforge.jemm.types.ID;
20
21 public class BDbStorageEngineUserLockImpl implements StorageEngineUserLockIF {
22 private final PrimaryIndex<Long, UserLockEntry> userLockIdx;
23 private final PrimaryIndex<ClientLockKey, ClientLockEntry> clientKeyIdx;
24 private final SecondaryIndex<String, ClientLockKey, ClientLockEntry> clientKeyRevIdx;
25
26 public BDbStorageEngineUserLockImpl(EntityStore store) {
27 try {
28 userLockIdx = store.getPrimaryIndex(Long.class, UserLockEntry.class);
29 clientKeyIdx = store.getPrimaryIndex(ClientLockKey.class, ClientLockEntry.class);
30 clientKeyRevIdx = store.getSecondaryIndex(clientKeyIdx, String.class, "clientId");
31
32 clearAll();
33 } catch (DatabaseException e) {
34 throw new StorageEngineException("Error initialising user lock index " ,e);
35 }
36 }
37
38 @Override
39 public UserLockInfo getLockInfo(ID id) {
40 try {
41 UserLockEntry entry = userLockIdx.get(id.getIDValue());
42 if(entry == null) {
43 UserLockInfo lockInfo = new UserLockInfo(id);
44 return lockInfo;
45 } else
46 return entry.convert();
47 } catch (DatabaseException e) {
48 throw new StorageEngineException("Error in getLockInfo(" + id +")" ,e);
49 }
50 }
51
52 @Override public void saveLockInfo(UserLockInfo info) {
53 try {
54 if(info.isUnused())
55 userLockIdx.delete(info.getId().getIDValue());
56 else
57 userLockIdx.put(new UserLockEntry(info));
58 } catch (DatabaseException e) {
59 throw new StorageEngineException("Error in saveLockInfo(" + info +")" ,e);
60 }
61 }
62
63 @Override public void clearAll() {
64 try {
65 EntityCursor<Long> cursor = userLockIdx.keys();
66 try {
67 Iterator<Long> i = cursor.iterator();
68 while (i.hasNext()) {
69 i.next();
70 i.remove();
71 }
72 } finally {
73 cursor.close();
74 }
75
76 EntityCursor<ClientLockKey> clCursor = clientKeyIdx.keys();
77 try {
78 Iterator<ClientLockKey> i = clCursor.iterator();
79 while (i.hasNext()) {
80 i.next();
81 i.remove();
82 }
83 } finally {
84 clCursor.close();
85 }
86 } catch (DatabaseException e) {
87 throw new StorageEngineException("Error in clearAll()" ,e);
88 }
89 }
90
91 @Override
92 public void addClientLockReference(ClientThreadId clientThreadId, ID objectId) {
93 try {
94 clientKeyIdx.put(new ClientLockEntry(clientThreadId,objectId));
95 } catch (DatabaseException e) {
96 throw new StorageEngineException("addClientLockReference(" + clientThreadId + ","
97 + objectId + ")" ,e);
98 }
99 }
100
101 @Override
102 public Set<ClientThreadIdRef> getClientLockSet(ClientId clientId) {
103 try {
104
105 Set<ClientThreadIdRef> set = new HashSet<ClientThreadIdRef>();
106
107 EntityCursor<ClientLockEntry> ec = clientKeyRevIdx.entities(clientId.getInternalRep(), true,
108 clientId.getInternalRep(), true);
109
110 for (ClientLockEntry clientLockEntry : ec)
111 set.add(new ClientThreadIdRef(clientLockEntry.getClientThreadId(),
112 clientLockEntry.getObjectId()));
113 ec.close();
114 return set;
115 } catch (Exception e) {
116 throw new StorageEngineException("getClientLockSet(" + clientId + ")" ,e);
117 }
118 }
119
120 @Override
121 public void removeClientLockReference(ClientThreadId clientThreadId, ID objectId) {
122 try {
123 clientKeyIdx.delete(new ClientLockKey(clientThreadId,objectId));
124 } catch (DatabaseException e) {
125 throw new StorageEngineException("addClientLockReference(" + clientThreadId + ","
126 + objectId + ")" ,e);
127 }
128 }
129 }