@Override public void close() throws JasDBStorageException { openIndex(); fullLock.lock(); resourceLockManager.exclusiveLock(); try { if(channel != null) { closeIndexResources(); } } finally { resourceLockManager.exclusiveUnlock(true); fullLock.unlock(); } }
@Override public void openIndex() throws JasDBStorageException { if(closed) { throw new JasDBStorageException("Index is closed"); } else if(rootBlock == null) { fullLock.lock(); try { initializeIndex(); } finally { fullLock.unlock(); } } }
private Index createInStore(String bagName, KeyInfo keyInfo) throws JasDBStorageException { if(!indexes.containsKey(bagName)) { loadIndexes(bagName); } Map<String, Index> bagIndexes = this.indexes.get(bagName); if(bagIndexes != null && !bagIndexes.containsKey(keyInfo.getKeyName())) { File indexFile = createIndexFile(bagName, keyInfo.getKeyName(), false); try { Index index = new BTreeIndex(indexFile, keyInfo); configureIndex(IndexTypes.BTREE, index); IndexDefinition definition = new IndexDefinition(keyInfo.getKeyName(), keyInfo.keyAsHeader(), keyInfo.valueAsHeader(), index.getIndexType()); metadataStore.addBagIndex(instanceId, bagName, definition); bagIndexes.put(keyInfo.getKeyName(), index); return index; } catch(ConfigurationException e) { throw new JasDBStorageException("Unable to create index, configuration error", e); } } else if(bagIndexes != null){ return bagIndexes.get(keyInfo.getKeyName()); } else { return null; } }
@Override public MemoryAware getMemoryManager() throws JasDBStorageException { openIndex(); return persister; }
@Override public void rebuildIndex(Iterator<IndexableItem> indexableItems) throws JasDBStorageException { fullLock.lock(); resourceLockManager.exclusiveLock(); try { resetIndex(); state = IndexState.REBUILDING; IndexRebuildUtil.bulkInsertIndex(this, keyInfo, indexableItems); flushIndex(); state = IndexState.OK; } finally { resourceLockManager.exclusiveUnlock(); fullLock.unlock(); } }
@Override public IndexSearchResultIteratorCollection searchIndex(SearchCondition searchCondition, SearchLimit searchLimit) throws JasDBStorageException { openIndex(); SearchOperation searchOperation; SearchCondition condition = searchCondition; if(searchCondition instanceof RangeCondition) { searchOperation = rangeSearchOperation; } else if(searchCondition instanceof NotEqualsCondition) { searchOperation = notEqualsSearchOperation; } else if(searchCondition instanceof EqualsCondition){ condition = handleEqualsToRange((EqualsCondition) searchCondition); if(condition == searchCondition) { searchOperation = equalsSearchOperation; } else { searchOperation = rangeSearchOperation; } } else { throw new JasDBStorageException("Search Condition is not supported by Btree"); } StatRecord searchRecord = StatisticsMonitor.createRecord("btree:search"); resourceLockManager.sharedLock(); try { return searchOperation.search(condition, searchLimit); } finally { resourceLockManager.sharedUnlock(); searchRecord.stop(); } }
@Override public void updateKey(Key oldKey, Key newKey) throws JasDBStorageException { openIndex(); StatRecord updateIndex = StatisticsMonitor.createRecord("btree:update"); resourceLockManager.sharedLock(); lockManager.startLockChain(); lockManager.acquireLock(LockIntentType.UPDATE, rootBlock); try { LeaveBlock leaveBlock = rootBlock.findLeaveBlock(LockIntentType.UPDATE, oldKey); doLeaveBlockUpdate(leaveBlock, newKey); } finally { lockManager.releaseLockChain(); resourceLockManager.sharedUnlock(); updateIndex.stop(); } }
@Override public void removeFromIndex(Key key) throws JasDBStorageException { openIndex(); resourceLockManager.sharedLock(); lockManager.startLockChain(); lockManager.acquireLock(LockIntentType.LEAVELOCK_OPTIMISTIC, rootBlock); try { LeaveBlock leaveBlock = rootBlock.findLeaveBlock(LockIntentType.LEAVELOCK_OPTIMISTIC, key); if(leaveBlock.size() == persister.getMinKeys()) { lockManager.releaseLockChain(); lockManager.startLockChain(); lockManager.acquireLock(LockIntentType.WRITE_EXCLUSIVE, rootBlock); leaveBlock = rootBlock.findLeaveBlock(LockIntentType.WRITE_EXCLUSIVE, key); doLeaveBlockRemove(leaveBlock, key); } else { doLeaveBlockRemove(leaveBlock, key); } } finally { lockManager.releaseLockChain(); resourceLockManager.sharedUnlock(); } }
@Override public void insertIntoIndex(Key key) throws JasDBStorageException { openIndex(); StatRecord btreeInsertRecord = StatisticsMonitor.createRecord("btree:insert"); resourceLockManager.sharedLock(); lockManager.startLockChain(); lockManager.acquireLock(LockIntentType.LEAVELOCK_OPTIMISTIC, rootBlock); try { LeaveBlock leaveBlock = rootBlock.findLeaveBlock(LockIntentType.LEAVELOCK_OPTIMISTIC, key); if(leaveBlock.size() == persister.getMaxKeys()) { lockManager.releaseLockChain(); lockManager.startLockChain(); lockManager.acquireLock(LockIntentType.WRITE_EXCLUSIVE, rootBlock); leaveBlock = rootBlock.findLeaveBlock(LockIntentType.WRITE_EXCLUSIVE, key); doLeaveBlockInsert(leaveBlock, key); } else { //no overflow, we can just write into the leave doLeaveBlockInsert(leaveBlock, key); } } finally { lockManager.releaseLockChain(); resourceLockManager.sharedUnlock(); btreeInsertRecord.stop(); } }
private void resetIndex() throws JasDBStorageException { //we close so the old index can be removed and reopened with a new fresh file if(!closed) { closeIndexResources(); } if(!indexLocation.exists() || indexLocation.delete()) { closed = false; rootBlock = null; } else { throw new JasDBStorageException("Unable to reset index, old index could not be removed"); } }
private Index loadIndex(String bagName, IndexDefinition indexDefinition) throws JasDBStorageException { try { KeyInfo keyInfo = new KeyInfoImpl(indexDefinition.getHeaderDescriptor(), indexDefinition.getValueDescriptor()); File indexFile = createIndexFile(bagName, indexDefinition.getIndexName(), false); switch(IndexTypes.getTypeFor(indexDefinition.getIndexType())) { case BTREE: LOG.debug("Loaded BTree Index for key: {}", indexDefinition.getIndexName()); Index btreeIndex = new BTreeIndex(indexFile, keyInfo); return configureIndex(IndexTypes.BTREE, btreeIndex); default: throw new JasDBStorageException("Reading from this index type: " + indexDefinition.getIndexName() + " is not supported"); } } catch(ConfigurationException e) { throw new JasDBStorageException("Unable to load index, invalid configuration", e); } }
RootBlock getRootBlock() throws JasDBStorageException { openIndex(); return rootBlock; }
@Override public void removeIndex() throws JasDBStorageException { fullLock.lock(); resourceLockManager.exclusiveLock(); try { if(channel != null) { closeIndexResources(); } if(!indexLocation.delete()) { indexLocation.deleteOnExit(); } } finally { resourceLockManager.exclusiveUnlock(true); fullLock.lock(); } }
@Override public void openWriter() throws JasDBStorageException { this.keyInfo = new KeyInfoImpl(new SimpleIndexField("__ID", new UUIDKeyType()), new SimpleIndexField("RECORD_POINTER", new LongKeyType())); this.index = new BTreeIndex(indexLocation, keyInfo); this.writer.openWriter(); this.index.openIndex(); }
protected BlockPersister getPersister() throws JasDBStorageException { openIndex(); return persister; }
@Override public void openWriter() throws JasDBStorageException { this.keyInfo = new KeyInfoImpl(new SimpleIndexField("__ID", new UUIDKeyType()), new SimpleIndexField("data", new DataKeyType())); try { this.index = new BTreeIndex(recordStorageLocation, keyInfo); this.index.openIndex(); } catch(OverlappingFileLockException e) { throw new RecordStoreInUseException("Record datastore: " + recordStorageLocation + " is already in use, cannot be opened"); } }
protected LockManager getLockManager() throws JasDBStorageException { openIndex(); return lockManager; }
@Override public IndexIterator getIndexIterator() throws JasDBStorageException { openIndex(); return new FullIndexIterator(rootBlock, lockManager, persister); }
@Override public void flushIndex() throws JasDBStorageException { openIndex(); persister.flush(); }
@Override public IndexScanReport scan(ScanIntent intent, Iterator<IndexableItem> indexableItems) throws JasDBStorageException { try { openIndex(); fullLock.lock(); try { if(intent == ScanIntent.RESCAN || intent == ScanIntent.DETECT_INCOMPLETE || scanReport == null) { scanReport = IndexScanner.doIndexScan(this, keyInfo, indexableItems, intent != ScanIntent.DETECT_INCOMPLETE); } return scanReport; } finally { fullLock.unlock(); } } catch(JasDBStorageException e) { scanReport = new IndexScanReportImpl(IndexState.INVALID, System.currentTimeMillis(), 0); return scanReport; } }