KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > tree > DBIN


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

8
9 package com.sleepycat.je.tree;
10
11 import java.nio.ByteBuffer JavaDoc;
12 import java.util.Comparator JavaDoc;
13
14 import com.sleepycat.je.DatabaseException;
15 import com.sleepycat.je.dbi.CursorImpl;
16 import com.sleepycat.je.dbi.DatabaseId;
17 import com.sleepycat.je.dbi.DatabaseImpl;
18 import com.sleepycat.je.dbi.DbConfigManager;
19 import com.sleepycat.je.dbi.MemoryBudget;
20 import com.sleepycat.je.log.LogEntryType;
21 import com.sleepycat.je.log.LogException;
22 import com.sleepycat.je.log.LogUtils;
23 import com.sleepycat.je.log.LoggableObject;
24
25 /**
26  * A DBIN represents an Duplicate Bottom Internal Node in the JE tree.
27  */

28 public final class DBIN extends BIN implements LoggableObject {
29     private static final String JavaDoc BEGIN_TAG = "<dbin>";
30     private static final String JavaDoc END_TAG = "</dbin>";
31     
32     /**
33      * Full key for this set of duplicates.
34      */

35     private byte[] dupKey;
36
37     public DBIN() {
38         super();
39     }
40
41     public DBIN(DatabaseImpl db,
42                 byte[] identifierKey,
43                 int maxEntriesPerNode,
44                 byte[] dupKey,
45                 int level) {
46         super(db, identifierKey, maxEntriesPerNode, level);
47         this.dupKey = dupKey;
48     }
49
50     /**
51      * Create a new DBIN. Need this because we can't call newInstance()
52      * without getting a 0 node.
53      */

54     protected IN createNewInstance(byte[] identifierKey,
55                                    int maxEntries,
56                                    int level) {
57         return new DBIN(getDatabase(),
58                         identifierKey,
59                         maxEntries,
60                         dupKey,
61                         level);
62     }
63
64     /*
65      * Return whether the shared latch for this kind of node should be of the
66      * "always exclusive" variety. Presently, only IN's are actually latched
67      * shared. BINs, DINs, and DBINs are all latched exclusive only.
68      */

69     boolean isAlwaysLatchedExclusively() {
70     return true;
71     }
72
73     /* Duplicates have no mask on their levels. */
74     protected int generateLevel(DatabaseId dbId, int newLevel) {
75         return newLevel;
76     }
77
78     /**
79      * Return the comparator function to be used for DBINs. This is
80      * the user defined duplicate comparison function, if defined.
81      */

82     public final Comparator JavaDoc getKeyComparator() {
83         return getDatabase().getDuplicateComparator();
84     }
85
86     /**
87      * Return the key for this duplicate set.
88      */

89     public byte[] getDupKey() {
90         return dupKey;
91     }
92
93     /**
94      * Get the key (dupe or identifier) in child that is used to locate
95      * it in 'this' node.
96      */

97     public byte[] getChildKey(IN child)
98         throws DatabaseException {
99
100         return child.getIdentifierKey();
101     }
102
103     /*
104      * A DBIN uses the dupTree key in its searches.
105      */

106     public byte[] selectKey(byte[] mainTreeKey, byte[] dupTreeKey) {
107         return dupTreeKey;
108     }
109
110     /**
111      * Return the key for navigating through the duplicate tree.
112      */

113     public byte[] getDupTreeKey() {
114         return getIdentifierKey();
115     }
116
117     /**
118      * Return the key for navigating through the main tree.
119      */

120     public byte[] getMainTreeKey() {
121         return dupKey;
122     }
123
124     /**
125      * @return true if this node is a duplicate-bearing node type, false
126      * if otherwise.
127      */

128     public boolean containsDuplicates() {
129         return true;
130     }
131     
132     /**
133      * @return the log entry type to use for bin delta log entries.
134      */

135     LogEntryType getBINDeltaType() {
136         return LogEntryType.LOG_DUP_BIN_DELTA;
137     }
138
139     public BINReference createReference() {
140         return new DBINReference(getNodeId(), getDatabase().getId(),
141                                  getIdentifierKey(), dupKey);
142     }
143
144     /**
145      * Count up the memory usage attributable to this node alone.
146      */

147     protected long computeMemorySize() {
148         long size = super.computeMemorySize();
149         /* XXX Need to update size when changing the dupKey.
150        if (dupKey != null && dupKey.getKey() != null) {
151        size += MemoryBudget.byteArraySize(dupKey.getKey().length);
152        }
153         */

154         return size;
155     }
156
157     /* Called once at environment startup by MemoryBudget. */
158     public static long computeOverhead(DbConfigManager configManager)
159         throws DatabaseException {
160
161         /*
162      * Overhead consists of all the fields in this class plus the
163      * entry arrays in the IN class.
164          */

165         return MemoryBudget.DBIN_FIXED_OVERHEAD +
166         IN.computeArraysOverhead(configManager);
167     }
168     
169     protected long getMemoryOverhead(MemoryBudget mb) {
170         return mb.getDBINOverhead();
171     }
172
173     /*
174      * A DBIN cannot be the ancestor of any IN.
175      */

176     protected boolean canBeAncestor(boolean targetContainsDuplicates) {
177         return false;
178     }
179
180     /**
181      * @Override
182      */

183     boolean hasNonLNChildren() {
184         return false;
185     }
186
187     /**
188      * The following four methods access the correct fields in a
189      * cursor depending on whether "this" is a BIN or DBIN. For
190      * BIN's, the CursorImpl.index and CursorImpl.bin fields should be
191      * used. For DBIN's, the CursorImpl.dupIndex and CursorImpl.dupBin
192      * fields should be used.
193      */

194     BIN getCursorBIN(CursorImpl cursor) {
195         return cursor.getDupBIN();
196     }
197
198     BIN getCursorBINToBeRemoved(CursorImpl cursor) {
199         return cursor.getDupBINToBeRemoved();
200     }
201
202     int getCursorIndex(CursorImpl cursor) {
203         return cursor.getDupIndex();
204     }
205
206     void setCursorBIN(CursorImpl cursor, BIN bin) {
207         cursor.setDupBIN((DBIN) bin);
208     }
209
210     void setCursorIndex(CursorImpl cursor, int index) {
211         cursor.setDupIndex(index);
212     }
213
214     /*
215      * Depth first search through a duplicate tree looking for an LN that
216      * has nodeId. When we find it, set location.bin and index and return
217      * true. If we don't find it, return false.
218      *
219      * No latching is performed.
220      */

221     boolean matchLNByNodeId(TreeLocation location, long nodeId)
222     throws DatabaseException {
223
224     latch();
225     try {
226         for (int i = 0; i < getNEntries(); i++) {
227         LN ln = (LN) fetchTarget(i);
228         if (ln != null) {
229             if (ln.getNodeId() == nodeId) {
230             location.bin = this;
231             location.index = i;
232             location.lnKey = getKey(i);
233             location.childLsn = getLsn(i);
234             return true;
235             }
236         }
237         }
238
239         return false;
240     } finally {
241         releaseLatch();
242     }
243     }
244
245     /*
246      * DbStat support.
247      */

248     void accumulateStats(TreeWalkerStatsAccumulator acc) {
249     acc.processDBIN(this, new Long JavaDoc(getNodeId()), getLevel());
250     }
251
252     public String JavaDoc beginTag() {
253         return BEGIN_TAG;
254     }
255
256     public String JavaDoc endTag() {
257         return END_TAG;
258     }
259
260     /**
261      * For unit test support:
262      * @return a string that dumps information about this IN, without
263      */

264     public String JavaDoc dumpString(int nSpaces, boolean dumpTags) {
265         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
266         sb.append(TreeUtils.indent(nSpaces));
267         sb.append(beginTag());
268         sb.append('\n');
269
270         sb.append(TreeUtils.indent(nSpaces+2));
271         sb.append("<dupkey>");
272         sb.append(dupKey == null ? "" : Key.dumpString(dupKey, 0));
273         sb.append("</dupkey>");
274         sb.append('\n');
275
276         sb.append(super.dumpString(nSpaces, false));
277
278         sb.append(TreeUtils.indent(nSpaces));
279         sb.append(endTag());
280         return sb.toString();
281     }
282
283     /*
284      * Logging support
285      */

286
287     /**
288      * @see LoggableObject#getLogType
289      */

290     public LogEntryType getLogType() {
291         return LogEntryType.LOG_DBIN;
292     }
293
294     /**
295      * @see LoggableObject#getLogSize
296      */

297     public int getLogSize() {
298         int size = super.getLogSize(); // ancestors
299
size += LogUtils.getByteArrayLogSize(dupKey); // identifier key
300
return size;
301     }
302
303     /**
304      * @see LoggableObject#writeToLog
305      */

306     public void writeToLog(ByteBuffer JavaDoc logBuffer) {
307
308         // ancestors
309
super.writeToLog(logBuffer);
310
311         // identifier key
312
LogUtils.writeByteArray(logBuffer, dupKey);
313     }
314
315     /**
316      * @see BIN#readFromLog
317      */

318     public void readFromLog(ByteBuffer JavaDoc itemBuffer, byte entryTypeVersion)
319         throws LogException {
320
321         // ancestors
322
super.readFromLog(itemBuffer, entryTypeVersion);
323
324         // identifier key
325
dupKey = LogUtils.readByteArray(itemBuffer);
326     }
327     
328     /**
329      * DBINS need to dump their dup key
330      */

331     protected void dumpLogAdditional(StringBuffer JavaDoc sb) {
332         super.dumpLogAdditional(sb);
333         sb.append(Key.dumpString(dupKey, 0));
334     }
335
336     public String JavaDoc shortClassName() {
337         return "DBIN";
338     }
339 }
340
Popular Tags