use of com.orientechnologies.orient.core.storage.cache.OCacheEntry in project orientdb by orientechnologies.
the class OSBTreeBonsaiLocal method reuseBucketFromFreeList.
private AllocationResult reuseBucketFromFreeList(OSysBucket sysBucket, OAtomicOperation atomicOperation) throws IOException {
final OBonsaiBucketPointer oldFreeListHead = sysBucket.getFreeListHead();
assert oldFreeListHead.isValid();
OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, oldFreeListHead.getPageIndex(), false);
cacheEntry.acquireExclusiveLock();
try {
final OSBTreeBonsaiBucket<K, V> bucket = new OSBTreeBonsaiBucket<K, V>(cacheEntry, oldFreeListHead.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, cacheEntry), this);
sysBucket.setFreeListHead(bucket.getFreeListPointer());
sysBucket.setFreeListLength(sysBucket.freeListLength() - 1);
} finally {
cacheEntry.releaseExclusiveLock();
}
return new AllocationResult(oldFreeListHead, cacheEntry);
}
use of com.orientechnologies.orient.core.storage.cache.OCacheEntry in project orientdb by orientechnologies.
the class OSBTreeBonsaiLocal method splitBucket.
private BucketSearchResult splitBucket(List<OBonsaiBucketPointer> path, int keyIndex, K keyToInsert, OAtomicOperation atomicOperation) throws IOException {
final OBonsaiBucketPointer bucketPointer = path.get(path.size() - 1);
OCacheEntry bucketEntry = loadPage(atomicOperation, fileId, bucketPointer.getPageIndex(), false);
bucketEntry.acquireExclusiveLock();
try {
OSBTreeBonsaiBucket<K, V> bucketToSplit = new OSBTreeBonsaiBucket<K, V>(bucketEntry, bucketPointer.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, bucketEntry), this);
final boolean splitLeaf = bucketToSplit.isLeaf();
final int bucketSize = bucketToSplit.size();
int indexToSplit = bucketSize >>> 1;
final K separationKey = bucketToSplit.getKey(indexToSplit);
final List<OSBTreeBonsaiBucket.SBTreeEntry<K, V>> rightEntries = new ArrayList<OSBTreeBonsaiBucket.SBTreeEntry<K, V>>(indexToSplit);
final int startRightIndex = splitLeaf ? indexToSplit : indexToSplit + 1;
for (int i = startRightIndex; i < bucketSize; i++) rightEntries.add(bucketToSplit.getEntry(i));
if (!bucketPointer.equals(rootBucketPointer)) {
final AllocationResult allocationResult = allocateBucket(atomicOperation);
OCacheEntry rightBucketEntry = allocationResult.getCacheEntry();
final OBonsaiBucketPointer rightBucketPointer = allocationResult.getPointer();
rightBucketEntry.acquireExclusiveLock();
try {
OSBTreeBonsaiBucket<K, V> newRightBucket = new OSBTreeBonsaiBucket<K, V>(rightBucketEntry, rightBucketPointer.getPageOffset(), splitLeaf, keySerializer, valueSerializer, getChanges(atomicOperation, rightBucketEntry), this);
newRightBucket.addAll(rightEntries);
bucketToSplit.shrink(indexToSplit);
if (splitLeaf) {
OBonsaiBucketPointer rightSiblingBucketPointer = bucketToSplit.getRightSibling();
newRightBucket.setRightSibling(rightSiblingBucketPointer);
newRightBucket.setLeftSibling(bucketPointer);
bucketToSplit.setRightSibling(rightBucketPointer);
if (rightSiblingBucketPointer.isValid()) {
final OCacheEntry rightSiblingBucketEntry = loadPage(atomicOperation, fileId, rightSiblingBucketPointer.getPageIndex(), false);
rightSiblingBucketEntry.acquireExclusiveLock();
OSBTreeBonsaiBucket<K, V> rightSiblingBucket = new OSBTreeBonsaiBucket<K, V>(rightSiblingBucketEntry, rightSiblingBucketPointer.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, rightSiblingBucketEntry), this);
try {
rightSiblingBucket.setLeftSibling(rightBucketPointer);
} finally {
rightSiblingBucketEntry.releaseExclusiveLock();
releasePage(atomicOperation, rightSiblingBucketEntry);
}
}
}
OBonsaiBucketPointer parentBucketPointer = path.get(path.size() - 2);
OCacheEntry parentCacheEntry = loadPage(atomicOperation, fileId, parentBucketPointer.getPageIndex(), false);
parentCacheEntry.acquireExclusiveLock();
try {
OSBTreeBonsaiBucket<K, V> parentBucket = new OSBTreeBonsaiBucket<K, V>(parentCacheEntry, parentBucketPointer.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, parentCacheEntry), this);
OSBTreeBonsaiBucket.SBTreeEntry<K, V> parentEntry = new OSBTreeBonsaiBucket.SBTreeEntry<K, V>(bucketPointer, rightBucketPointer, separationKey, null);
int insertionIndex = parentBucket.find(separationKey);
assert insertionIndex < 0;
insertionIndex = -insertionIndex - 1;
while (!parentBucket.addEntry(insertionIndex, parentEntry, true)) {
parentCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, parentCacheEntry);
BucketSearchResult bucketSearchResult = splitBucket(path.subList(0, path.size() - 1), insertionIndex, separationKey, atomicOperation);
parentBucketPointer = bucketSearchResult.getLastPathItem();
parentCacheEntry = loadPage(atomicOperation, fileId, parentBucketPointer.getPageIndex(), false);
parentCacheEntry.acquireExclusiveLock();
insertionIndex = bucketSearchResult.itemIndex;
parentBucket = new OSBTreeBonsaiBucket<K, V>(parentCacheEntry, parentBucketPointer.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, parentCacheEntry), this);
}
} finally {
parentCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, parentCacheEntry);
}
} finally {
rightBucketEntry.releaseExclusiveLock();
releasePage(atomicOperation, rightBucketEntry);
}
ArrayList<OBonsaiBucketPointer> resultPath = new ArrayList<OBonsaiBucketPointer>(path.subList(0, path.size() - 1));
if (comparator.compare(keyToInsert, separationKey) < 0) {
resultPath.add(bucketPointer);
return new BucketSearchResult(keyIndex, resultPath);
}
resultPath.add(rightBucketPointer);
if (splitLeaf) {
return new BucketSearchResult(keyIndex - indexToSplit, resultPath);
}
return new BucketSearchResult(keyIndex - indexToSplit - 1, resultPath);
} else {
long treeSize = bucketToSplit.getTreeSize();
final List<OSBTreeBonsaiBucket.SBTreeEntry<K, V>> leftEntries = new ArrayList<OSBTreeBonsaiBucket.SBTreeEntry<K, V>>(indexToSplit);
for (int i = 0; i < indexToSplit; i++) leftEntries.add(bucketToSplit.getEntry(i));
final AllocationResult leftAllocationResult = allocateBucket(atomicOperation);
OCacheEntry leftBucketEntry = leftAllocationResult.getCacheEntry();
OBonsaiBucketPointer leftBucketPointer = leftAllocationResult.getPointer();
final AllocationResult rightAllocationResult = allocateBucket(atomicOperation);
OCacheEntry rightBucketEntry = rightAllocationResult.getCacheEntry();
OBonsaiBucketPointer rightBucketPointer = rightAllocationResult.getPointer();
leftBucketEntry.acquireExclusiveLock();
try {
OSBTreeBonsaiBucket<K, V> newLeftBucket = new OSBTreeBonsaiBucket<K, V>(leftBucketEntry, leftBucketPointer.getPageOffset(), splitLeaf, keySerializer, valueSerializer, getChanges(atomicOperation, leftBucketEntry), this);
newLeftBucket.addAll(leftEntries);
if (splitLeaf)
newLeftBucket.setRightSibling(rightBucketPointer);
} finally {
leftBucketEntry.releaseExclusiveLock();
releasePage(atomicOperation, leftBucketEntry);
}
rightBucketEntry.acquireExclusiveLock();
try {
OSBTreeBonsaiBucket<K, V> newRightBucket = new OSBTreeBonsaiBucket<K, V>(rightBucketEntry, rightBucketPointer.getPageOffset(), splitLeaf, keySerializer, valueSerializer, getChanges(atomicOperation, rightBucketEntry), this);
newRightBucket.addAll(rightEntries);
if (splitLeaf)
newRightBucket.setLeftSibling(leftBucketPointer);
} finally {
rightBucketEntry.releaseExclusiveLock();
releasePage(atomicOperation, rightBucketEntry);
}
bucketToSplit = new OSBTreeBonsaiBucket<K, V>(bucketEntry, bucketPointer.getPageOffset(), false, keySerializer, valueSerializer, getChanges(atomicOperation, bucketEntry), this);
bucketToSplit.setTreeSize(treeSize);
bucketToSplit.addEntry(0, new OSBTreeBonsaiBucket.SBTreeEntry<K, V>(leftBucketPointer, rightBucketPointer, separationKey, null), true);
ArrayList<OBonsaiBucketPointer> resultPath = new ArrayList<OBonsaiBucketPointer>(path.subList(0, path.size() - 1));
if (comparator.compare(keyToInsert, separationKey) < 0) {
resultPath.add(leftBucketPointer);
return new BucketSearchResult(keyIndex, resultPath);
}
resultPath.add(rightBucketPointer);
if (splitLeaf)
return new BucketSearchResult(keyIndex - indexToSplit, resultPath);
return new BucketSearchResult(keyIndex - indexToSplit - 1, resultPath);
}
} finally {
bucketEntry.releaseExclusiveLock();
releasePage(atomicOperation, bucketEntry);
}
}
use of com.orientechnologies.orient.core.storage.cache.OCacheEntry in project orientdb by orientechnologies.
the class OSBTreeBonsaiLocal method loadEntriesBetween.
@Override
public void loadEntriesBetween(K keyFrom, boolean fromInclusive, K keyTo, boolean toInclusive, RangeResultListener<K, V> listener) {
final OSessionStoragePerformanceStatistic statistic = performanceStatisticManager.getSessionPerformanceStatistic();
int readEntries = 0;
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 bucketSearchResultFrom = findBucket(keyFrom, atomicOperation);
OBonsaiBucketPointer bucketPointerFrom = bucketSearchResultFrom.getLastPathItem();
int indexFrom;
if (bucketSearchResultFrom.itemIndex >= 0) {
indexFrom = fromInclusive ? bucketSearchResultFrom.itemIndex : bucketSearchResultFrom.itemIndex + 1;
} else {
indexFrom = -bucketSearchResultFrom.itemIndex - 1;
}
BucketSearchResult bucketSearchResultTo = findBucket(keyTo, atomicOperation);
OBonsaiBucketPointer bucketPointerTo = bucketSearchResultTo.getLastPathItem();
int indexTo;
if (bucketSearchResultTo.itemIndex >= 0) {
indexTo = toInclusive ? bucketSearchResultTo.itemIndex : bucketSearchResultTo.itemIndex - 1;
} else {
indexTo = -bucketSearchResultTo.itemIndex - 2;
}
int startIndex = indexFrom;
int endIndex;
OBonsaiBucketPointer bucketPointer = bucketPointerFrom;
resultsLoop: while (true) {
final OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, bucketPointer.getPageIndex(), false);
cacheEntry.acquireSharedLock();
try {
OSBTreeBonsaiBucket<K, V> bucket = new OSBTreeBonsaiBucket<K, V>(cacheEntry, bucketPointer.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, cacheEntry), this);
if (!bucketPointer.equals(bucketPointerTo))
endIndex = bucket.size() - 1;
else
endIndex = indexTo;
for (int i = startIndex; i <= endIndex; i++) {
if (!listener.addResult(bucket.getEntry(i))) {
readEntries++;
break resultsLoop;
}
}
if (bucketPointer.equals(bucketPointerTo))
break;
bucketPointer = bucket.getRightSibling();
if (bucketPointer.getPageIndex() < 0)
break;
} finally {
cacheEntry.releaseSharedLock();
releasePage(atomicOperation, cacheEntry);
}
startIndex = 0;
}
} finally {
lock.unlock();
}
} catch (IOException ioe) {
throw OException.wrapException(new OSBTreeBonsaiLocalException("Error during fetch of values between key " + keyFrom + " and key " + keyTo + " in sbtree " + getName(), this), ioe);
} finally {
atomicOperationsManager.releaseReadLock(this);
}
} finally {
if (statistic != null)
statistic.stopRidBagEntryReadTimer(readEntries);
completeOperation();
}
}
use of com.orientechnologies.orient.core.storage.cache.OCacheEntry in project orientdb by orientechnologies.
the class OSBTreeBonsaiLocal method initAfterCreate.
private void initAfterCreate(OAtomicOperation atomicOperation) throws IOException {
initSysBucket(atomicOperation);
final AllocationResult allocationResult = allocateBucket(atomicOperation);
OCacheEntry rootCacheEntry = allocationResult.getCacheEntry();
this.rootBucketPointer = allocationResult.getPointer();
rootCacheEntry.acquireExclusiveLock();
try {
OSBTreeBonsaiBucket<K, V> rootBucket = new OSBTreeBonsaiBucket<K, V>(rootCacheEntry, this.rootBucketPointer.getPageOffset(), true, keySerializer, valueSerializer, getChanges(atomicOperation, rootCacheEntry), this);
rootBucket.setTreeSize(0);
} finally {
rootCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, rootCacheEntry);
}
}
use of com.orientechnologies.orient.core.storage.cache.OCacheEntry in project orientdb by orientechnologies.
the class OSBTreeBonsaiLocal method attachFreeListHead.
private void attachFreeListHead(OBonsaiBucketPointer bucketPointer, OBonsaiBucketPointer freeListHead, OAtomicOperation atomicOperation) throws IOException {
OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, bucketPointer.getPageIndex(), false);
cacheEntry.acquireExclusiveLock();
try {
final OSBTreeBonsaiBucket<K, V> bucket = new OSBTreeBonsaiBucket<K, V>(cacheEntry, bucketPointer.getPageOffset(), keySerializer, valueSerializer, getChanges(atomicOperation, cacheEntry), this);
bucket.setFreeListPointer(freeListHead);
} finally {
cacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, cacheEntry);
}
}
Aggregations