use of com.orientechnologies.orient.core.exception.OSBTreeBonsaiLocalException in project orientdb by orientechnologies.
the class OSBTreeBonsaiBucket method addEntry.
public boolean addEntry(int index, SBTreeEntry<K, V> treeEntry, boolean updateNeighbors) throws IOException {
final int keySize = keySerializer.getObjectSize(treeEntry.key);
int valueSize = 0;
int entrySize = keySize;
if (isLeaf) {
assert valueSerializer.isFixedLength();
valueSize = valueSerializer.getFixedLength();
entrySize += valueSize;
checkEntreeSize(entrySize);
} else
entrySize += 2 * (OLongSerializer.LONG_SIZE + OIntegerSerializer.INT_SIZE);
int size = size();
int freePointer = getIntValue(offset + FREE_POINTER_OFFSET);
if (freePointer - entrySize < (size + 1) * OIntegerSerializer.INT_SIZE + POSITIONS_ARRAY_OFFSET) {
if (size > 1)
return false;
else
throw new OSBTreeBonsaiLocalException("Entry size ('key + value') is more than is more than allowed " + (freePointer - 2 * OIntegerSerializer.INT_SIZE + POSITIONS_ARRAY_OFFSET) + " bytes, either increase page size using '" + OGlobalConfiguration.SBTREEBONSAI_BUCKET_SIZE.getKey() + "' parameter, or decrease 'key + value' size.", tree);
}
if (index <= size - 1) {
moveData(offset + POSITIONS_ARRAY_OFFSET + index * OIntegerSerializer.INT_SIZE, offset + POSITIONS_ARRAY_OFFSET + (index + 1) * OIntegerSerializer.INT_SIZE, (size - index) * OIntegerSerializer.INT_SIZE);
}
freePointer -= entrySize;
setIntValue(offset + FREE_POINTER_OFFSET, freePointer);
setIntValue(offset + POSITIONS_ARRAY_OFFSET + index * OIntegerSerializer.INT_SIZE, freePointer);
setIntValue(offset + SIZE_OFFSET, size + 1);
if (isLeaf) {
byte[] serializedKey = new byte[keySize];
keySerializer.serializeNativeObject(treeEntry.key, serializedKey, 0);
setBinaryValue(offset + freePointer, serializedKey);
freePointer += keySize;
byte[] serializedValue = new byte[valueSize];
valueSerializer.serializeNativeObject(treeEntry.value, serializedValue, 0);
setBinaryValue(offset + freePointer, serializedValue);
} else {
setBucketPointer(offset + freePointer, treeEntry.leftChild);
freePointer += OLongSerializer.LONG_SIZE + OIntegerSerializer.INT_SIZE;
setBucketPointer(offset + freePointer, treeEntry.rightChild);
freePointer += OLongSerializer.LONG_SIZE + OIntegerSerializer.INT_SIZE;
byte[] serializedKey = new byte[keySize];
keySerializer.serializeNativeObject(treeEntry.key, serializedKey, 0);
setBinaryValue(offset + freePointer, serializedKey);
size++;
if (updateNeighbors && size > 1) {
if (index < size - 1) {
final int nextEntryPosition = getIntValue(offset + POSITIONS_ARRAY_OFFSET + (index + 1) * OIntegerSerializer.INT_SIZE);
setBucketPointer(offset + nextEntryPosition, treeEntry.rightChild);
}
if (index > 0) {
final int prevEntryPosition = getIntValue(offset + POSITIONS_ARRAY_OFFSET + (index - 1) * OIntegerSerializer.INT_SIZE);
setBucketPointer(offset + prevEntryPosition + OLongSerializer.LONG_SIZE + OIntegerSerializer.INT_SIZE, treeEntry.leftChild);
}
}
}
return true;
}
use of com.orientechnologies.orient.core.exception.OSBTreeBonsaiLocalException in project orientdb by orientechnologies.
the class OSBTreeBonsaiLocal method delete.
/**
* Deletes a whole tree. Puts all its pages to free list for further reusage.
*/
@Override
public void delete() {
startOperation();
try {
final OAtomicOperation atomicOperation;
try {
atomicOperation = startAtomicOperation(false);
} catch (IOException e) {
throw OException.wrapException(new OSBTreeBonsaiLocalException("Error during sbtree deletion", this), e);
}
final Lock lock = FILE_LOCK_MANAGER.acquireExclusiveLock(fileId);
try {
final Queue<OBonsaiBucketPointer> subTreesToDelete = new LinkedList<OBonsaiBucketPointer>();
subTreesToDelete.add(rootBucketPointer);
recycleSubTrees(subTreesToDelete, atomicOperation);
endAtomicOperation(false, null);
} catch (Exception e) {
rollback(e);
throw OException.wrapException(new OSBTreeBonsaiLocalException("Error during delete of sbtree with name " + getName(), this), e);
} finally {
lock.unlock();
}
} finally {
completeOperation();
}
}
use of com.orientechnologies.orient.core.exception.OSBTreeBonsaiLocalException in project orientdb by orientechnologies.
the class OSBTreeBonsaiLocal method get.
@Override
public V get(K key) {
final OSessionStoragePerformanceStatistic statistic = performanceStatisticManager.getSessionPerformanceStatistic();
startOperation();
if (statistic != null)
statistic.startRidBagEntryReadTimer();
try {
atomicOperationsManager.acquireReadLock(this);
try {
final Lock lock = FILE_LOCK_MANAGER.acquireSharedLock(fileId);
try {
OAtomicOperation atomicOperation = atomicOperationsManager.getCurrentOperation();
BucketSearchResult bucketSearchResult = findBucket(key, atomicOperation);
if (bucketSearchResult.itemIndex < 0)
return null;
OBonsaiBucketPointer bucketPointer = bucketSearchResult.getLastPathItem();
OCacheEntry keyBucketCacheEntry = loadPage(atomicOperation, fileId, bucketPointer.getPageIndex(), false);
keyBucketCacheEntry.acquireSharedLock();
try {
OSBTreeBonsaiBucket<K, V> keyBucket = new OSBTreeBonsaiBucket<K, V>(keyBucketCacheEntry, bucketPointer.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, keyBucketCacheEntry), this);
return keyBucket.getEntry(bucketSearchResult.itemIndex).value;
} finally {
keyBucketCacheEntry.releaseSharedLock();
releasePage(atomicOperation, keyBucketCacheEntry);
}
} finally {
lock.unlock();
}
} catch (IOException e) {
throw OException.wrapException(new OSBTreeBonsaiLocalException("Error during retrieving of sbtree with name " + getName(), this), e);
} finally {
atomicOperationsManager.releaseReadLock(this);
}
} finally {
if (statistic != null)
statistic.stopRidBagEntryReadTimer(1);
completeOperation();
}
}
use of com.orientechnologies.orient.core.exception.OSBTreeBonsaiLocalException in project orientdb by orientechnologies.
the class OSBTreeBonsaiLocal method put.
@Override
public boolean put(K key, V value) {
final OSessionStoragePerformanceStatistic statistic = performanceStatisticManager.getSessionPerformanceStatistic();
startOperation();
if (statistic != null)
statistic.startRidBagEntryUpdateTimer();
try {
final OAtomicOperation atomicOperation;
try {
atomicOperation = startAtomicOperation(true);
} catch (IOException e) {
throw OException.wrapException(new OSBTreeBonsaiLocalException("Error during sbtree entrie put", this), e);
}
final Lock lock = FILE_LOCK_MANAGER.acquireExclusiveLock(fileId);
try {
BucketSearchResult bucketSearchResult = findBucket(key, atomicOperation);
OBonsaiBucketPointer bucketPointer = bucketSearchResult.getLastPathItem();
OCacheEntry keyBucketCacheEntry = loadPage(atomicOperation, fileId, bucketPointer.getPageIndex(), false);
keyBucketCacheEntry.acquireExclusiveLock();
OSBTreeBonsaiBucket<K, V> keyBucket = new OSBTreeBonsaiBucket<K, V>(keyBucketCacheEntry, bucketPointer.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, keyBucketCacheEntry), this);
final boolean itemFound = bucketSearchResult.itemIndex >= 0;
boolean result = true;
if (itemFound) {
final int updateResult = keyBucket.updateValue(bucketSearchResult.itemIndex, value);
assert updateResult == 0 || updateResult == 1;
result = updateResult != 0;
} else {
int insertionIndex = -bucketSearchResult.itemIndex - 1;
while (!keyBucket.addEntry(insertionIndex, new OSBTreeBonsaiBucket.SBTreeEntry<K, V>(OBonsaiBucketPointer.NULL, OBonsaiBucketPointer.NULL, key, value), true)) {
keyBucketCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, keyBucketCacheEntry);
bucketSearchResult = splitBucket(bucketSearchResult.path, insertionIndex, key, atomicOperation);
bucketPointer = bucketSearchResult.getLastPathItem();
insertionIndex = bucketSearchResult.itemIndex;
keyBucketCacheEntry = loadPage(atomicOperation, fileId, bucketSearchResult.getLastPathItem().getPageIndex(), false);
keyBucketCacheEntry.acquireExclusiveLock();
keyBucket = new OSBTreeBonsaiBucket<K, V>(keyBucketCacheEntry, bucketPointer.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, keyBucketCacheEntry), this);
}
}
keyBucketCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, keyBucketCacheEntry);
if (!itemFound)
setSize(size() + 1, atomicOperation);
endAtomicOperation(false, null);
return result;
} catch (IOException e) {
rollback(e);
throw OException.wrapException(new OSBTreeBonsaiLocalException("Error during index update with key " + key + " and value " + value, this), e);
} finally {
lock.unlock();
}
} finally {
if (statistic != null)
statistic.stopRidBagEntryUpdateTimer();
completeOperation();
}
}
use of com.orientechnologies.orient.core.exception.OSBTreeBonsaiLocalException in project orientdb by orientechnologies.
the class OSBTreeBonsaiLocal method clear.
/**
* Removes all entries from bonsai tree. Put all but the root page to free list for further reuse.
*/
@Override
public void clear() {
startOperation();
try {
final OAtomicOperation atomicOperation;
try {
atomicOperation = startAtomicOperation(true);
} catch (IOException e) {
throw OException.wrapException(new OSBTreeBonsaiLocalException("Error during sbtree entrie clear", this), e);
}
final Lock lock = FILE_LOCK_MANAGER.acquireExclusiveLock(fileId);
try {
final Queue<OBonsaiBucketPointer> subTreesToDelete = new LinkedList<OBonsaiBucketPointer>();
OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, rootBucketPointer.getPageIndex(), false);
cacheEntry.acquireExclusiveLock();
try {
OSBTreeBonsaiBucket<K, V> rootBucket = new OSBTreeBonsaiBucket<K, V>(cacheEntry, rootBucketPointer.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, cacheEntry), this);
addChildrenToQueue(subTreesToDelete, rootBucket);
rootBucket.shrink(0);
rootBucket = new OSBTreeBonsaiBucket<K, V>(cacheEntry, rootBucketPointer.getPageOffset(), true, keySerializer, valueSerializer, getChanges(atomicOperation, cacheEntry), this);
rootBucket.setTreeSize(0);
} finally {
cacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, cacheEntry);
}
recycleSubTrees(subTreesToDelete, atomicOperation);
endAtomicOperation(false, null);
} catch (IOException e) {
rollback(e);
throw OException.wrapException(new OSBTreeBonsaiLocalException("Error during clear of sbtree with name " + getName(), this), e);
} catch (RuntimeException e) {
rollback(e);
throw e;
} finally {
lock.unlock();
}
} finally {
completeOperation();
}
}
Aggregations