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.btreeimpl.btreeindex.*; 26 import org.netbeans.mdr.persistence.*; 27 import org.netbeans.mdr.util.Logger; 28 29 33 public class BtreeStorage implements Storage { 34 35 36 private static final String COUNTER_KEY = "counter"; 37 38 39 private static final String MAP1_INDEX_PREFIX = "storageIds:"; 40 41 42 private static final String MAP2_INDEX_PREFIX = "storageCodes:"; 43 44 45 private BtreeDatabase btreeDB; 46 47 48 private transient EntryTypeInfo mofIdEntryTypeInfo; 49 50 51 private transient byte[] buffer = new byte[8]; 52 53 54 MofidGenerator gen; 55 56 57 private final String btreeDBName; 58 59 String storageUUID; 60 61 62 private ObjectResolver resolver; 63 64 65 private SinglevaluedIndex storageIdsMap; 66 67 private SinglevaluedIndex storageCodesMap; 68 69 private int storageNumbersCounter; 70 71 private HashMap tempMap = null; 72 73 private HashMap tempMap2 = null; 74 75 private final Map properties; 76 77 82 public BtreeStorage(String name, Map properties) { 83 this.properties = properties; 84 Logger.getDefault().log("DATABASE: " + name); 85 btreeDBName = name; 86 storageUUID = (String ) properties.get(BtreeFactory.STORAGE_UUID); 87 if (storageUUID != null) 88 Logger.getDefault().log("Storage UUID: " + storageUUID); 89 90 } 91 92 Object getProperty(String name) { 93 return properties.get(name); 94 } 95 96 98 public String getName() { 99 return btreeDBName; 100 } 101 102 104 public synchronized String getStorageId() { 105 return gen.getMofidPrefix(); 106 } 107 108 public synchronized long getSerialNumber () { 109 return gen.getNextMofid(); 110 } 111 112 113 116 public boolean exists() { 117 return BtreeDatabase.exists(btreeDBName); 118 } 119 120 124 public synchronized boolean delete() throws StorageException { 125 checkRepositoryClosed(); 126 return BtreeDatabase.delete(btreeDBName); 127 } 128 129 133 public synchronized void create(boolean replace, ObjectResolver resolver) throws StorageException { 134 checkRepositoryClosed(); 135 if (exists()) { 136 if (replace) { 137 if (!delete()) { 138 throw new StorageBadRequestException( 139 MessageFormat.format( 140 "Unable to delete btree repository {0}", 141 new Object [] {btreeDBName} ) ); 142 } 143 } 144 else { 145 throw new StorageBadRequestException( 146 MessageFormat.format( 147 "Btree repository {0} already exists", 148 new Object [] {btreeDBName} ) ); 149 } 150 } 151 152 this.resolver = resolver; 153 btreeDB = new BtreeDatabase(btreeDBName, this, true); 154 gen = btreeDB.getMofidGenerator(); 155 storageIdsMap = createSinglevaluedIndex (MAP1_INDEX_PREFIX, 156 Storage.EntryType.STRING, Storage.EntryType.INT); 157 storageCodesMap = createSinglevaluedIndex (MAP2_INDEX_PREFIX, 158 Storage.EntryType.INT, Storage.EntryType.STRING); 159 } 160 161 167 public synchronized void open(boolean createIfNoExist, ObjectResolver resolver) 168 throws StorageException { 169 checkRepositoryClosed(); 170 if (exists()) { 171 this.resolver = resolver; 172 btreeDB = new BtreeDatabase(btreeDBName, this, false); 173 gen = btreeDB.getMofidGenerator(); 174 storageIdsMap = getSinglevaluedIndex (MAP1_INDEX_PREFIX); 175 storageCodesMap = getSinglevaluedIndex (MAP2_INDEX_PREFIX); 176 return; 177 } 178 179 if (createIfNoExist) { 180 create(false, resolver); 181 return; 182 } 183 184 throw new StorageBadRequestException( 185 MessageFormat.format( 186 "Btree repository {0} does not exist", 187 new Object [] {btreeDBName} ) ); 188 } 189 190 193 public synchronized void close() throws StorageException { 194 checkRepositoryOpen(); 195 btreeDB.close(); 196 btreeDB = null; 197 gen = null; 198 tempMap = null; 199 } 200 201 203 public synchronized SinglevaluedIndex getPrimaryIndex() throws StorageException { 204 checkRepositoryOpen(); 205 return btreeDB; 206 } 207 208 214 215 public synchronized SinglevaluedIndex createSinglevaluedIndex(String name, Storage.EntryType keyType, Storage.EntryType valueType) throws StorageException { 216 checkRepositoryOpen(); 217 SinglevaluedBtree index = 218 new SinglevaluedBtree(name, keyType, valueType, 219 new BtreeMDRSource(this, BtreeDatabase.PAGE_SIZE)); 220 btreeDB.addIndex(name, index, new MOFID(this)); 221 return index; 222 } 223 224 231 public synchronized MultivaluedOrderedIndex createMultivaluedOrderedIndex(String name, Storage.EntryType keyType, Storage.EntryType valueType, boolean unique) throws StorageException { 232 checkRepositoryOpen(); 233 MultivaluedOrderedBtree index = 234 new MultivaluedOrderedBtree(name, keyType, valueType, unique, 235 new BtreeMDRSource(this, BtreeDatabase.PAGE_SIZE)); 236 btreeDB.addIndex(name, index, new MOFID(this)); 237 return index; 238 } 239 240 248 public synchronized MultivaluedIndex createMultivaluedIndex(String name, Storage.EntryType keyType, Storage.EntryType valueType, boolean unique) throws StorageException { 249 checkRepositoryOpen(); 250 MultivaluedBtree index = 251 new MultivaluedBtree(name, keyType, valueType, unique, 252 new BtreeMDRSource(this, BtreeDatabase.PAGE_SIZE)); 253 btreeDB.addIndex(name, index, new MOFID(this)); 254 return index; 255 } 256 257 261 public synchronized Index getIndex(String name) throws StorageException { 262 checkRepositoryOpen(); 263 return (Index) btreeDB.fetchIndex(name); 264 } 265 266 270 public synchronized SinglevaluedIndex getSinglevaluedIndex(String name) throws StorageException { 271 Object idx = getIndex(name); 272 checkIndexType(idx, name, SinglevaluedIndex.class); 273 return (SinglevaluedIndex)idx; 274 } 275 276 280 public synchronized MultivaluedIndex getMultivaluedIndex(String name) throws StorageException { 281 Object idx = getIndex(name); 282 checkIndexType(idx, name, MultivaluedIndex.class); 283 return (MultivaluedIndex)idx; 284 } 285 286 290 public synchronized MultivaluedOrderedIndex getMultivaluedOrderedIndex(String name) throws StorageException { 291 Object idx = getIndex(name); 292 checkIndexType(idx, name, MultivaluedOrderedIndex.class); 293 return (MultivaluedOrderedIndex)idx; 294 } 295 296 299 public synchronized void dropIndex(String name) throws StorageException { 300 checkRepositoryOpen(); 301 btreeDB.dropIndex(name); 302 } 303 304 307 public void objectStateWillChange(Object key) throws StorageException { 308 } 310 311 314 public synchronized void objectStateChanged(Object key) throws StorageException { 315 checkRepositoryOpen(); 316 btreeDB.objectStateChanged(key); 317 } 318 319 323 public synchronized void commitChanges() throws StorageException { 324 checkRepositoryOpen(); 325 btreeDB.commitChanges(); 326 } 327 328 335 public synchronized void rollBackChanges() throws StorageException { 336 checkRepositoryOpen(); 337 btreeDB.rollbackChanges(); 338 close(); 339 open(false, resolver); 340 } 341 342 345 public synchronized void shutDown() throws StorageException { 346 checkRepositoryOpen(); 347 btreeDB.shutDown(); 348 } 349 350 355 public boolean supportsMultipleStorableIndexes() { 356 357 return false; 358 } 359 360 public synchronized void writeMOFID (java.io.OutputStream out, MOFID mofId) throws StorageException { 361 366 367 375 376 long mofidData = mofId.getSerialNumber(); 378 String storageId = mofId.getStorageID(); 379 short s; 380 if (this.getStorageId().equals(storageId)) { 381 s = (short) BtreeFactory.SAME_PREFIX_CODE; 382 } else if (BtreeFactory.INTERNAL_PREFIX.equals(storageId)) { 383 s = (short) BtreeFactory.INTERNAL_PREFIX_CODE; 384 } else { 385 s = (short) this.storageIdToNumber(storageId); 386 } 387 mofidData |= ((long) s) << 48; 388 try { 389 while (mofidData != 0) { 390 int b = ((int) mofidData) & 0x7f; 391 mofidData >>>= 7; 392 if (mofidData != 0) b |= 0x80; 393 out.write(b); 394 } 395 } catch (IOException e) { 396 throw (StorageException) Logger.getDefault().annotate(new StorageIOException(e), e); 397 } 398 } 399 400 public final void writeMOFIDData (java.io.OutputStream out, MOFID mofid) throws StorageException { 401 try { 402 out.write (this.getMOFIDData(mofid)); 403 } catch (IOException ioException) { 404 throw new StorageIOException (ioException); 405 } 406 } 407 408 public synchronized final byte[] getMOFIDData (MOFID mofid) throws StorageException { 409 if (this.mofIdEntryTypeInfo == null) { 410 this.mofIdEntryTypeInfo = EntryTypeInfo.getEntryTypeInfo(Storage.EntryType.MOFID,this); 411 } 412 return this.mofIdEntryTypeInfo.toBuffer(mofid); 413 } 414 415 public synchronized MOFID readMOFID (java.io.InputStream in) throws StorageException { 420 421 long mofidData = 0; 423 try { 424 int b; 425 int i = 0; 426 do { 427 b = in.read(); 428 mofidData |= ((long) (b & 0x7f)) << (i * 7); 429 i++; 430 } while ((b & 0x80) != 0); 431 int storageNumber = (int) (mofidData >> 48); 432 String storageId; 433 switch (storageNumber) { 434 case BtreeFactory.INTERNAL_PREFIX_CODE: 435 storageId = BtreeFactory.INTERNAL_PREFIX; 436 break; 437 case BtreeFactory.SAME_PREFIX_CODE: 438 storageId = this.getStorageId(); 439 break; 440 default: 441 storageId = this.numberToStorageId(storageNumber); 442 } 443 return new MOFID (mofidData & 0xffffffffffffL, storageId); 444 } catch (IOException e) { 445 throw (StorageException) Logger.getDefault().annotate(new StorageIOException(e), e); 446 } 447 448 458 } 459 460 public synchronized final MOFID readMOFIDData (java.io.InputStream in) throws StorageException { 461 if (this.mofIdEntryTypeInfo == null) { 462 this.mofIdEntryTypeInfo = EntryTypeInfo.getEntryTypeInfo(Storage.EntryType.MOFID, this); 463 } 464 try { 465 in.read (this.buffer); 466 return (MOFID) mofIdEntryTypeInfo.fromBuffer (this.buffer); 467 }catch (IOException ioException) { 468 throw new StorageIOException (ioException); 469 } 470 } 471 472 473 public synchronized MofidGenerator getMofidGenerator() { 474 return btreeDB.getMofidGenerator(); 475 } 476 477 479 public synchronized Map getMofidMap() { 480 return btreeDB.getMofidMap(); 481 } 482 483 486 private void initStorageIdsMap () throws StorageException { 487 Object value = storageIdsMap.getIfExists (COUNTER_KEY); 488 if (value == null) { 489 storageNumbersCounter = BtreeFactory.FIRST_EXTERNAL_CODE; 490 storageIdsMap.put (COUNTER_KEY, value = new Integer (storageNumbersCounter)); 491 } 492 storageNumbersCounter = ((Integer ) value).intValue (); 493 tempMap = new HashMap (); 494 tempMap2 = new HashMap (); 495 } 496 497 500 public synchronized int storageIdToNumber (String storageId) throws StorageException { 501 Object value; 502 if (tempMap == null) 503 initStorageIdsMap (); 504 value = tempMap.get (storageId); 505 if (value == null) { 506 value = storageIdsMap.getIfExists (storageId); 507 if (value == null) { 508 storageNumbersCounter++; 509 value = new Integer (storageNumbersCounter); 510 storageIdsMap.replace (COUNTER_KEY, value); 511 storageIdsMap.put (storageId, value); 512 storageCodesMap.put (value, storageId); 513 } 514 tempMap.put (storageId, value); 515 } 516 return ((Integer ) value).intValue (); 517 } 518 519 522 public synchronized String numberToStorageId (int number) throws StorageException { 523 Object value; 524 if (tempMap == null) 525 initStorageIdsMap (); 526 Object code = new Integer (number); 527 value = tempMap2.get (code); 528 if (value == null) { 529 value = storageCodesMap.get (code); 530 if (value == null) { 531 throw new StorageBadRequestException ("Unknown storage code requested: " + number); 532 } 533 tempMap2.put (code, value); 534 } 535 return (String ) value; 536 } 537 538 541 public synchronized Object resolveObject (MOFID key) throws StorageException { 542 return resolver.resolve (key.getStorageID(), key); 543 } 544 545 546 private void checkIndexType(Object idx, String idxName, Class idxType) 547 throws StorageException { 548 if (!idxType.isInstance(idx)) { 549 throw new StorageBadRequestException( 550 MessageFormat.format("{0} is not a {1}", 551 new Object [] { idxName, idxType.getName() } ) ); 552 } 553 } 554 555 556 private void checkRepositoryClosed() throws StorageException { 557 if (btreeDB != null) { 558 throw new StorageBadRequestException( 559 MessageFormat.format( 560 "The btree repository {0} is already open", 561 new Object [] { btreeDBName} ) ); 562 } 563 } 564 565 566 private void checkRepositoryOpen() throws StorageException { 567 if (btreeDB == null) { 568 throw new StorageBadRequestException( 569 MessageFormat.format( 570 "The btree repository {0} is not open", 571 new Object [] { btreeDBName} ) ); 572 } 573 } 574 575 } 576 577 | Popular Tags |