use of com.orientechnologies.orient.core.exception.OPaginatedClusterException in project orientdb by orientechnologies.
the class OPaginatedCluster method getEntries.
@Override
public long getEntries() {
startOperation();
try {
atomicOperationsManager.acquireReadLock(this);
try {
acquireSharedLock();
try {
final OAtomicOperation atomicOperation = atomicOperationsManager.getCurrentOperation();
final OCacheEntry pinnedStateEntry = loadPage(atomicOperation, fileId, pinnedStateEntryIndex, true);
pinnedStateEntry.acquireSharedLock();
try {
return new OPaginatedClusterState(pinnedStateEntry, getChanges(atomicOperation, pinnedStateEntry)).getSize();
} finally {
pinnedStateEntry.releaseSharedLock();
releasePage(atomicOperation, pinnedStateEntry);
}
} finally {
releaseSharedLock();
}
} catch (IOException ioe) {
throw OException.wrapException(new OPaginatedClusterException("Error during retrieval of size of '" + getName() + "' cluster", this), ioe);
} finally {
atomicOperationsManager.releaseReadLock(this);
}
} finally {
completeOperation();
}
}
use of com.orientechnologies.orient.core.exception.OPaginatedClusterException in project orientdb by orientechnologies.
the class OPaginatedCluster method createMultiPageRecord.
private RecordCreationResult createMultiPageRecord(long fileId, long pinnedStateEntryIndex, byte[] content, int recordVersion, byte recordType, OAtomicOperation atomicOperation) throws IOException {
RecordCreationResult recordCreationResult;
try {
int entrySize = content.length + OIntegerSerializer.INT_SIZE + OByteSerializer.BYTE_SIZE;
int fullEntryPosition = 0;
byte[] fullEntry = new byte[entrySize];
fullEntry[fullEntryPosition] = recordType;
fullEntryPosition++;
OIntegerSerializer.INSTANCE.serializeNative(content.length, fullEntry, fullEntryPosition);
fullEntryPosition += OIntegerSerializer.INT_SIZE;
System.arraycopy(content, 0, fullEntry, fullEntryPosition, content.length);
long prevPageRecordPointer = -1;
long firstPageIndex = -1;
int firstPagePosition = -1;
int version = 0;
int from = 0;
int to = from + (OClusterPage.MAX_RECORD_SIZE - OByteSerializer.BYTE_SIZE - OLongSerializer.LONG_SIZE);
int recordsSizeDiff = 0;
do {
byte[] entryContent = new byte[to - from + OByteSerializer.BYTE_SIZE + OLongSerializer.LONG_SIZE];
System.arraycopy(fullEntry, from, entryContent, 0, to - from);
if (from > 0)
entryContent[entryContent.length - OLongSerializer.LONG_SIZE - OByteSerializer.BYTE_SIZE] = 0;
else
entryContent[entryContent.length - OLongSerializer.LONG_SIZE - OByteSerializer.BYTE_SIZE] = 1;
OLongSerializer.INSTANCE.serializeNative(-1L, entryContent, entryContent.length - OLongSerializer.LONG_SIZE);
final AddEntryResult addEntryResult = addEntry(fileId, pinnedStateEntryIndex, recordVersion, entryContent, atomicOperation);
recordsSizeDiff += addEntryResult.recordsSizeDiff;
if (firstPageIndex == -1) {
firstPageIndex = addEntryResult.pageIndex;
firstPagePosition = addEntryResult.pagePosition;
version = addEntryResult.recordVersion;
}
long addedPagePointer = createPagePointer(addEntryResult.pageIndex, addEntryResult.pagePosition);
if (prevPageRecordPointer >= 0) {
long prevPageIndex = getPageIndex(prevPageRecordPointer);
int prevPageRecordPosition = getRecordPosition(prevPageRecordPointer);
final OCacheEntry prevPageCacheEntry = loadPage(atomicOperation, fileId, prevPageIndex, false);
prevPageCacheEntry.acquireExclusiveLock();
try {
final OClusterPage prevPage = new OClusterPage(prevPageCacheEntry, false, getChanges(atomicOperation, prevPageCacheEntry));
prevPage.setRecordLongValue(prevPageRecordPosition, -OLongSerializer.LONG_SIZE, addedPagePointer);
} finally {
prevPageCacheEntry.releaseExclusiveLock();
releasePage(atomicOperation, prevPageCacheEntry);
}
}
prevPageRecordPointer = addedPagePointer;
from = to;
to = to + (OClusterPage.MAX_RECORD_SIZE - OLongSerializer.LONG_SIZE - OByteSerializer.BYTE_SIZE);
if (to > fullEntry.length)
to = fullEntry.length;
} while (from < to);
updateClusterState(fileId, pinnedStateEntryIndex, 1, recordsSizeDiff, atomicOperation);
recordCreationResult = new RecordCreationResult(firstPageIndex, firstPagePosition, version);
} catch (RuntimeException e) {
endAtomicOperation(true, e);
throw OException.wrapException(new OPaginatedClusterException("Error during record creation", this), e);
}
return recordCreationResult;
}
use of com.orientechnologies.orient.core.exception.OPaginatedClusterException in project orientdb by orientechnologies.
the class OPaginatedCluster method hideRecord.
@Override
public boolean hideRecord(long position) throws IOException {
startOperation();
try {
OAtomicOperation atomicOperation = startAtomicOperation(true);
acquireExclusiveLock();
try {
OClusterPositionMapBucket.PositionEntry positionEntry = clusterPositionMap.get(position, 1);
if (positionEntry == null) {
endAtomicOperation(false, null);
return false;
}
long pageIndex = positionEntry.getPageIndex();
if (getFilledUpTo(atomicOperation, fileId) <= pageIndex) {
endAtomicOperation(false, null);
return false;
}
try {
updateClusterState(fileId, pinnedStateEntryIndex, -1, 0, atomicOperation);
clusterPositionMap.remove(position);
addAtomicOperationMetadata(new ORecordId(id, position), atomicOperation);
endAtomicOperation(false, null);
return true;
} catch (Exception e) {
endAtomicOperation(true, e);
throw OException.wrapException(new OPaginatedClusterException("Error during record hide", this), e);
}
} finally {
releaseExclusiveLock();
}
} finally {
completeOperation();
}
}
use of com.orientechnologies.orient.core.exception.OPaginatedClusterException in project orientdb by orientechnologies.
the class OPaginatedCluster method readFullEntry.
@SuppressFBWarnings(value = "PZLA_PREFER_ZERO_LENGTH_ARRAYS")
private byte[] readFullEntry(final long clusterPosition, long pageIndex, int recordPosition, final OAtomicOperation atomicOperation, final int pageCount) throws IOException {
if (getFilledUpTo(atomicOperation, fileId) <= pageIndex)
return null;
final List<byte[]> recordChunks = new ArrayList<byte[]>();
int contentSize = 0;
long nextPagePointer;
boolean firstEntry = true;
do {
OCacheEntry cacheEntry = loadPage(atomicOperation, fileId, pageIndex, false, pageCount);
cacheEntry.acquireSharedLock();
try {
final OClusterPage localPage = new OClusterPage(cacheEntry, false, getChanges(atomicOperation, cacheEntry));
if (localPage.isDeleted(recordPosition)) {
if (recordChunks.isEmpty())
return null;
else
throw new OPaginatedClusterException("Content of record " + new ORecordId(id, clusterPosition) + " was broken", this);
}
byte[] content = localPage.getRecordBinaryValue(recordPosition, 0, localPage.getRecordSize(recordPosition));
if (firstEntry && content[content.length - OLongSerializer.LONG_SIZE - OByteSerializer.BYTE_SIZE] == 0)
return null;
recordChunks.add(content);
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);
byte[] fullContent;
if (recordChunks.size() == 1)
fullContent = recordChunks.get(0);
else {
fullContent = new byte[contentSize + OLongSerializer.LONG_SIZE + OByteSerializer.BYTE_SIZE];
int fullContentPosition = 0;
for (byte[] recordChuck : recordChunks) {
System.arraycopy(recordChuck, 0, fullContent, fullContentPosition, recordChuck.length - OLongSerializer.LONG_SIZE - OByteSerializer.BYTE_SIZE);
fullContentPosition += recordChuck.length - OLongSerializer.LONG_SIZE - OByteSerializer.BYTE_SIZE;
}
}
return fullContent;
}
use of com.orientechnologies.orient.core.exception.OPaginatedClusterException in project orientdb by orientechnologies.
the class LocalPaginatedClusterTest method testResurrectRecord.
public void testResurrectRecord() throws IOException {
byte[] smallRecord = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int recordVersion = 0;
recordVersion++;
recordVersion++;
OPhysicalPosition physicalPosition = paginatedCluster.createRecord(smallRecord, recordVersion, (byte) 1, null);
Assert.assertEquals(physicalPosition.clusterPosition, 0);
Assert.assertEquals(paginatedCluster.getRecordStatus(physicalPosition.clusterPosition), OPaginatedCluster.RECORD_STATUS.PRESENT);
for (int i = 0; i < 1000; ++i) {
recordVersion++;
smallRecord = new byte[] { 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3 };
try {
paginatedCluster.recycleRecord(physicalPosition.clusterPosition, smallRecord, recordVersion, (byte) 2);
Assert.fail("it must be not possible to resurrect a non deleted record");
} catch (OPaginatedClusterException e) {
// OK
}
Assert.assertEquals(paginatedCluster.getRecordStatus(physicalPosition.clusterPosition), OPaginatedCluster.RECORD_STATUS.PRESENT);
paginatedCluster.deleteRecord(physicalPosition.clusterPosition);
Assert.assertEquals(paginatedCluster.getRecordStatus(physicalPosition.clusterPosition), OPaginatedCluster.RECORD_STATUS.REMOVED);
ORawBuffer rawBuffer = paginatedCluster.readRecord(physicalPosition.clusterPosition, false);
Assert.assertNull(rawBuffer);
paginatedCluster.recycleRecord(physicalPosition.clusterPosition, smallRecord, recordVersion, (byte) 2);
rawBuffer = paginatedCluster.readRecord(physicalPosition.clusterPosition, false);
Assert.assertNotNull(rawBuffer);
Assert.assertEquals(rawBuffer.version, recordVersion);
Assert.assertEquals(rawBuffer.buffer, smallRecord);
Assert.assertEquals(rawBuffer.recordType, 2);
// UPDATE 10 TIMES WITH A GROWING CONTENT TO STIMULATE DEFRAG AND CHANGE OF PAGES
for (int k = 0; k < 10; ++k) {
final byte[] updatedRecord = new byte[10 * k];
for (int j = 0; j < updatedRecord.length; ++j) {
updatedRecord[j] = (byte) j;
}
paginatedCluster.updateRecord(physicalPosition.clusterPosition, updatedRecord, recordVersion, (byte) 4);
}
}
}
Aggregations