KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > txn > BasicLocker


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: BasicLocker.java,v 1.84 2006/10/30 21:14:26 bostic Exp $
7  */

8
9 package com.sleepycat.je.txn;
10
11 import java.util.HashSet JavaDoc;
12 import java.util.Iterator JavaDoc;
13 import java.util.Set JavaDoc;
14
15 import com.sleepycat.je.Database;
16 import com.sleepycat.je.DatabaseException;
17 import com.sleepycat.je.LockStats;
18 import com.sleepycat.je.dbi.CursorImpl;
19 import com.sleepycat.je.dbi.DatabaseImpl;
20 import com.sleepycat.je.dbi.EnvironmentImpl;
21 import com.sleepycat.je.utilint.DbLsn;
22
23 /**
24  * A concrete Locker that simply tracks locks and releases them when
25  * operationEnd is called.
26  */

27 public class BasicLocker extends Locker {
28
29     /*
30      * A BasicLocker can release all locks, so there is no need to distinguish
31      * between read and write locks.
32      *
33      * ownedLock is used for the first lock obtained, and ownedLockSet is
34      * instantiated and used only if more than one lock is obtained. This is
35      * an optimization for the common case where only one lock is held by a
36      * non-transactional locker.
37      *
38      * There's no need to track memory utilization for these non-txnal lockers,
39      * because the lockers are short lived.
40      */

41     private Lock ownedLock;
42     private Set JavaDoc ownedLockSet;
43
44     /**
45      * Creates a BasicLocker.
46      */

47     public BasicLocker(EnvironmentImpl env)
48         throws DatabaseException {
49
50         super(env, false, false);
51     }
52
53     /**
54      * BasicLockers always have a fixed id, because they are never used for
55      * recovery.
56      */

57     protected long generateId(TxnManager txnManager) {
58         return TxnManager.NULL_TXN_ID;
59     }
60
61     protected void checkState(boolean ignoreCalledByAbort)
62         throws DatabaseException {
63         /* Do nothing. */
64     }
65
66     /**
67      * @see Locker#lockInternal
68      * @Override
69      */

70     LockResult lockInternal(long nodeId,
71                             LockType lockType,
72                             boolean noWait,
73                             DatabaseImpl database)
74         throws DatabaseException {
75   
76     /* Does nothing in BasicLocker. synchronized is for posterity. */
77     synchronized (this) {
78         checkState(false);
79     }
80
81     long timeout = 0;
82         boolean useNoWait = noWait || defaultNoWait;
83         if (!useNoWait) {
84             synchronized (this) {
85                 timeout = lockTimeOutMillis;
86             }
87         }
88
89         /* Ask for the lock. */
90         LockGrantType grant = lockManager.lock
91             (nodeId, this, lockType, timeout, useNoWait, database);
92
93         return new LockResult(grant, null);
94     }
95
96     /**
97      * Get the txn that owns the lock on this node. Return null if there's no
98      * owning txn found.
99      */

100     public Locker getWriteOwnerLocker(long nodeId)
101         throws DatabaseException {
102    
103         return lockManager.getWriteOwnerLocker(new Long JavaDoc(nodeId));
104     }
105
106     /**
107      * Get the abort LSN for this node in the txn that owns the lock on this
108      * node. Return null if there's no owning txn found.
109      */

110     public long getOwnerAbortLsn(long nodeId)
111         throws DatabaseException {
112    
113         Locker ownerTxn = lockManager.getWriteOwnerLocker(new Long JavaDoc(nodeId));
114         if (ownerTxn != null) {
115             return ownerTxn.getAbortLsn(nodeId);
116         }
117         return DbLsn.NULL_LSN;
118     }
119
120     /**
121      * Is never transactional.
122      */

123     public boolean isTransactional() {
124         return false;
125     }
126
127     /**
128      * Is never serializable isolation.
129      */

130     public boolean isSerializableIsolation() {
131         return false;
132     }
133
134     /**
135      * Is never read-committed isolation.
136      */

137     public boolean isReadCommittedIsolation() {
138         return false;
139     }
140
141     /**
142      * No transactional locker is available.
143      */

144     public Txn getTxnLocker() {
145         return null;
146     }
147
148     /**
149      * Creates a new instance of this txn for the same environment. No
150      * transactional locks are held by this object, so no locks are retained.
151      */

152     public Locker newNonTxnLocker()
153         throws DatabaseException {
154
155         return new BasicLocker(envImpl);
156     }
157
158     /**
159      * Releases all locks, since all locks held by this locker are
160      * non-transactional.
161      */

162     public void releaseNonTxnLocks()
163         throws DatabaseException {
164
165         operationEnd(true);
166     }
167
168     /**
169      * Release locks at the end of the transaction.
170      */

171     public void operationEnd()
172         throws DatabaseException {
173
174         operationEnd(true);
175     }
176
177     /**
178      * Release locks at the end of the transaction.
179      */

180     public void operationEnd(boolean operationOK)
181         throws DatabaseException {
182
183         /*
184          * Don't remove locks from txn's lock collection until iteration is
185          * done, lest we get a ConcurrentModificationException during deadlock
186      * graph "display". [#9544]
187          */

188         if (ownedLock != null) {
189             lockManager.release(ownedLock, this);
190             ownedLock = null;
191         }
192         if (ownedLockSet != null) {
193             Iterator JavaDoc iter = ownedLockSet.iterator();
194             while (iter.hasNext()) {
195                 Lock l = (Lock) iter.next();
196                 lockManager.release(l, this);
197             }
198
199             /* Now clear lock collection. */
200             ownedLockSet.clear();
201         }
202
203         /* Unload delete info, but don't wake up the compressor. */
204         synchronized (this) {
205             if ((deleteInfo != null) &&
206         (deleteInfo.size() > 0)) {
207                 envImpl.addToCompressorQueue(deleteInfo.values(),
208                                              false); // no wakeup
209
deleteInfo.clear();
210             }
211         }
212     }
213
214     /**
215      * Transfer any MapLN locks to the db handle.
216      */

217     public void setHandleLockOwner(boolean ignore /*operationOK*/,
218                                    Database dbHandle,
219                                    boolean dbIsClosing)
220     throws DatabaseException {
221
222         if (dbHandle != null) {
223             if (!dbIsClosing) {
224                 transferHandleLockToHandle(dbHandle);
225             }
226             unregisterHandle(dbHandle);
227         }
228     }
229
230     /**
231      * This txn doesn't store cursors.
232      */

233     public void registerCursor(CursorImpl cursor)
234     throws DatabaseException {
235     }
236
237     /**
238      * This txn doesn't store cursors.
239      */

240     public void unRegisterCursor(CursorImpl cursor)
241     throws DatabaseException {
242     }
243
244     /*
245      * Transactional methods are all no-oped.
246      */

247
248     /**
249      * @return the abort LSN for this node.
250      */

251     public long getAbortLsn(long nodeId)
252         throws DatabaseException {
253
254         return DbLsn.NULL_LSN;
255     }
256
257     /**
258      * @return a dummy WriteLockInfo for this node.
259      */

260     public WriteLockInfo getWriteLockInfo(long nodeId)
261     throws DatabaseException {
262
263     return WriteLockInfo.basicWriteLockInfo;
264     }
265
266     public void markDeleteAtTxnEnd(DatabaseImpl db, boolean deleteAtCommit)
267         throws DatabaseException {
268
269         if (deleteAtCommit) {
270             db.deleteAndReleaseINs();
271         }
272     }
273
274     /**
275      * Add a lock to set owned by this transaction.
276      */

277     void addLock(Long JavaDoc nodeId,
278                  Lock lock,
279                  LockType type,
280                  LockGrantType grantStatus)
281         throws DatabaseException {
282
283         if (ownedLock == lock ||
284             (ownedLockSet != null &&
285          ownedLockSet.contains(lock))) {
286             return; // Already owned
287
}
288         if (ownedLock == null) {
289             ownedLock = lock;
290         } else {
291             if (ownedLockSet == null) {
292                 ownedLockSet = new HashSet JavaDoc();
293             }
294             ownedLockSet.add(lock);
295         }
296     }
297     
298     /**
299      * Remove a lock from the set owned by this txn.
300      */

301     void removeLock(long nodeId, Lock lock)
302         throws DatabaseException {
303
304         if (lock == ownedLock) {
305             ownedLock = null;
306         } else if (ownedLockSet != null) {
307             ownedLockSet.remove(lock);
308         }
309     }
310
311     /**
312      * Always false for this txn.
313      */

314     public boolean createdNode(long nodeId)
315         throws DatabaseException {
316
317         return false;
318     }
319
320     /**
321      * A lock is being demoted. Move it from the write collection into the read
322      * collection.
323      */

324     void moveWriteToReadLock(long nodeId, Lock lock) {
325     }
326
327     /**
328      * stats
329      */

330     public LockStats collectStats(LockStats stats)
331         throws DatabaseException {
332
333         if (ownedLock != null) {
334             if (ownedLock.isOwnedWriteLock(this)) {
335                 stats.setNWriteLocks(stats.getNWriteLocks() + 1);
336             } else {
337                 stats.setNReadLocks(stats.getNReadLocks() + 1);
338             }
339         }
340         if (ownedLockSet != null) {
341             Iterator JavaDoc iter = ownedLockSet.iterator();
342             
343             while (iter.hasNext()) {
344                 Lock l = (Lock) iter.next();
345                 if (l.isOwnedWriteLock(this)) {
346                     stats.setNWriteLocks(stats.getNWriteLocks() + 1);
347                 } else {
348                     stats.setNReadLocks(stats.getNReadLocks() + 1);
349                 }
350             }
351         }
352         return stats;
353     }
354 }
355
Popular Tags