use of org.apache.ignite.internal.processors.cache.database.tree.io.DataPageIO in project ignite by apache.
the class FreeListImpl method insertDataRow.
/** {@inheritDoc} */
@Override
public void insertDataRow(CacheDataRow row) throws IgniteCheckedException {
int rowSize = getRowSize(row);
int written = 0;
do {
if (written != 0)
memMetrics.incrementLargeEntriesPages();
int freeSpace = Math.min(MIN_SIZE_FOR_DATA_PAGE, rowSize - written);
long pageId = 0L;
if (freeSpace == MIN_SIZE_FOR_DATA_PAGE)
pageId = takeEmptyPage(emptyDataPagesBucket, DataPageIO.VERSIONS);
boolean reuseBucket = false;
// TODO: properly handle reuse bucket.
if (pageId == 0L) {
for (int b = bucket(freeSpace, false) + 1; b < BUCKETS - 1; b++) {
pageId = takeEmptyPage(b, DataPageIO.VERSIONS);
if (pageId != 0L) {
reuseBucket = isReuseBucket(b);
break;
}
}
}
boolean allocated = pageId == 0L;
if (allocated)
pageId = allocateDataPage(row.partition());
DataPageIO init = reuseBucket || allocated ? DataPageIO.VERSIONS.latest() : null;
written = write(pageId, writeRow, init, row, written, FAIL_I);
// We can't fail here.
assert written != FAIL_I;
} while (written != COMPLETE);
}
use of org.apache.ignite.internal.processors.cache.database.tree.io.DataPageIO in project ignite by apache.
the class PagesList method handlePageFull.
/**
* @param pageId Page ID.
* @param page Page pointer.
* @param pageAddr Page address.
* @param io IO.
* @param dataId Data page ID.
* @param data Data page pointer.
* @param dataAddr Data page address.
* @param bucket Bucket index.
* @throws IgniteCheckedException If failed.
* */
private void handlePageFull(final long pageId, final long page, final long pageAddr, PagesListNodeIO io, final long dataId, final long data, final long dataAddr, int bucket) throws IgniteCheckedException {
DataPageIO dataIO = DataPageIO.VERSIONS.forPage(dataAddr);
// Attempt to add page failed: the node page is full.
if (isReuseBucket(bucket)) {
// We can put only empty data pages to reuse bucket.
assert dataIO.isEmpty(dataAddr);
// Change page type to index and add it as next node page to this list.
long newDataId = PageIdUtils.changeType(dataId, FLAG_IDX);
setupNextPage(io, pageId, pageAddr, newDataId, dataAddr);
if (needWalDeltaRecord(pageId, page, null))
wal.log(new PagesListSetNextRecord(cacheId, pageId, newDataId));
if (needWalDeltaRecord(dataId, data, null))
wal.log(new PagesListInitNewPageRecord(cacheId, dataId, io.getType(), io.getVersion(), newDataId, pageId, 0L));
// In reuse bucket the page itself can be used as a free page.
bucketsSize[bucket].incrementAndGet();
updateTail(bucket, pageId, newDataId);
} else {
// Just allocate a new node page and add our data page there.
final long nextId = allocatePage(null);
final long nextPage = acquirePage(nextId);
try {
// Newly allocated page.
long nextPageAddr = writeLock(nextId, nextPage);
assert nextPageAddr != 0L;
// Here we should never write full page, because it is known to be new.
Boolean nextWalPlc = FALSE;
try {
setupNextPage(io, pageId, pageAddr, nextId, nextPageAddr);
if (needWalDeltaRecord(pageId, page, null))
wal.log(new PagesListSetNextRecord(cacheId, pageId, nextId));
int idx = io.addPage(nextPageAddr, dataId, pageSize());
if (needWalDeltaRecord(nextId, nextPage, nextWalPlc))
wal.log(new PagesListInitNewPageRecord(cacheId, nextId, io.getType(), io.getVersion(), nextId, pageId, dataId));
assert idx != -1;
dataIO.setFreeListPageId(dataAddr, nextId);
if (needWalDeltaRecord(dataId, data, null))
wal.log(new DataPageSetFreeListPageRecord(cacheId, dataId, nextId));
bucketsSize[bucket].incrementAndGet();
updateTail(bucket, pageId, nextId);
} finally {
writeUnlock(nextId, nextPage, nextPageAddr, nextWalPlc, true);
}
} finally {
releasePage(nextId, nextPage);
}
}
}
use of org.apache.ignite.internal.processors.cache.database.tree.io.DataPageIO in project ignite by apache.
the class PagesList method putDataPage.
/**
* @param pageId Page ID.
* @param page Page pointer.
* @param pageAddr Page address.
* @param io IO.
* @param dataId Data page ID.
* @param dataPage Data page pointer.
* @param dataAddr Data page address.
* @param bucket Bucket.
* @return {@code true} If succeeded.
* @throws IgniteCheckedException If failed.
*/
private boolean putDataPage(final long pageId, final long page, final long pageAddr, PagesListNodeIO io, final long dataId, final long dataPage, final long dataAddr, int bucket) throws IgniteCheckedException {
if (io.getNextId(pageAddr) != 0L)
// Splitted.
return false;
int idx = io.addPage(pageAddr, dataId, pageSize());
if (idx == -1)
handlePageFull(pageId, page, pageAddr, io, dataId, dataPage, dataAddr, bucket);
else {
bucketsSize[bucket].incrementAndGet();
if (needWalDeltaRecord(pageId, page, null))
wal.log(new PagesListAddPageRecord(cacheId, pageId, dataId));
DataPageIO dataIO = DataPageIO.VERSIONS.forPage(dataAddr);
dataIO.setFreeListPageId(dataAddr, pageId);
if (needWalDeltaRecord(dataId, dataPage, null))
wal.log(new DataPageSetFreeListPageRecord(cacheId, dataId, pageId));
}
return true;
}
use of org.apache.ignite.internal.processors.cache.database.tree.io.DataPageIO in project ignite by apache.
the class CacheDataRowAdapter method initFromLink.
/**
* Read row from data pages.
* Can be called with cctx == null, if cache instance is unknown, but its ID is stored in the data row.
*
* @param cctx Cctx.
* @param sharedCtx Shared context.
* @param pageMem Page memory.
* @param rowData Row data.
*/
public final void initFromLink(@Nullable GridCacheContext<?, ?> cctx, GridCacheSharedContext<?, ?> sharedCtx, PageMemory pageMem, RowData rowData) throws IgniteCheckedException {
assert link != 0 : "link";
assert key == null : "key";
CacheObjectContext coctx = null;
if (cctx != null) {
cacheId = cctx.memoryPolicy().config().getPageEvictionMode() == DataPageEvictionMode.DISABLED ? cctx.cacheId() : // Force cacheId reading for evictable memory policies.
0;
coctx = cctx.cacheObjectContext();
}
long nextLink = link;
IncompleteObject<?> incomplete = null;
boolean first = true;
do {
final long pageId = pageId(nextLink);
final long page = pageMem.acquirePage(cacheId, pageId);
try {
// Non-empty data page must not be recycled.
long pageAddr = pageMem.readLock(cacheId, pageId, page);
assert pageAddr != 0L : nextLink;
try {
DataPageIO io = DataPageIO.VERSIONS.forPage(pageAddr);
DataPagePayload data = io.readPayload(pageAddr, itemId(nextLink), pageMem.pageSize());
nextLink = data.nextLink();
if (first) {
if (nextLink == 0) {
// Fast path for a single page row.
readFullRow(sharedCtx, coctx, pageAddr + data.offset(), rowData);
return;
}
first = false;
}
ByteBuffer buf = pageMem.pageBuffer(pageAddr);
buf.position(data.offset());
buf.limit(data.offset() + data.payloadSize());
boolean keyOnly = rowData == RowData.KEY_ONLY;
incomplete = readFragment(sharedCtx, coctx, buf, keyOnly, incomplete);
if (keyOnly && key != null)
return;
} finally {
pageMem.readUnlock(cacheId, pageId, page);
}
} finally {
pageMem.releasePage(cacheId, pageId, page);
}
} while (nextLink != 0);
assert isReady() : "ready";
}
use of org.apache.ignite.internal.processors.cache.database.tree.io.DataPageIO in project ignite by apache.
the class PageAbstractEvictionTracker method evictDataPage.
/**
* @param pageIdx Page index.
* @return true if at least one data row has been evicted
* @throws IgniteCheckedException If failed.
*/
final boolean evictDataPage(int pageIdx) throws IgniteCheckedException {
long fakePageId = PageIdUtils.pageId(0, (byte) 0, pageIdx);
long page = pageMem.acquirePage(0, fakePageId);
List<CacheDataRowAdapter> rowsToEvict;
try {
long pageAddr = pageMem.readLockForce(0, fakePageId, page);
try {
if (PageIO.getType(pageAddr) != PageIO.T_DATA)
// Can't evict: page has been recycled into non-data page.
return false;
DataPageIO io = DataPageIO.VERSIONS.forPage(pageAddr);
long realPageId = PageIO.getPageId(pageAddr);
if (!checkTouch(realPageId))
// Can't evict: another thread concurrently invoked forgetPage()
return false;
rowsToEvict = io.forAllItems(pageAddr, new DataPageIO.CC<CacheDataRowAdapter>() {
@Override
public CacheDataRowAdapter apply(long link) throws IgniteCheckedException {
CacheDataRowAdapter row = new CacheDataRowAdapter(link);
row.initFromLink(null, sharedCtx, pageMem, CacheDataRowAdapter.RowData.KEY_ONLY);
assert row.cacheId() != 0 : "Cache ID should be stored in rows of evictable cache";
return row;
}
});
} finally {
pageMem.readUnlock(0, fakePageId, page);
}
} finally {
pageMem.releasePage(0, fakePageId, page);
}
boolean evictionDone = false;
for (CacheDataRowAdapter dataRow : rowsToEvict) {
GridCacheContext<?, ?> cacheCtx = sharedCtx.cacheContext(dataRow.cacheId());
if (!cacheCtx.userCache())
continue;
GridCacheEntryEx entryEx = cacheCtx.isNear() ? cacheCtx.near().dht().entryEx(dataRow.key()) : cacheCtx.cache().entryEx(dataRow.key());
evictionDone |= entryEx.evictInternal(GridCacheVersionManager.EVICT_VER, null, true);
}
return evictionDone;
}
Aggregations