KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > log > entry > LNLogEntry


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: LNLogEntry.java,v 1.38 2006/11/17 23:47:24 mark Exp $
7  */

8
9 package com.sleepycat.je.log.entry;
10
11 import java.nio.ByteBuffer JavaDoc;
12
13 import com.sleepycat.je.DatabaseException;
14 import com.sleepycat.je.dbi.DatabaseId;
15 import com.sleepycat.je.log.LogEntryType;
16 import com.sleepycat.je.log.LogUtils;
17 import com.sleepycat.je.log.LoggableObject;
18 import com.sleepycat.je.tree.Key;
19 import com.sleepycat.je.tree.LN;
20 import com.sleepycat.je.txn.Txn;
21 import com.sleepycat.je.utilint.DbLsn;
22
23 /**
24  * LNLogEntry embodies all LN transactional log entries.
25  * These entries contain:
26  * <pre>
27  * ln
28  * databaseid
29  * key
30  * abortLsn -- if transactional
31  * abortKnownDeleted -- if transactional
32  * txn -- if transactional
33  * </pre>
34  */

35 public class LNLogEntry implements LogEntry, LoggableObject, NodeLogEntry {
36
37     /* Objects contained in an LN entry */
38     private LN ln;
39     private DatabaseId dbId;
40     private byte[] key;
41     private long abortLsn = DbLsn.NULL_LSN;
42     private boolean abortKnownDeleted;
43     private Txn txn;
44     
45     private static final byte ABORT_KNOWN_DELETED_MASK = (byte) 1;
46
47     /* Class used to instantiate the main item in this entry */
48     private Class JavaDoc logClass; // used for reading a log entry
49
private LogEntryType entryType; // used for writing a log entry
50
private long nodeId;
51
52     /*
53      * Note: used this flag instead of splitting this class into a txnal and
54      * non-txnal version because we want to subclass it with the duplicate
55      * deleted entry, which also comes in txnal and non-txnal form.
56      */

57     private boolean isTransactional;
58
59     /* Constructor to read an entry. */
60     public LNLogEntry(Class JavaDoc logClass, boolean isTransactional) {
61         this.logClass = logClass;
62         this.isTransactional = isTransactional;
63     }
64
65     /* Constructor to write an entry. */
66     public LNLogEntry(LogEntryType entryType,
67                       LN ln,
68               DatabaseId dbId,
69               byte[] key,
70                       long abortLsn,
71               boolean abortKnownDeleted,
72               Txn txn) {
73         this.entryType = entryType;
74         this.ln = ln;
75         this.dbId = dbId;
76         this.key = key;
77         this.abortLsn = abortLsn;
78     this.abortKnownDeleted = abortKnownDeleted;
79         this.txn = txn;
80         this.isTransactional = (txn != null);
81         this.logClass = ln.getClass();
82         this.nodeId = ln.getNodeId();
83     }
84
85     /**
86      * @see LogEntry#readEntry
87      */

88     public void readEntry(ByteBuffer JavaDoc entryBuffer,
89               int entrySize,
90                           byte entryTypeVersion,
91               boolean readFullItem)
92         throws DatabaseException {
93
94         try {
95             if (readFullItem) {
96                 /* Read LN and get node ID. */
97                 ln = (LN) logClass.newInstance();
98                 ln.readFromLog(entryBuffer, entryTypeVersion);
99                 nodeId = ln.getNodeId();
100
101                 /* DatabaseImpl Id */
102                 dbId = new DatabaseId();
103                 dbId.readFromLog(entryBuffer, entryTypeVersion);
104
105                 /* Key */
106                 key = LogUtils.readByteArray(entryBuffer);
107
108                 if (isTransactional) {
109
110                     /*
111                      * AbortLsn. If it was a marker LSN that was used to fill
112                      * in a create, mark it null.
113                      */

114             abortLsn = LogUtils.readLong(entryBuffer);
115                     if (DbLsn.getFileNumber(abortLsn) ==
116                         DbLsn.getFileNumber(DbLsn.NULL_LSN)) {
117                         abortLsn = DbLsn.NULL_LSN;
118                     }
119
120                     abortKnownDeleted =
121                         ((entryBuffer.get() & ABORT_KNOWN_DELETED_MASK) != 0) ?
122                         true : false;
123
124                     /* Locker */
125                     txn = new Txn();
126                     txn.readFromLog(entryBuffer, entryTypeVersion);
127
128                     ln.setLastLoggedTransactionally();
129                 } else {
130                     ln.clearLastLoggedTransactionally();
131                 }
132             } else {
133
134                 /*
135                  * Read node ID and position to end.
136                  * We currently do not support getting the db and txn ID in
137                  * this mode, and we may want to change the log format to do
138                  * that efficiently.
139                  */

140                 int endPosition = entryBuffer.position() + entrySize;
141                 nodeId = LogUtils.readLong(entryBuffer);
142                 entryBuffer.position(endPosition);
143                 ln = null;
144             }
145         } catch (IllegalAccessException JavaDoc e) {
146             throw new DatabaseException(e);
147         } catch (InstantiationException JavaDoc e) {
148             throw new DatabaseException(e);
149         }
150     }
151
152     /**
153      * @see LogEntry#dumpEntry
154      */

155     public StringBuffer JavaDoc dumpEntry(StringBuffer JavaDoc sb, boolean verbose) {
156         ln.dumpLog(sb, verbose);
157         dbId.dumpLog(sb, verbose);
158         sb.append(Key.dumpString(key, 0));
159         if (isTransactional) {
160             if (abortLsn != DbLsn.NULL_LSN) {
161         sb.append(DbLsn.toString(abortLsn));
162             }
163         sb.append("<knownDeleted val=\"");
164         sb.append(abortKnownDeleted ? "true" : "false");
165         sb.append("\"/>");
166             txn.dumpLog(sb, verbose);
167         }
168         return sb;
169     }
170
171     /**
172      * @see LogEntry#getMainItem
173      */

174     public Object JavaDoc getMainItem() {
175         return ln;
176     }
177
178     /**
179      * @see LogEntry#clone
180      */

181     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
182         return super.clone();
183     }
184
185     /**
186      * @see LogEntry#isTransactional
187      */

188     public boolean isTransactional() {
189     return isTransactional;
190     }
191
192     /**
193      * @see LogEntry#getTransactionId
194      */

195     public long getTransactionId() {
196     if (isTransactional) {
197         return txn.getId();
198     } else {
199         return 0;
200     }
201     }
202
203     /**
204      * @see NodeLogEntry#getNodeId
205      */

206     public long getNodeId() {
207         return nodeId;
208     }
209
210     /*
211      * Writing support
212      */

213
214     /**
215      * @see LoggableObject#getLogType
216      */

217     public LogEntryType getLogType() {
218         return entryType;
219     }
220
221     /**
222      * @see LoggableObject#marshallOutsideWriteLatch
223      * Ask the ln if it can be marshalled outside the log write latch.
224      */

225     public boolean marshallOutsideWriteLatch() {
226         return ln.marshallOutsideWriteLatch();
227     }
228
229     /**
230      * Returns true for a deleted LN to count it immediately as obsolete.
231      * @see LoggableObject#countAsObsoleteWhenLogged
232      */

233     public boolean countAsObsoleteWhenLogged() {
234         return ln.isDeleted();
235     }
236
237     /**
238      * For LN entries, we need to record the latest LSN for that node with the
239      * owning transaction, within the protection of the log latch. This is a
240      * callback for the log manager to do that recording.
241      *
242      * @see LoggableObject#postLogWork
243      */

244     public void postLogWork(long justLoggedLsn)
245         throws DatabaseException {
246
247         if (isTransactional) {
248             txn.addLogInfo(justLoggedLsn);
249         }
250     }
251
252     /**
253      * Returns the given LN log size plus the size of the given key for the
254      * given transactional mode. Used by LN.delete and LN.modify to calculate
255      * the total obsolete log size of the previous version of the LNLogEntry
256      * without having the LNLogEntry instance in hand.
257      */

258     public static int getStaticLogSize(int lnLogSize,
259                                        byte[] key,
260                                        boolean transactional) {
261         int size = lnLogSize +
262             DatabaseId.LOG_SIZE +
263             LogUtils.getByteArrayLogSize(key);
264         if (transactional) {
265         size += LogUtils.getLongLogSize();
266         size++; // abortKnownDeleted
267
size += Txn.LOG_SIZE;
268         }
269         return size;
270     }
271
272     /**
273      * @see LoggableObject#getLogSize
274      */

275     public int getLogSize() {
276         return getStaticLogSize(ln.getLogSize(), key, isTransactional);
277     }
278
279     /**
280      * @see LoggableObject#writeToLog
281      */

282     public void writeToLog(ByteBuffer JavaDoc destBuffer) {
283         ln.writeToLog(destBuffer);
284         dbId.writeToLog(destBuffer);
285         LogUtils.writeByteArray(destBuffer, key);
286
287         if (isTransactional) {
288         LogUtils.writeLong(destBuffer, abortLsn);
289         byte aKD = 0;
290         if (abortKnownDeleted) {
291         aKD |= ABORT_KNOWN_DELETED_MASK;
292         }
293         destBuffer.put(aKD);
294             txn.writeToLog(destBuffer);
295             ln.setLastLoggedTransactionally();
296         } else {
297             ln.clearLastLoggedTransactionally();
298         }
299     }
300
301     /*
302      * Accessors
303      */

304     public LN getLN() {
305         return ln;
306     }
307
308     public DatabaseId getDbId() {
309         return dbId;
310     }
311
312     public byte[] getKey() {
313         return key;
314     }
315
316     public byte[] getDupKey() {
317         if (ln.isDeleted()) {
318             return null;
319         } else {
320             return ln.getData();
321         }
322     }
323
324     public long getAbortLsn() {
325         return abortLsn;
326     }
327
328     public boolean getAbortKnownDeleted() {
329     return abortKnownDeleted;
330     }
331
332     public Long JavaDoc getTxnId() {
333         if (isTransactional) {
334             return new Long JavaDoc(txn.getId());
335         } else {
336             return null;
337         }
338     }
339
340     public Txn getUserTxn() {
341         if (isTransactional) {
342             return txn;
343         } else {
344             return null;
345         }
346     }
347 }
348
Popular Tags