1 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 52 abstract class BtreeExtent { 53 54 55 static final int NORMAL_MAGIC = 0x2A2A; 56 57 58 static final int CONTINUATION_MAGIC = 0x6B6B; 59 60 61 static final int DELETED_MAGIC = 0x5F5F; 62 63 64 final short chunks; 65 66 67 public static final int MAX_EXTENT_SIZE = 68 BtreeDataFile.BTREE_CHUNK_SIZE * BtreeDataFile.MAX_CHUNKS_IN_EXTENT; 69 70 71 int nextInChain; 72 73 74 final int myChunkNum; 75 76 77 boolean headerIsDirty; 78 79 80 final BtreeDataFile owner; 81 82 83 static final byte IS_NORMAL = 1; 84 static final byte IS_CONTINUATION = 2; 85 static final byte IS_DELETED = 3; 86 87 88 static final String NORMAL_NAME = "normal"; 89 static final String CONTINUATION_NAME = "continuation"; 90 static final String DELETED_NAME = "deleted"; 91 92 97 BtreeExtent(BtreeExtent src) { 98 chunks = src.chunks; 99 myChunkNum = src.myChunkNum; 100 owner = src.owner; 101 headerIsDirty = true; 102 } 103 104 109 BtreeExtent(BtreeDataFile file, int chunkNum, short numChunks) { 110 owner = file; 111 chunks = numChunks; 112 myChunkNum = chunkNum; 113 headerIsDirty = true; 114 } 115 116 124 final static BtreeExtent readExtent(BtreeDataFile dataFile, int chunkNum) 125 throws StorageException { 126 127 BtreeExtent extent = null; 128 IntHolder offset = new IntHolder(); 129 CachedPage page = dataFile.getChunk(chunkNum, offset); 130 try { 131 short magic = Converter.readShort(page.contents, offset); 132 short chunks = Converter.readShort(page.contents, offset); 133 134 switch (magic) { 135 case NORMAL_MAGIC: 136 extent = new NormalBtreeExtent(dataFile, chunkNum, chunks); 137 break; 138 139 case CONTINUATION_MAGIC: 140 extent = new ContinuationBtreeExtent( 141 dataFile, chunkNum, chunks); 142 break; 143 144 case DELETED_MAGIC: 145 extent = new DeletedBtreeExtent(dataFile, chunkNum, chunks); 146 break; 147 148 default: 149 throw new StoragePersistentDataException( 150 MessageFormat.format( 151 "Bad Magic Number {0} in header at offset {1}", 152 new Object [] { 153 new Integer (magic), 154 new Integer (chunkNum)})); 155 } 156 157 extent.nextInChain = Converter.readInt(page.contents, offset); 158 extent.headerIsDirty = false; 159 extent.readHeaderFromPage(page.contents, offset); 160 } 161 finally { 162 page.unpin(); 163 } 164 165 return extent; 166 } 167 168 173 abstract void readHeaderFromPage(byte buffer[], IntHolder offset); 174 175 179 final void writeHeader() throws StorageException { 180 if (!headerIsDirty) 181 return; 182 183 IntHolder offst = new IntHolder(); 184 CachedPage page = owner.getChunk(myChunkNum, offst); 185 try { 186 page.setWritable(); 187 Converter.writeShort(page.contents, offst, getMagic()); 188 Converter.writeShort(page.contents, offst, chunks); 189 Converter.writeInt(page.contents, offst, nextInChain); 190 writeHeaderToPage(page, offst.getValue()); 191 } 192 finally { 193 page.unpin(); 194 } 195 headerIsDirty = false; 196 } 197 198 202 protected abstract void writeHeaderToPage(CachedPage page, int offset); 203 204 207 abstract short getMagic(); 208 209 212 int getSize() { 213 return chunks; 214 } 215 216 220 void setNext(int next) { 221 if (nextInChain != next) { 222 nextInChain = next; 223 headerIsDirty = true; 224 } 225 } 226 227 230 void setNext(BtreeExtent next) { 231 setNext(next.myChunkNum); 232 } 233 234 238 int getNext() { 239 return nextInChain; 240 } 241 242 245 int getOffset() { 246 return myChunkNum; 247 } 248 249 252 abstract byte getType(); 253 254 257 abstract String getTypeName(); 258 259 263 static String getTypeName(int extentType) { 264 switch(extentType) { 265 case IS_NORMAL: 266 return NORMAL_NAME; 267 268 case IS_CONTINUATION: 269 return CONTINUATION_NAME; 270 271 case IS_DELETED: 272 return DELETED_NAME; 273 } 274 275 return "unknown"; 276 } 277 278 279 public static final int DUMP_BASIC = 1; 280 281 282 public static final int DUMP_KEY = 2; 283 284 285 public static final int DUMP_DATA = 4; 286 287 288 public static final int DUMP_DATA_CHECKSUM = 8; 289 290 305 void dump(int level, PrintWriter strm) 306 throws StorageException{ 307 if ((level & DUMP_BASIC) != 0) { 308 strm.println("Extent: " + myChunkNum); 309 strm.println("Type: " + this.getClass().getName()); 310 strm.println("Size: " + chunks); 311 if (nextInChain > 0) 312 strm.println("Next: " + nextInChain); 313 } 314 } 315 316 321 static void dumpBytesAsHex(InputStream in, PrintWriter out, String indent) { 322 323 try { 324 int position = 0; 325 int data; 326 while ((data = in.read()) >= 0) { 327 if (position >= 16) { 328 out.println(); 329 position = 0; 330 } 331 if (position == 0) 332 out.print(indent); 333 else 334 out.print(" "); 335 336 String hex = Integer.toHexString(data); 337 if (hex.length() == 1) 338 hex = "0" + hex; 339 out.print(hex); 340 position++; 341 } 342 if (position > 0) 343 out.println(); 344 } 345 catch (IOException exc) { 346 out.print("\n\nIO EXCEPTION!\n\n"); 347 } 348 } 349 } 350 | Popular Tags |