use of com.orientechnologies.orient.core.id.ORecordId in project orientdb by orientechnologies.
the class OPaginatedCluster method deleteRecord.
public boolean deleteRecord(long clusterPosition) throws IOException {
startOperation();
OSessionStoragePerformanceStatistic statistic = performanceStatisticManager.getSessionPerformanceStatistic();
if (statistic != null)
statistic.startRecordDeletionTimer();
try {
OAtomicOperation atomicOperation = startAtomicOperation(true);
acquireExclusiveLock();
try {
OClusterPositionMapBucket.PositionEntry positionEntry = clusterPositionMap.get(clusterPosition, 1);
if (positionEntry == null) {
endAtomicOperation(false, null);
return false;
}
long pageIndex = positionEntry.getPageIndex();
int recordPosition = positionEntry.getRecordPosition();
if (getFilledUpTo(atomicOperation, fileId) <= pageIndex) {
endAtomicOperation(false, null);
return false;
}
long nextPagePointer;
int removedContentSize = 0;
do {
boolean cacheEntryReleased = false;
OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, pageIndex, false);
cacheEntry.acquireExclusiveLock();
int initialFreePageIndex;
try {
OClusterPage localPage = new OClusterPage(cacheEntry, false, getChanges(atomicOperation, cacheEntry));
initialFreePageIndex = calculateFreePageIndex(localPage);
if (localPage.isDeleted(recordPosition)) {
if (removedContentSize == 0) {
cacheEntryReleased = true;
try {
cacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, cacheEntry);
} finally {
endAtomicOperation(false, null);
}
return false;
} else
throw new OPaginatedClusterException("Content of record " + new ORecordId(id, clusterPosition) + " was broken", this);
} else if (removedContentSize == 0) {
cacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, cacheEntry);
cacheEntry = loadPage(atomicOperation, fileId, pageIndex, false);
cacheEntry.acquireExclusiveLock();
localPage = new OClusterPage(cacheEntry, false, getChanges(atomicOperation, cacheEntry));
}
byte[] content = localPage.getRecordBinaryValue(recordPosition, 0, localPage.getRecordSize(recordPosition));
int initialFreeSpace = localPage.getFreeSpace();
localPage.deleteRecord(recordPosition);
removedContentSize += localPage.getFreeSpace() - initialFreeSpace;
nextPagePointer = OLongSerializer.INSTANCE.deserializeNative(content, content.length - OLongSerializer.LONG_SIZE);
} finally {
if (!cacheEntryReleased) {
cacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, cacheEntry);
}
}
updateFreePagesIndex(fileId, pinnedStateEntryIndex, initialFreePageIndex, pageIndex, atomicOperation);
pageIndex = getPageIndex(nextPagePointer);
recordPosition = getRecordPosition(nextPagePointer);
} while (nextPagePointer >= 0);
updateClusterState(fileId, pinnedStateEntryIndex, -1, -removedContentSize, atomicOperation);
clusterPositionMap.remove(clusterPosition);
addAtomicOperationMetadata(new ORecordId(id, clusterPosition), atomicOperation);
endAtomicOperation(false, null);
return true;
} catch (IOException e) {
endAtomicOperation(true, e);
throw OException.wrapException(new OPaginatedClusterException("Error during record deletion", this), e);
} catch (RuntimeException e) {
endAtomicOperation(true, e);
throw OException.wrapException(new OPaginatedClusterException("Error during record deletion", this), e);
} finally {
releaseExclusiveLock();
}
} finally {
if (statistic != null)
statistic.stopRecordDeletionTimer();
completeOperation();
}
}
use of com.orientechnologies.orient.core.id.ORecordId in project orientdb by orientechnologies.
the class OPaginatedCluster method updateRecord.
public void updateRecord(final long clusterPosition, byte[] content, final int recordVersion, final byte recordType) throws IOException {
startOperation();
OSessionStoragePerformanceStatistic statistic = performanceStatisticManager.getSessionPerformanceStatistic();
if (statistic != null)
statistic.startRecordUpdateTimer();
try {
content = compression.compress(content);
content = encryption.encrypt(content);
OAtomicOperation atomicOperation = startAtomicOperation(true);
acquireExclusiveLock();
try {
final OClusterPositionMapBucket.PositionEntry positionEntry = clusterPositionMap.get(clusterPosition, 1);
if (positionEntry == null) {
endAtomicOperation(false, null);
return;
}
int nextRecordPosition = positionEntry.getRecordPosition();
long nextPageIndex = positionEntry.getPageIndex();
int newRecordPosition = -1;
long newPageIndex = -1;
long prevPageIndex = -1;
int prevRecordPosition = -1;
long nextEntryPointer = -1;
int from = 0;
int to;
long sizeDiff = 0;
byte[] updateEntry = null;
do {
final int entrySize;
final int updatedEntryPosition;
if (updateEntry == null) {
if (from == 0) {
entrySize = Math.min(getEntryContentLength(content.length), OClusterPage.MAX_RECORD_SIZE);
to = entrySize - (2 * OByteSerializer.BYTE_SIZE + OIntegerSerializer.INT_SIZE + OLongSerializer.LONG_SIZE);
} else {
entrySize = Math.min(content.length - from + OByteSerializer.BYTE_SIZE + OLongSerializer.LONG_SIZE, OClusterPage.MAX_RECORD_SIZE);
to = from + entrySize - (OByteSerializer.BYTE_SIZE + OLongSerializer.LONG_SIZE);
}
updateEntry = new byte[entrySize];
int entryPosition = 0;
if (from == 0) {
updateEntry[entryPosition] = recordType;
entryPosition++;
OIntegerSerializer.INSTANCE.serializeNative(content.length, updateEntry, entryPosition);
entryPosition += OIntegerSerializer.INT_SIZE;
}
System.arraycopy(content, from, updateEntry, entryPosition, to - from);
entryPosition += to - from;
if (nextPageIndex == positionEntry.getPageIndex())
updateEntry[entryPosition] = 1;
entryPosition++;
OLongSerializer.INSTANCE.serializeNative(-1, updateEntry, entryPosition);
if (to < content.length) {
assert entrySize == OClusterPage.MAX_RECORD_SIZE;
}
} else {
entrySize = updateEntry.length;
if (from == 0) {
to = entrySize - (2 * OByteSerializer.BYTE_SIZE + OIntegerSerializer.INT_SIZE + OLongSerializer.LONG_SIZE);
} else {
to = from + entrySize - (OByteSerializer.BYTE_SIZE + OLongSerializer.LONG_SIZE);
}
}
int freePageIndex = -1;
if (nextPageIndex < 0) {
FindFreePageResult findFreePageResult = findFreePage(fileId, pinnedStateEntryIndex, entrySize, atomicOperation);
nextPageIndex = findFreePageResult.pageIndex;
freePageIndex = findFreePageResult.freePageIndex;
}
boolean isNew = false;
OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, nextPageIndex, false);
if (cacheEntry == null) {
cacheEntry = addPage(atomicOperation, fileId);
isNew = true;
}
cacheEntry.acquireExclusiveLock();
try {
final OClusterPage localPage = new OClusterPage(cacheEntry, isNew, getChanges(atomicOperation, cacheEntry));
final int pageFreeSpace = localPage.getFreeSpace();
if (freePageIndex < 0)
freePageIndex = calculateFreePageIndex(localPage);
else
assert isNew || freePageIndex == calculateFreePageIndex(localPage);
if (nextRecordPosition >= 0) {
if (localPage.isDeleted(nextRecordPosition))
throw new OPaginatedClusterException("Record with rid " + new ORecordId(id, clusterPosition) + " was deleted", this);
int currentEntrySize = localPage.getRecordSize(nextRecordPosition);
nextEntryPointer = localPage.getRecordLongValue(nextRecordPosition, currentEntrySize - OLongSerializer.LONG_SIZE);
if (currentEntrySize == entrySize) {
localPage.replaceRecord(nextRecordPosition, updateEntry, recordVersion);
updatedEntryPosition = nextRecordPosition;
} else {
localPage.deleteRecord(nextRecordPosition);
if (localPage.getMaxRecordSize() >= entrySize) {
updatedEntryPosition = localPage.appendRecord(recordVersion, updateEntry);
if (updatedEntryPosition < 0) {
throw new IllegalStateException("Page " + cacheEntry.getPageIndex() + " does not have enough free space to add record content");
}
} else {
updatedEntryPosition = -1;
}
}
if (nextEntryPointer >= 0) {
nextRecordPosition = getRecordPosition(nextEntryPointer);
nextPageIndex = getPageIndex(nextEntryPointer);
} else {
nextPageIndex = -1;
nextRecordPosition = -1;
}
} else {
assert localPage.getFreeSpace() >= entrySize;
updatedEntryPosition = localPage.appendRecord(recordVersion, updateEntry);
if (updatedEntryPosition < 0) {
throw new IllegalStateException("Page " + cacheEntry.getPageIndex() + " does not have enough free space to add record content");
}
nextPageIndex = -1;
nextRecordPosition = -1;
}
sizeDiff += pageFreeSpace - localPage.getFreeSpace();
} finally {
cacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, cacheEntry);
}
updateFreePagesIndex(fileId, pinnedStateEntryIndex, freePageIndex, cacheEntry.getPageIndex(), atomicOperation);
if (updatedEntryPosition >= 0) {
if (from == 0) {
newPageIndex = cacheEntry.getPageIndex();
newRecordPosition = updatedEntryPosition;
}
from = to;
if (prevPageIndex >= 0) {
OCacheEntry prevCacheEntry = loadPage(atomicOperation, fileId, prevPageIndex, false);
prevCacheEntry.acquireExclusiveLock();
try {
OClusterPage prevPage = new OClusterPage(prevCacheEntry, false, getChanges(atomicOperation, prevCacheEntry));
prevPage.setRecordLongValue(prevRecordPosition, -OLongSerializer.LONG_SIZE, createPagePointer(cacheEntry.getPageIndex(), updatedEntryPosition));
} finally {
prevCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, prevCacheEntry);
}
}
prevPageIndex = cacheEntry.getPageIndex();
prevRecordPosition = updatedEntryPosition;
updateEntry = null;
}
} while (to < content.length || updateEntry != null);
// clear unneeded pages
while (nextEntryPointer >= 0) {
nextPageIndex = getPageIndex(nextEntryPointer);
nextRecordPosition = getRecordPosition(nextEntryPointer);
final int freePagesIndex;
final int freeSpace;
OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, nextPageIndex, false);
cacheEntry.acquireExclusiveLock();
try {
final OClusterPage localPage = new OClusterPage(cacheEntry, false, getChanges(atomicOperation, cacheEntry));
freeSpace = localPage.getFreeSpace();
freePagesIndex = calculateFreePageIndex(localPage);
nextEntryPointer = localPage.getRecordLongValue(nextRecordPosition, -OLongSerializer.LONG_SIZE);
localPage.deleteRecord(nextRecordPosition);
sizeDiff += freeSpace - localPage.getFreeSpace();
} finally {
cacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, cacheEntry);
}
updateFreePagesIndex(fileId, pinnedStateEntryIndex, freePagesIndex, nextPageIndex, atomicOperation);
}
assert newPageIndex >= 0;
assert newRecordPosition >= 0;
if (newPageIndex != positionEntry.getPageIndex() || newRecordPosition != positionEntry.getRecordPosition()) {
clusterPositionMap.update(clusterPosition, new OClusterPositionMapBucket.PositionEntry(newPageIndex, newRecordPosition));
}
updateClusterState(fileId, pinnedStateEntryIndex, 0, sizeDiff, atomicOperation);
addAtomicOperationMetadata(new ORecordId(id, clusterPosition), atomicOperation);
endAtomicOperation(false, null);
} catch (RuntimeException e) {
endAtomicOperation(true, e);
throw OException.wrapException(new OPaginatedClusterException("Error during record update", this), e);
} finally {
releaseExclusiveLock();
}
} finally {
if (statistic != null)
statistic.stopRecordUpdateTimer();
completeOperation();
}
}
use of com.orientechnologies.orient.core.id.ORecordId in project orientdb by orientechnologies.
the class OCommandExecutorSQLSetAware method extractClassFromTarget.
protected OClass extractClassFromTarget(String iTarget) {
// CLASS
if (!iTarget.toUpperCase().startsWith(OCommandExecutorSQLAbstract.CLUSTER_PREFIX) && !iTarget.startsWith(OCommandExecutorSQLAbstract.INDEX_PREFIX)) {
if (iTarget.toUpperCase().startsWith(OCommandExecutorSQLAbstract.CLASS_PREFIX))
// REMOVE CLASS PREFIX
iTarget = iTarget.substring(OCommandExecutorSQLAbstract.CLASS_PREFIX.length());
if (iTarget.charAt(0) == ORID.PREFIX)
return getDatabase().getMetadata().getSchema().getClassByClusterId(new ORecordId(iTarget).getClusterId());
return getDatabase().getMetadata().getSchema().getClass(iTarget);
}
//CLUSTER
if (iTarget.toUpperCase().startsWith(OCommandExecutorSQLAbstract.CLUSTER_PREFIX)) {
String clusterName = iTarget.substring(OCommandExecutorSQLAbstract.CLUSTER_PREFIX.length()).trim();
ODatabaseDocumentInternal db = getDatabase();
if (clusterName.startsWith("[") && clusterName.endsWith("]")) {
String[] clusterNames = clusterName.substring(1, clusterName.length() - 1).split(",");
OClass candidateClass = null;
for (String cName : clusterNames) {
OCluster aCluster = db.getStorage().getClusterByName(cName.trim());
if (aCluster == null) {
return null;
}
OClass aClass = db.getMetadata().getSchema().getClassByClusterId(aCluster.getId());
if (aClass == null) {
return null;
}
if (candidateClass == null || candidateClass.equals(aClass) || candidateClass.isSubClassOf(aClass)) {
candidateClass = aClass;
} else if (!candidateClass.isSuperClassOf(aClass)) {
return null;
}
}
return candidateClass;
} else {
OCluster cluster = db.getStorage().getClusterByName(clusterName);
if (cluster != null) {
return db.getMetadata().getSchema().getClassByClusterId(cluster.getId());
}
}
}
return null;
}
use of com.orientechnologies.orient.core.id.ORecordId in project orientdb by orientechnologies.
the class OPaginatedCluster method createRecord.
public OPhysicalPosition createRecord(byte[] content, final int recordVersion, final byte recordType, OPhysicalPosition allocatedPosition) throws IOException {
startOperation();
OSessionStoragePerformanceStatistic statistic = performanceStatisticManager.getSessionPerformanceStatistic();
if (statistic != null)
statistic.startRecordCreationTimer();
try {
content = compression.compress(content);
content = encryption.encrypt(content);
OAtomicOperation atomicOperation = startAtomicOperation(true);
acquireExclusiveLock();
try {
final RecordCreationResult recordCreationResult = createDataRecord(fileId, pinnedStateEntryIndex, content, recordVersion, recordType, atomicOperation);
final long clusterPosition;
if (allocatedPosition != null) {
clusterPositionMap.update(allocatedPosition.clusterPosition, new OClusterPositionMapBucket.PositionEntry(recordCreationResult.pageIndex, recordCreationResult.recordPosition));
clusterPosition = allocatedPosition.clusterPosition;
} else
clusterPosition = clusterPositionMap.add(recordCreationResult.pageIndex, recordCreationResult.recordPosition);
addAtomicOperationMetadata(new ORecordId(id, clusterPosition), atomicOperation);
endAtomicOperation(false, null);
return createPhysicalPosition(recordType, clusterPosition, recordCreationResult.recordVersion);
} finally {
releaseExclusiveLock();
}
} finally {
if (statistic != null)
statistic.stopRecordCreationTimer();
completeOperation();
}
}
use of com.orientechnologies.orient.core.id.ORecordId in project orientdb by orientechnologies.
the class OPaginatedCluster method readDebug.
public OPaginatedClusterDebug readDebug(long clusterPosition) throws IOException {
startOperation();
try {
OPaginatedClusterDebug debug = new OPaginatedClusterDebug();
debug.clusterPosition = clusterPosition;
debug.fileId = fileId;
OAtomicOperation atomicOperation = storageLocal.getAtomicOperationsManager().getCurrentOperation();
OClusterPositionMapBucket.PositionEntry positionEntry = clusterPositionMap.get(clusterPosition, 1);
if (positionEntry == null) {
debug.empty = true;
return debug;
}
long pageIndex = positionEntry.getPageIndex();
int recordPosition = positionEntry.getRecordPosition();
if (getFilledUpTo(atomicOperation, fileId) <= pageIndex) {
debug.empty = true;
return debug;
}
debug.pages = new ArrayList<OClusterPageDebug>();
int contentSize = 0;
long nextPagePointer;
boolean firstEntry = true;
do {
OClusterPageDebug debugPage = new OClusterPageDebug();
debugPage.pageIndex = pageIndex;
OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, pageIndex, false);
cacheEntry.acquireSharedLock();
try {
final OClusterPage localPage = new OClusterPage(cacheEntry, false, getChanges(atomicOperation, cacheEntry));
if (localPage.isDeleted(recordPosition)) {
if (debug.pages.isEmpty()) {
debug.empty = true;
return debug;
} else
throw new OPaginatedClusterException("Content of record " + new ORecordId(id, clusterPosition) + " was broken", this);
}
debugPage.inPagePosition = recordPosition;
debugPage.inPageSize = localPage.getRecordSize(recordPosition);
byte[] content = localPage.getRecordBinaryValue(recordPosition, 0, debugPage.inPageSize);
debugPage.content = content;
if (firstEntry && content[content.length - OLongSerializer.LONG_SIZE - OByteSerializer.BYTE_SIZE] == 0) {
debug.empty = true;
return debug;
}
debug.pages.add(debugPage);
nextPagePointer = OLongSerializer.INSTANCE.deserializeNative(content, content.length - OLongSerializer.LONG_SIZE);
contentSize += content.length - OLongSerializer.LONG_SIZE - OByteSerializer.BYTE_SIZE;
firstEntry = false;
} finally {
cacheEntry.releaseSharedLock();
releasePage(atomicOperation, cacheEntry);
}
pageIndex = getPageIndex(nextPagePointer);
recordPosition = getRecordPosition(nextPagePointer);
} while (nextPagePointer >= 0);
debug.contentSize = contentSize;
return debug;
} finally {
completeOperation();
}
}
Aggregations