diskCache.release(pinnedStateEntry);
}
}
private void updateFreePagesIndex(int prevFreePageIndex, long pageIndex, OClusterPage.TrackMode trackMode) throws IOException {
final OCacheEntry cacheEntry = diskCache.load(fileId, pageIndex, false);
cacheEntry.acquireExclusiveLock();
try {
final OClusterPage localPage = new OClusterPage(cacheEntry, false, trackMode);
int newFreePageIndex = calculateFreePageIndex(localPage);
if (prevFreePageIndex == newFreePageIndex)
return;
long nextPageIndex = localPage.getNextPage();
long prevPageIndex = localPage.getPrevPage();
if (prevPageIndex >= 0) {
final OCacheEntry prevPageCacheEntry = diskCache.load(fileId, prevPageIndex, false);
prevPageCacheEntry.acquireExclusiveLock();
try {
final OClusterPage prevPage = new OClusterPage(prevPageCacheEntry, false, trackMode);
assert calculateFreePageIndex(prevPage) == prevFreePageIndex;
prevPage.setNextPage(nextPageIndex);
logPageChanges(prevPage, fileId, prevPageIndex, false);
prevPageCacheEntry.markDirty();
} finally {
prevPageCacheEntry.releaseExclusiveLock();
diskCache.release(prevPageCacheEntry);
}
}
if (nextPageIndex >= 0) {
final OCacheEntry nextPageCacheEntry = diskCache.load(fileId, nextPageIndex, false);
nextPageCacheEntry.acquireExclusiveLock();
try {
final OClusterPage nextPage = new OClusterPage(nextPageCacheEntry, false, trackMode);
if (calculateFreePageIndex(nextPage) != prevFreePageIndex)
calculateFreePageIndex(nextPage);
assert calculateFreePageIndex(nextPage) == prevFreePageIndex;
nextPage.setPrevPage(prevPageIndex);
logPageChanges(nextPage, fileId, nextPageIndex, false);
} finally {
nextPageCacheEntry.releaseExclusiveLock();
diskCache.release(nextPageCacheEntry);
}
}
localPage.setNextPage(-1);
localPage.setPrevPage(-1);
if (prevFreePageIndex < 0 && newFreePageIndex < 0)
return;
if (prevFreePageIndex >= 0 && prevFreePageIndex < FREE_LIST_SIZE) {
if (prevPageIndex < 0)
updateFreePagesList(prevFreePageIndex, nextPageIndex);
}
if (newFreePageIndex >= 0) {
long oldFreePage;
diskCache.loadPinnedPage(pinnedStateEntry);
try {
OPaginatedClusterState clusterFreeList = new OPaginatedClusterState(pinnedStateEntry, ODurablePage.TrackMode.NONE);
oldFreePage = clusterFreeList.getFreeListPage(newFreePageIndex);
} finally {
diskCache.release(pinnedStateEntry);
}
if (oldFreePage >= 0) {
final OCacheEntry oldFreePageCacheEntry = diskCache.load(fileId, oldFreePage, false);
oldFreePageCacheEntry.acquireExclusiveLock();
try {
final OClusterPage oldFreeLocalPage = new OClusterPage(oldFreePageCacheEntry, false, trackMode);
assert calculateFreePageIndex(oldFreeLocalPage) == newFreePageIndex;
oldFreeLocalPage.setPrevPage(pageIndex);
logPageChanges(oldFreeLocalPage, fileId, oldFreePage, false);
oldFreePageCacheEntry.markDirty();
} finally {
oldFreePageCacheEntry.releaseExclusiveLock();
diskCache.release(oldFreePageCacheEntry);
}
localPage.setNextPage(oldFreePage);
localPage.setPrevPage(-1);