final AddEntryResult addEntryResult = addEntry(recordVersion, entryContent, trackMode);
updateClusterState(trackMode, 1, addEntryResult.recordsSizeDiff);
final OClusterPosition clusterPosition = clusterPositionMap.add(addEntryResult.pageIndex, addEntryResult.pagePosition);
endAtomicOperation(false);
return createPhysicalPosition(recordType, clusterPosition, addEntryResult.recordVersion);
} catch (Throwable e) {
endAtomicOperation(true);
throw new OStorageException(null, e);
}
} else {
startAtomicOperation();
try {
lockTillAtomicOperationCompletes();
final OClusterPage.TrackMode trackMode = getTrackMode();
int entrySize = grownContentSize + OIntegerSerializer.INT_SIZE + OByteSerializer.BYTE_SIZE;
if (useCRC32)
entrySize += OIntegerSerializer.INT_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);
fullEntryPosition += grownContentSize;
if (useCRC32) {
CRC32 crc32 = new CRC32();
crc32.update(fullEntry, 0, fullEntryPosition);
OIntegerSerializer.INSTANCE.serializeNative((int) crc32.getValue(), fullEntry, fullEntryPosition);
}
long prevPageRecordPointer = -1;
long firstPageIndex = -1;
int firstPagePosition = -1;
ORecordVersion version = null;
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(recordVersion, entryContent, trackMode);
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 = prevPageRecordPointer >>> PAGE_INDEX_OFFSET;
int prevPageRecordPosition = (int) (prevPageRecordPointer & RECORD_POSITION_MASK);
final OCacheEntry prevPageCacheEntry = diskCache.load(fileId, prevPageIndex, false);
prevPageCacheEntry.acquireExclusiveLock();
try {
final OClusterPage prevPage = new OClusterPage(prevPageCacheEntry, false, ODurablePage.TrackMode.FULL);
prevPage.setRecordLongValue(prevPageRecordPosition, -OLongSerializer.LONG_SIZE, addedPagePointer);
logPageChanges(prevPage, fileId, prevPageIndex, false);
prevPageCacheEntry.markDirty();
} finally {
prevPageCacheEntry.releaseExclusiveLock();
diskCache.release(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(trackMode, 1, recordsSizeDiff);
OClusterPosition clusterPosition = clusterPositionMap.add(firstPageIndex, firstPagePosition);
endAtomicOperation(false);
return createPhysicalPosition(recordType, clusterPosition, version);
} catch (Throwable e) {