KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > mdr > persistence > btreeimpl > btreestorage > NormalBtreeExtent


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.mdr.persistence.btreeimpl.btreestorage;
20
21 import java.io.*;
22 import java.text.*;
23 import java.util.*;
24
25 import org.netbeans.mdr.persistence.*;
26 /**
27 * A NormalBtreeExtent is the first (and possibly only) extent in a record.
28 *
29 * <p>
30 * Disk format:
31 * <ol>
32 * <li>
33 * bytes 0-7 generic BtreeExtent header
34 * <li>
35 * bytes 8-9 key length (KL)
36 * <li>
37 * bytes 10-13 extent data length (DL)
38 * <li>
39 * bytes 14-17 record data length
40 * <li>
41 * bytes 18-17+KL key
42 * <li>
43 * bytes 18+KL-17+KL+DL data
44 * </ol>
45 * DL is data length for the extent plus any continuation extents.
46 * If there are continuation extents, all of the bytes in this extent are full,
47 * and the extent is of maximum size.
48 * <p>
49 * Note that the key must fit within the first chunk (the first 128 bytes).
50 * That is, keys of longer than MAX_KEY_LENGTH bytes are not allowed.
51 * <p>
52 * extent data length will be unequal to record data length if and only
53 * if there are continuation records.
54 */

55 class NormalBtreeExtent extends ActiveBtreeExtent {
56
57     /** size of fixed part of header */
58     static final int NORMAL_FIXED_LENGTH = 18;
59
60     /** maximum legal key length */
61     static final int MAX_KEY_LENGTH = BtreeDataFile.BTREE_CHUNK_SIZE - NORMAL_FIXED_LENGTH;
62
63     /** the record key */
64     byte key[];
65
66     /** the number of data bytes in the entire record */
67     int totalLength;
68
69     /** initialize a new NormalBtreeExtent
70     * @param file the BtreeDataFile this extent will belong to
71     * @param chunkNum where this extent begins
72     * @param numChunks the size of the extent
73     */

74     NormalBtreeExtent(BtreeDataFile file, int chunkNum, short numChunks) {
75         super(file, chunkNum, numChunks);
76     }
77
78     /** Convert a deleted extent to an active one. The deleted extent has
79     * already been removed from its chain
80     * @param del the extent to convert
81     * @param length data length
82     */

83     NormalBtreeExtent(DeletedBtreeExtent del, byte k[], int length) {
84         super(del);
85         key = k;
86         dataStart = NORMAL_FIXED_LENGTH + key.length;
87         setMyDataLength(length);
88     }
89
90     /** create a new NormalBtreeExtent in memory
91     * @param file the BtreeDataFile this extent will belong to
92     * @param chunkNum where this extent begins
93     * @param numChunks the size of the extent
94     * @param dLen how much data this extent will contain
95     * @param totLen hom much data the entire record will contain
96     * @param k the record's key
97     */

98     NormalBtreeExtent(
99         BtreeDataFile file, int chunkNum, short numChunks, int totLen, byte k[])
100                         throws StorageException {
101
102         super(file, chunkNum, numChunks);
103         if (k.length > MAX_KEY_LENGTH) {
104             throw new StorageBadRequestException(
105                 MessageFormat.format("Invalid key length: {0}",
106                     new Object JavaDoc[] {new Integer JavaDoc(k.length)} ));
107         }
108         key = k;
109         setMyDataLength(totLen);
110         totalLength = totLen;
111         dataStart = NORMAL_FIXED_LENGTH + key.length;
112         this.headerIsDirty = true;
113     }
114
115     /** read the type-specific parts of the extent header from the
116     * buffer.
117     * @param buffer the buffer to read from
118     * @param offset the offset to being reading at
119     */

120     void readHeaderFromPage(byte buffer[], IntHolder offset) {
121         short keyLen = Converter.readShort(buffer, offset);
122         key = new byte[keyLen];
123         dataLength = Converter.readInt(buffer, offset);
124         totalLength = Converter.readInt(buffer, offset);
125         System.arraycopy(buffer, offset.getValue(), key, 0, keyLen);
126         dataStart = NORMAL_FIXED_LENGTH + key.length;
127     }
128
129     /** write the type-specific part of the header to the file cache
130     * @param page the page to write to
131     * @param offset the offset to begin an
132     */

133     protected void writeHeaderToPage(CachedPage page, int offset) {
134         offset = Converter.writeShort(page.contents, offset, (short)key.length);
135         offset = Converter.writeInt(page.contents, offset, dataLength);
136         offset = Converter.writeInt(page.contents, offset, totalLength);
137         System.arraycopy(key, 0, page.contents, offset, key.length);
138     }
139
140     /** get the amount of data contained in this extent
141     * @return amount of data
142     */

143     int getMyDataLength() {
144         return dataLength;
145     }
146
147     /** get the amount of data contained in the entire record
148     * @return amount of data
149     */

150     int getTotalDataLength() {
151         return totalLength;
152     }
153
154     /** get how much data this extent could contain
155     * @return maximum amount of data which would fit
156     */

157     int getAvailableDataLength() {
158         return getAvailableDataLength(chunks, key.length);
159     }
160
161     /** Get the magic number for this type of extent
162     * @return the magic number
163     */

164     short getMagic() {
165         return NORMAL_MAGIC;
166     }
167
168     /** return the number of chunks an extent with this much data would
169     * occupy. If an extent of maximum size wouldn't hold this much,
170     * return the maximum extent size.
171     * @param dataLength amount of data to hold.
172     * @return size of extent in chunks
173     */

174     static int getNumChunks(int keyLength, int dataLength) {
175         int size = (keyLength + dataLength + NORMAL_FIXED_LENGTH - 1) /
176                                         BtreeDataFile.BTREE_CHUNK_SIZE + 1;
177         return Math.min(size, BtreeDataFile.MAX_CHUNKS_IN_EXTENT);
178     }
179
180     /** return the number of data bytes which can fit in a normal
181     * extent with the
182     * given key length
183     * @param numChunks size of extent in chunks
184     * @param keyLength length of key
185     * @return available data bytes
186     */

187     static int getAvailableDataLength(int numChunks, int keyLength) {
188         return (BtreeDataFile.BTREE_CHUNK_SIZE * numChunks)
189             - NORMAL_FIXED_LENGTH - keyLength;
190     }
191
192     /** set the amount of data contained in this extent
193     * @param length amount of data
194     */

195     int setMyDataLength(int length) {
196         int oldDataLength = dataLength;
197         dataLength = Math.min(length, getAvailableDataLength());
198         if (dataLength != oldDataLength) {
199             headerIsDirty = true;
200         }
201         if (totalLength != length) {
202             totalLength = length;
203             headerIsDirty = true;
204         }
205         return dataLength;
206     }
207
208     /** is the extent already full of data
209     * @return true if the extent has no room for more data
210     */

211     boolean isMaximum() {
212         return key.length + dataLength + NORMAL_FIXED_LENGTH
213                                     == BtreeDataFile.MAX_BYTES_IN_EXTENT;
214     }
215
216     /** return type of extent
217     * @return IS_NORMAL
218     */

219     byte getType() {
220         return IS_NORMAL;
221     }
222
223     /** return name of type of extent
224     * @return NORMAL_NAME
225     */

226     String JavaDoc getTypeName() {
227         return NORMAL_NAME;
228     }
229
230     /** dump extent as text (for debugging)
231     * @param level bitmask of what to dump. See the superclass for the
232     * meaning of level.
233     * @param strm where to dump it to
234     */

235     void dump(int level, PrintWriter strm)
236                     throws StorageException{
237
238         super.dump(level, strm);
239     if ((level & DUMP_BASIC) != 0) {
240         strm.println("" + totalLength + " bytes in record");
241         strm.println("" + key.length + " bytes in key");
242     }
243
244         if ((level & DUMP_KEY) != 0) {
245             dumpBytesAsHex(new ByteArrayInputStream(key), strm, "\t");
246         }
247     }
248 }
249
Popular Tags