use of com.orientechnologies.orient.core.storage.cache.OCacheEntry in project orientdb by orientechnologies.
the class OClusterPositionMap method resurrect.
public void resurrect(final long clusterPosition, final OClusterPositionMapBucket.PositionEntry entry) throws IOException {
startOperation();
try {
OAtomicOperation atomicOperation = startAtomicOperation(true);
acquireExclusiveLock();
try {
final long pageIndex = clusterPosition / OClusterPositionMapBucket.MAX_ENTRIES;
final int index = (int) (clusterPosition % OClusterPositionMapBucket.MAX_ENTRIES);
if (pageIndex >= getFilledUpTo(atomicOperation, fileId))
throw new OClusterPositionMapException("Passed in cluster position " + clusterPosition + " is outside of range of cluster-position map", this);
final OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, pageIndex, false, 1);
cacheEntry.acquireExclusiveLock();
try {
final OClusterPositionMapBucket bucket = new OClusterPositionMapBucket(cacheEntry, getChanges(atomicOperation, cacheEntry));
bucket.resurrect(index, entry);
} finally {
cacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, cacheEntry);
}
endAtomicOperation(false, null);
} catch (IOException e) {
endAtomicOperation(true, e);
throw OException.wrapException(new OClusterPositionMapException("Error of resurrecting mapping between logical and physical record position", this), e);
} catch (RuntimeException e) {
endAtomicOperation(true, e);
throw OException.wrapException(new OClusterPositionMapException("Error of resurrecting mapping between logical and physical record position", this), e);
} finally {
releaseExclusiveLock();
}
} finally {
completeOperation();
}
}
use of com.orientechnologies.orient.core.storage.cache.OCacheEntry in project orientdb by orientechnologies.
the class OLocalHashTable20 method load.
@Override
public void load(String name, OType[] keyTypes, boolean nullKeyIsSupported) {
acquireExclusiveLock();
try {
if (keyTypes != null)
this.keyTypes = Arrays.copyOf(keyTypes, keyTypes.length);
else
this.keyTypes = null;
this.nullKeyIsSupported = nullKeyIsSupported;
OAtomicOperation atomicOperation = atomicOperationsManager.getCurrentOperation();
fileStateId = openFile(atomicOperation, name + metadataConfigurationFileExtension);
final OCacheEntry hashStateEntry = loadPage(atomicOperation, fileStateId, 0, true);
hashStateEntryIndex = hashStateEntry.getPageIndex();
directory = new OHashTableDirectory(treeStateFileExtension, name, getFullName(), durableInNonTxMode, storage);
directory.open();
pinPage(atomicOperation, hashStateEntry);
try {
OHashIndexFileLevelMetadataPage page = new OHashIndexFileLevelMetadataPage(hashStateEntry, getChanges(atomicOperation, hashStateEntry), false);
keySerializer = (OBinarySerializer<K>) storage.getComponentsFactory().binarySerializerFactory.getObjectSerializer(page.getKeySerializerId());
valueSerializer = (OBinarySerializer<V>) storage.getComponentsFactory().binarySerializerFactory.getObjectSerializer(page.getValueSerializerId());
} finally {
releasePage(atomicOperation, hashStateEntry);
}
if (nullKeyIsSupported)
nullBucketFileId = openFile(atomicOperation, name + nullBucketFileExtension);
} catch (IOException e) {
throw OException.wrapException(new OIndexException("Exception during hash table loading"), e);
} finally {
releaseExclusiveLock();
}
}
use of com.orientechnologies.orient.core.storage.cache.OCacheEntry in project orientdb by orientechnologies.
the class OSBTree method put.
@SuppressWarnings("unchecked")
private boolean put(K key, V value, OIndexEngine.Validator<K, V> validator) {
final OSessionStoragePerformanceStatistic statistic = performanceStatisticManager.getSessionPerformanceStatistic();
startOperation();
if (statistic != null)
statistic.startIndexEntryUpdateTimer();
try {
final OAtomicOperation atomicOperation;
try {
atomicOperation = startAtomicOperation(true);
} catch (IOException e) {
throw OException.wrapException(new OSBTreeException("Error during sbtree entrie put", this), e);
}
acquireExclusiveLock();
try {
checkNullSupport(key);
if (key != null) {
final int keySize = keySerializer.getObjectSize(key, (Object[]) keyTypes);
final int valueSize = valueSerializer.getObjectSize(value);
if (keySize > MAX_KEY_SIZE)
throw new OTooBigIndexKeyException("Key size is more than allowed, operation was canceled. Current key size " + keySize + ", allowed " + MAX_KEY_SIZE, getName());
final boolean createLinkToTheValue = valueSize > MAX_EMBEDDED_VALUE_SIZE;
key = keySerializer.preprocess(key, (Object[]) keyTypes);
long valueLink = -1;
if (createLinkToTheValue)
valueLink = createLinkToTheValue(value, atomicOperation);
final OSBTreeValue<V> treeValue = new OSBTreeValue<V>(createLinkToTheValue, valueLink, createLinkToTheValue ? null : value);
BucketSearchResult bucketSearchResult = findBucket(key, atomicOperation);
OCacheEntry keyBucketCacheEntry = loadPage(atomicOperation, fileId, bucketSearchResult.getLastPathItem(), false);
keyBucketCacheEntry.acquireExclusiveLock();
OSBTreeBucket<K, V> keyBucket = new OSBTreeBucket<K, V>(keyBucketCacheEntry, keySerializer, keyTypes, valueSerializer, getChanges(atomicOperation, keyBucketCacheEntry));
if (validator != null) {
// assuming validation throws by default
boolean failure = true;
boolean ignored = false;
try {
final V oldValue = bucketSearchResult.itemIndex > -1 ? readValue(keyBucket.getValue(bucketSearchResult.itemIndex), atomicOperation) : null;
final Object result = validator.validate(key, oldValue, value);
if (result == OIndexEngine.Validator.IGNORE) {
ignored = true;
failure = false;
return false;
}
value = (V) result;
failure = false;
} finally {
if (failure || ignored) {
keyBucketCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, keyBucketCacheEntry);
}
if (// in case of a failure atomic operation will be ended in a usual way below
ignored)
endAtomicOperation(false, null);
}
}
int insertionIndex;
int sizeDiff;
if (bucketSearchResult.itemIndex >= 0) {
int updateResult = keyBucket.updateValue(bucketSearchResult.itemIndex, treeValue);
if (updateResult >= 0) {
keyBucketCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, keyBucketCacheEntry);
endAtomicOperation(false, null);
return true;
} else {
assert updateResult == -1;
long removedLinkedValue = keyBucket.remove(bucketSearchResult.itemIndex);
if (removedLinkedValue >= 0)
removeLinkedValue(removedLinkedValue, atomicOperation);
insertionIndex = bucketSearchResult.itemIndex;
sizeDiff = 0;
}
} else {
insertionIndex = -bucketSearchResult.itemIndex - 1;
sizeDiff = 1;
}
while (!keyBucket.addEntry(insertionIndex, new OSBTreeBucket.SBTreeEntry<K, V>(-1, -1, key, treeValue), true)) {
keyBucketCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, keyBucketCacheEntry);
bucketSearchResult = splitBucket(bucketSearchResult.path, insertionIndex, key, atomicOperation);
insertionIndex = bucketSearchResult.itemIndex;
keyBucketCacheEntry = loadPage(atomicOperation, fileId, bucketSearchResult.getLastPathItem(), false);
keyBucketCacheEntry.acquireExclusiveLock();
keyBucket = new OSBTreeBucket<K, V>(keyBucketCacheEntry, keySerializer, keyTypes, valueSerializer, getChanges(atomicOperation, keyBucketCacheEntry));
}
keyBucketCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, keyBucketCacheEntry);
if (sizeDiff != 0)
setSize(size() + sizeDiff, atomicOperation);
} else {
OCacheEntry cacheEntry;
boolean isNew = false;
if (getFilledUpTo(atomicOperation, nullBucketFileId) == 0) {
cacheEntry = addPage(atomicOperation, nullBucketFileId);
isNew = true;
} else
cacheEntry = loadPage(atomicOperation, nullBucketFileId, 0, false);
final int valueSize = valueSerializer.getObjectSize(value);
final boolean createLinkToTheValue = valueSize > MAX_EMBEDDED_VALUE_SIZE;
long valueLink = -1;
if (createLinkToTheValue)
valueLink = createLinkToTheValue(value, atomicOperation);
final OSBTreeValue<V> treeValue = new OSBTreeValue<V>(createLinkToTheValue, valueLink, createLinkToTheValue ? null : value);
int sizeDiff = 0;
boolean ignored = false;
cacheEntry.acquireExclusiveLock();
try {
final ONullBucket<V> nullBucket = new ONullBucket<V>(cacheEntry, getChanges(atomicOperation, cacheEntry), valueSerializer, isNew);
final OSBTreeValue<V> oldValue = nullBucket.getValue();
if (validator != null) {
final V oldValueValue = oldValue == null ? null : readValue(oldValue, atomicOperation);
final Object result = validator.validate(null, oldValueValue, value);
if (result == OIndexEngine.Validator.IGNORE) {
ignored = true;
return false;
}
value = (V) result;
}
if (oldValue != null)
sizeDiff = -1;
nullBucket.setValue(treeValue);
} finally {
cacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, cacheEntry);
if (ignored)
endAtomicOperation(false, null);
}
sizeDiff++;
setSize(size() + sizeDiff, atomicOperation);
}
endAtomicOperation(false, null);
return true;
} catch (IOException e) {
rollback(e);
throw OException.wrapException(new OSBTreeException("Error during index update with key " + key + " and value " + value, this), e);
} catch (RuntimeException e) {
rollback(e);
throw e;
} finally {
releaseExclusiveLock();
}
} finally {
if (statistic != null)
statistic.stopIndexEntryUpdateTimer();
completeOperation();
}
}
use of com.orientechnologies.orient.core.storage.cache.OCacheEntry in project orientdb by orientechnologies.
the class OSBTree method lastItem.
private BucketSearchResult lastItem(OAtomicOperation atomicOperation) throws IOException {
LinkedList<PagePathItemUnit> path = new LinkedList<PagePathItemUnit>();
long bucketIndex = ROOT_INDEX;
OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, bucketIndex, false);
cacheEntry.acquireSharedLock();
OSBTreeBucket<K, V> bucket = new OSBTreeBucket<K, V>(cacheEntry, keySerializer, keyTypes, valueSerializer, getChanges(atomicOperation, cacheEntry));
int itemIndex = bucket.size() - 1;
try {
while (true) {
if (!bucket.isLeaf()) {
if (itemIndex < -1) {
if (!path.isEmpty()) {
PagePathItemUnit pagePathItemUnit = path.removeLast();
bucketIndex = pagePathItemUnit.pageIndex;
itemIndex = pagePathItemUnit.itemIndex - 1;
} else
return null;
} else {
path.add(new PagePathItemUnit(bucketIndex, itemIndex));
if (itemIndex > -1) {
OSBTreeBucket.SBTreeEntry<K, V> entry = bucket.getEntry(itemIndex);
bucketIndex = entry.rightChild;
} else {
OSBTreeBucket.SBTreeEntry<K, V> entry = bucket.getEntry(0);
bucketIndex = entry.leftChild;
}
itemIndex = OSBTreeBucket.MAX_PAGE_SIZE_BYTES + 1;
}
} else {
if (bucket.isEmpty()) {
if (!path.isEmpty()) {
PagePathItemUnit pagePathItemUnit = path.removeLast();
bucketIndex = pagePathItemUnit.pageIndex;
itemIndex = pagePathItemUnit.itemIndex - 1;
} else
return null;
} else {
final ArrayList<Long> resultPath = new ArrayList<Long>(path.size() + 1);
for (PagePathItemUnit pathItemUnit : path) resultPath.add(pathItemUnit.pageIndex);
resultPath.add(bucketIndex);
return new BucketSearchResult(bucket.size() - 1, resultPath);
}
}
cacheEntry.releaseSharedLock();
releasePage(atomicOperation, cacheEntry);
cacheEntry = loadPage(atomicOperation, fileId, bucketIndex, false);
cacheEntry.acquireSharedLock();
bucket = new OSBTreeBucket<K, V>(cacheEntry, keySerializer, keyTypes, valueSerializer, getChanges(atomicOperation, cacheEntry));
if (itemIndex == OSBTreeBucket.MAX_PAGE_SIZE_BYTES + 1)
itemIndex = bucket.size() - 1;
}
} finally {
cacheEntry.releaseSharedLock();
releasePage(atomicOperation, cacheEntry);
}
}
use of com.orientechnologies.orient.core.storage.cache.OCacheEntry in project orientdb by orientechnologies.
the class OSBTree method splitNonRootBucket.
private BucketSearchResult splitNonRootBucket(List<Long> path, int keyIndex, K keyToInsert, long pageIndex, OSBTreeBucket<K, V> bucketToSplit, boolean splitLeaf, int indexToSplit, K separationKey, List<OSBTreeBucket.SBTreeEntry<K, V>> rightEntries, OAtomicOperation atomicOperation) throws IOException {
OCacheEntry rightBucketEntry = addPage(atomicOperation, fileId);
rightBucketEntry.acquireExclusiveLock();
try {
OSBTreeBucket<K, V> newRightBucket = new OSBTreeBucket<K, V>(rightBucketEntry, splitLeaf, keySerializer, keyTypes, valueSerializer, getChanges(atomicOperation, rightBucketEntry));
newRightBucket.addAll(rightEntries);
bucketToSplit.shrink(indexToSplit);
if (splitLeaf) {
long rightSiblingPageIndex = bucketToSplit.getRightSibling();
newRightBucket.setRightSibling(rightSiblingPageIndex);
newRightBucket.setLeftSibling(pageIndex);
bucketToSplit.setRightSibling(rightBucketEntry.getPageIndex());
if (rightSiblingPageIndex >= 0) {
final OCacheEntry rightSiblingBucketEntry = loadPage(atomicOperation, fileId, rightSiblingPageIndex, false);
rightSiblingBucketEntry.acquireExclusiveLock();
OSBTreeBucket<K, V> rightSiblingBucket = new OSBTreeBucket<K, V>(rightSiblingBucketEntry, keySerializer, keyTypes, valueSerializer, getChanges(atomicOperation, rightSiblingBucketEntry));
try {
rightSiblingBucket.setLeftSibling(rightBucketEntry.getPageIndex());
} finally {
rightSiblingBucketEntry.releaseExclusiveLock();
releasePage(atomicOperation, rightSiblingBucketEntry);
}
}
}
long parentIndex = path.get(path.size() - 2);
OCacheEntry parentCacheEntry = loadPage(atomicOperation, fileId, parentIndex, false);
parentCacheEntry.acquireExclusiveLock();
try {
OSBTreeBucket<K, V> parentBucket = new OSBTreeBucket<K, V>(parentCacheEntry, keySerializer, keyTypes, valueSerializer, getChanges(atomicOperation, parentCacheEntry));
OSBTreeBucket.SBTreeEntry<K, V> parentEntry = new OSBTreeBucket.SBTreeEntry<K, V>(pageIndex, rightBucketEntry.getPageIndex(), 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);
parentIndex = bucketSearchResult.getLastPathItem();
parentCacheEntry = loadPage(atomicOperation, fileId, parentIndex, false);
parentCacheEntry.acquireExclusiveLock();
insertionIndex = bucketSearchResult.itemIndex;
parentBucket = new OSBTreeBucket<K, V>(parentCacheEntry, keySerializer, keyTypes, valueSerializer, getChanges(atomicOperation, parentCacheEntry));
}
} finally {
parentCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, parentCacheEntry);
}
} finally {
rightBucketEntry.releaseExclusiveLock();
releasePage(atomicOperation, rightBucketEntry);
}
ArrayList<Long> resultPath = new ArrayList<Long>(path.subList(0, path.size() - 1));
if (comparator.compare(keyToInsert, separationKey) < 0) {
resultPath.add(pageIndex);
return new BucketSearchResult(keyIndex, resultPath);
}
resultPath.add(rightBucketEntry.getPageIndex());
if (splitLeaf) {
return new BucketSearchResult(keyIndex - indexToSplit, resultPath);
}
resultPath.add(rightBucketEntry.getPageIndex());
return new BucketSearchResult(keyIndex - indexToSplit - 1, resultPath);
}
Aggregations