use of org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetNextRecord in project ignite by apache.
the class PagesList method fairMerge.
/**
* Link previous and next to each other.
* @param prevId Previous Previous page ID.
* @param pageId Page ID.
* @param nextId Next page ID.
* @param nextPage Next page absolute pointer.
* @param nextAddr Next page address.
* @param statHolder Statistics holder to track IO operations.
* @throws IgniteCheckedException If failed.
*/
private void fairMerge(final long prevId, long pageId, long nextId, long nextPage, long nextAddr, IoStatisticsHolder statHolder) throws IgniteCheckedException {
long prevPage = acquirePage(prevId, statHolder);
try {
// No check, we keep a reference.
final long prevAddr = writeLock(prevId, prevPage);
assert prevAddr != 0L;
try {
PagesListNodeIO prevIO = PagesListNodeIO.VERSIONS.forPage(prevAddr);
PagesListNodeIO nextIO = PagesListNodeIO.VERSIONS.forPage(nextAddr);
// These references must be updated at the same time in write locks.
assert prevIO.getNextId(prevAddr) == pageId;
assert nextIO.getPreviousId(nextAddr) == pageId;
prevIO.setNextId(prevAddr, nextId);
if (needWalDeltaRecord(prevId, prevPage, null))
wal.log(new PagesListSetNextRecord(grpId, prevId, nextId));
nextIO.setPreviousId(nextAddr, prevId);
if (needWalDeltaRecord(nextId, nextPage, null))
wal.log(new PagesListSetPreviousRecord(grpId, nextId, prevId));
} finally {
writeUnlock(prevId, prevPage, prevAddr, true);
}
} finally {
releasePage(prevId, prevPage);
}
}
use of org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetNextRecord 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.pagemem.wal.record.delta.PagesListSetNextRecord in project ignite by apache.
the class PagesList method fairMerge.
/**
* Link previous and next to each other.
* @param prevId Previous Previous page ID.
* @param pageId Page ID.
* @param nextId Next page ID.
* @param nextPage Next page absolute pointer.
* @param nextAddr Next page address.
* @throws IgniteCheckedException If failed.
*/
private void fairMerge(final long prevId, long pageId, long nextId, long nextPage, long nextAddr) throws IgniteCheckedException {
long prevPage = acquirePage(prevId);
try {
// No check, we keep a reference.
final long prevAddr = writeLock(prevId, prevPage);
assert prevAddr != 0L;
try {
PagesListNodeIO prevIO = PagesListNodeIO.VERSIONS.forPage(prevAddr);
PagesListNodeIO nextIO = PagesListNodeIO.VERSIONS.forPage(nextAddr);
// These references must be updated at the same time in write locks.
assert prevIO.getNextId(prevAddr) == pageId;
assert nextIO.getPreviousId(nextAddr) == pageId;
prevIO.setNextId(prevAddr, nextId);
if (needWalDeltaRecord(prevId, prevPage, null))
wal.log(new PagesListSetNextRecord(cacheId, prevId, nextId));
nextIO.setPreviousId(nextAddr, prevId);
if (needWalDeltaRecord(nextId, nextPage, null))
wal.log(new PagesListSetPreviousRecord(cacheId, nextId, prevId));
} finally {
writeUnlock(prevId, prevPage, prevAddr, true);
}
} finally {
releasePage(prevId, prevPage);
}
}
use of org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetNextRecord in project ignite by apache.
the class RecordDataV1Serializer method readRecord.
/**
* {@inheritDoc}
*/
@Override
public WALRecord readRecord(WALRecord.RecordType type, ByteBufferBackedDataInput in) throws IOException, IgniteCheckedException {
WALRecord res;
switch(type) {
case PAGE_RECORD:
byte[] arr = new byte[pageSize];
int cacheId = in.readInt();
long pageId = in.readLong();
in.readFully(arr);
res = new PageSnapshot(new FullPageId(pageId, cacheId), arr);
break;
case CHECKPOINT_RECORD:
long msb = in.readLong();
long lsb = in.readLong();
boolean hasPtr = in.readByte() != 0;
int idx = hasPtr ? in.readInt() : 0;
int off = hasPtr ? in.readInt() : 0;
int len = hasPtr ? in.readInt() : 0;
Map<Integer, CacheState> states = readPartitionStates(in);
boolean end = in.readByte() != 0;
FileWALPointer walPtr = hasPtr ? new FileWALPointer(idx, off, len) : null;
CheckpointRecord cpRec = new CheckpointRecord(new UUID(msb, lsb), walPtr, end);
cpRec.cacheGroupStates(states);
res = cpRec;
break;
case META_PAGE_INIT:
cacheId = in.readInt();
pageId = in.readLong();
int ioType = in.readUnsignedShort();
int ioVer = in.readUnsignedShort();
long treeRoot = in.readLong();
long reuseListRoot = in.readLong();
res = new MetaPageInitRecord(cacheId, pageId, ioType, ioVer, treeRoot, reuseListRoot);
break;
case PARTITION_META_PAGE_UPDATE_COUNTERS:
cacheId = in.readInt();
pageId = in.readLong();
long updCntr = in.readLong();
long rmvId = in.readLong();
int partSize = in.readInt();
long countersPageId = in.readLong();
byte state = in.readByte();
int allocatedIdxCandidate = in.readInt();
res = new MetaPageUpdatePartitionDataRecord(cacheId, pageId, updCntr, rmvId, partSize, countersPageId, state, allocatedIdxCandidate);
break;
case MEMORY_RECOVERY:
long ts = in.readLong();
res = new MemoryRecoveryRecord(ts);
break;
case PARTITION_DESTROY:
cacheId = in.readInt();
int partId = in.readInt();
res = new PartitionDestroyRecord(cacheId, partId);
break;
case DATA_RECORD:
int entryCnt = in.readInt();
List<DataEntry> entries = new ArrayList<>(entryCnt);
for (int i = 0; i < entryCnt; i++) entries.add(readDataEntry(in));
res = new DataRecord(entries, 0L);
break;
case METASTORE_DATA_RECORD:
int strLen = in.readInt();
byte[] strBytes = new byte[strLen];
in.readFully(strBytes);
String key = new String(strBytes);
int valLen = in.readInt();
assert valLen >= 0;
byte[] val;
if (valLen > 0) {
val = new byte[valLen];
in.readFully(val);
} else
val = null;
return new MetastoreDataRecord(key, val);
case HEADER_RECORD:
long magic = in.readLong();
if (magic != HeaderRecord.REGULAR_MAGIC && magic != HeaderRecord.COMPACTED_MAGIC)
throw new EOFException("Magic is corrupted [actual=" + U.hexLong(magic) + ']');
int ver = in.readInt();
res = new HeaderRecord(ver);
break;
case DATA_PAGE_INSERT_RECORD:
{
cacheId = in.readInt();
pageId = in.readLong();
int size = in.readUnsignedShort();
in.ensure(size);
byte[] payload = new byte[size];
in.readFully(payload);
res = new DataPageInsertRecord(cacheId, pageId, payload);
break;
}
case DATA_PAGE_UPDATE_RECORD:
{
cacheId = in.readInt();
pageId = in.readLong();
int itemId = in.readInt();
int size = in.readUnsignedShort();
in.ensure(size);
byte[] payload = new byte[size];
in.readFully(payload);
res = new DataPageUpdateRecord(cacheId, pageId, itemId, payload);
break;
}
case DATA_PAGE_INSERT_FRAGMENT_RECORD:
{
cacheId = in.readInt();
pageId = in.readLong();
final long lastLink = in.readLong();
final int payloadSize = in.readInt();
final byte[] payload = new byte[payloadSize];
in.readFully(payload);
res = new DataPageInsertFragmentRecord(cacheId, pageId, payload, lastLink);
break;
}
case DATA_PAGE_REMOVE_RECORD:
cacheId = in.readInt();
pageId = in.readLong();
int itemId = in.readUnsignedByte();
res = new DataPageRemoveRecord(cacheId, pageId, itemId);
break;
case DATA_PAGE_SET_FREE_LIST_PAGE:
cacheId = in.readInt();
pageId = in.readLong();
long freeListPage = in.readLong();
res = new DataPageSetFreeListPageRecord(cacheId, pageId, freeListPage);
break;
case INIT_NEW_PAGE_RECORD:
cacheId = in.readInt();
pageId = in.readLong();
ioType = in.readUnsignedShort();
ioVer = in.readUnsignedShort();
long virtualPageId = in.readLong();
res = new InitNewPageRecord(cacheId, pageId, ioType, ioVer, virtualPageId);
break;
case BTREE_META_PAGE_INIT_ROOT:
cacheId = in.readInt();
pageId = in.readLong();
long rootId = in.readLong();
res = new MetaPageInitRootRecord(cacheId, pageId, rootId);
break;
case BTREE_META_PAGE_INIT_ROOT2:
cacheId = in.readInt();
pageId = in.readLong();
long rootId2 = in.readLong();
int inlineSize = in.readShort();
res = new MetaPageInitRootInlineRecord(cacheId, pageId, rootId2, inlineSize);
break;
case BTREE_META_PAGE_ADD_ROOT:
cacheId = in.readInt();
pageId = in.readLong();
rootId = in.readLong();
res = new MetaPageAddRootRecord(cacheId, pageId, rootId);
break;
case BTREE_META_PAGE_CUT_ROOT:
cacheId = in.readInt();
pageId = in.readLong();
res = new MetaPageCutRootRecord(cacheId, pageId);
break;
case BTREE_INIT_NEW_ROOT:
cacheId = in.readInt();
pageId = in.readLong();
rootId = in.readLong();
ioType = in.readUnsignedShort();
ioVer = in.readUnsignedShort();
long leftId = in.readLong();
long rightId = in.readLong();
BPlusIO<?> io = BPlusIO.getBPlusIO(ioType, ioVer);
byte[] rowBytes = new byte[io.getItemSize()];
in.readFully(rowBytes);
res = new NewRootInitRecord<>(cacheId, pageId, rootId, (BPlusInnerIO<?>) io, leftId, rowBytes, rightId);
break;
case BTREE_PAGE_RECYCLE:
cacheId = in.readInt();
pageId = in.readLong();
long newPageId = in.readLong();
res = new RecycleRecord(cacheId, pageId, newPageId);
break;
case BTREE_PAGE_INSERT:
cacheId = in.readInt();
pageId = in.readLong();
ioType = in.readUnsignedShort();
ioVer = in.readUnsignedShort();
int itemIdx = in.readUnsignedShort();
rightId = in.readLong();
io = BPlusIO.getBPlusIO(ioType, ioVer);
rowBytes = new byte[io.getItemSize()];
in.readFully(rowBytes);
res = new InsertRecord<>(cacheId, pageId, io, itemIdx, rowBytes, rightId);
break;
case BTREE_FIX_LEFTMOST_CHILD:
cacheId = in.readInt();
pageId = in.readLong();
rightId = in.readLong();
res = new FixLeftmostChildRecord(cacheId, pageId, rightId);
break;
case BTREE_FIX_COUNT:
cacheId = in.readInt();
pageId = in.readLong();
int cnt = in.readUnsignedShort();
res = new FixCountRecord(cacheId, pageId, cnt);
break;
case BTREE_PAGE_REPLACE:
cacheId = in.readInt();
pageId = in.readLong();
ioType = in.readUnsignedShort();
ioVer = in.readUnsignedShort();
itemIdx = in.readUnsignedShort();
io = BPlusIO.getBPlusIO(ioType, ioVer);
rowBytes = new byte[io.getItemSize()];
in.readFully(rowBytes);
res = new ReplaceRecord<>(cacheId, pageId, io, rowBytes, itemIdx);
break;
case BTREE_PAGE_REMOVE:
cacheId = in.readInt();
pageId = in.readLong();
itemIdx = in.readUnsignedShort();
cnt = in.readUnsignedShort();
res = new RemoveRecord(cacheId, pageId, itemIdx, cnt);
break;
case BTREE_PAGE_INNER_REPLACE:
cacheId = in.readInt();
pageId = in.readLong();
int dstIdx = in.readUnsignedShort();
long srcPageId = in.readLong();
int srcIdx = in.readUnsignedShort();
rmvId = in.readLong();
res = new InnerReplaceRecord<>(cacheId, pageId, dstIdx, srcPageId, srcIdx, rmvId);
break;
case BTREE_FORWARD_PAGE_SPLIT:
cacheId = in.readInt();
pageId = in.readLong();
long fwdId = in.readLong();
ioType = in.readUnsignedShort();
ioVer = in.readUnsignedShort();
srcPageId = in.readLong();
int mid = in.readUnsignedShort();
cnt = in.readUnsignedShort();
res = new SplitForwardPageRecord(cacheId, pageId, fwdId, ioType, ioVer, srcPageId, mid, cnt);
break;
case BTREE_EXISTING_PAGE_SPLIT:
cacheId = in.readInt();
pageId = in.readLong();
mid = in.readUnsignedShort();
fwdId = in.readLong();
res = new SplitExistingPageRecord(cacheId, pageId, mid, fwdId);
break;
case BTREE_PAGE_MERGE:
cacheId = in.readInt();
pageId = in.readLong();
long prntId = in.readLong();
int prntIdx = in.readUnsignedShort();
rightId = in.readLong();
boolean emptyBranch = in.readBoolean();
res = new MergeRecord<>(cacheId, pageId, prntId, prntIdx, rightId, emptyBranch);
break;
case BTREE_FIX_REMOVE_ID:
cacheId = in.readInt();
pageId = in.readLong();
rmvId = in.readLong();
res = new FixRemoveId(cacheId, pageId, rmvId);
break;
case PAGES_LIST_SET_NEXT:
cacheId = in.readInt();
pageId = in.readLong();
long nextPageId = in.readLong();
res = new PagesListSetNextRecord(cacheId, pageId, nextPageId);
break;
case PAGES_LIST_SET_PREVIOUS:
cacheId = in.readInt();
pageId = in.readLong();
long prevPageId = in.readLong();
res = new PagesListSetPreviousRecord(cacheId, pageId, prevPageId);
break;
case PAGES_LIST_INIT_NEW_PAGE:
cacheId = in.readInt();
pageId = in.readLong();
ioType = in.readInt();
ioVer = in.readInt();
newPageId = in.readLong();
prevPageId = in.readLong();
long addDataPageId = in.readLong();
res = new PagesListInitNewPageRecord(cacheId, pageId, ioType, ioVer, newPageId, prevPageId, addDataPageId);
break;
case PAGES_LIST_ADD_PAGE:
cacheId = in.readInt();
pageId = in.readLong();
long dataPageId = in.readLong();
res = new PagesListAddPageRecord(cacheId, pageId, dataPageId);
break;
case PAGES_LIST_REMOVE_PAGE:
cacheId = in.readInt();
pageId = in.readLong();
long rmvdPageId = in.readLong();
res = new PagesListRemovePageRecord(cacheId, pageId, rmvdPageId);
break;
case TRACKING_PAGE_DELTA:
cacheId = in.readInt();
pageId = in.readLong();
long pageIdToMark = in.readLong();
long nextSnapshotId0 = in.readLong();
long lastSuccessfulSnapshotId0 = in.readLong();
res = new TrackingPageDeltaRecord(cacheId, pageId, pageIdToMark, nextSnapshotId0, lastSuccessfulSnapshotId0);
break;
case META_PAGE_UPDATE_NEXT_SNAPSHOT_ID:
cacheId = in.readInt();
pageId = in.readLong();
long nextSnapshotId = in.readLong();
res = new MetaPageUpdateNextSnapshotId(cacheId, pageId, nextSnapshotId);
break;
case META_PAGE_UPDATE_LAST_SUCCESSFUL_FULL_SNAPSHOT_ID:
cacheId = in.readInt();
pageId = in.readLong();
long lastSuccessfulFullSnapshotId = in.readLong();
res = new MetaPageUpdateLastSuccessfulFullSnapshotId(cacheId, pageId, lastSuccessfulFullSnapshotId);
break;
case META_PAGE_UPDATE_LAST_SUCCESSFUL_SNAPSHOT_ID:
cacheId = in.readInt();
pageId = in.readLong();
long lastSuccessfulSnapshotId = in.readLong();
long lastSuccessfulSnapshotTag = in.readLong();
res = new MetaPageUpdateLastSuccessfulSnapshotId(cacheId, pageId, lastSuccessfulSnapshotId, lastSuccessfulSnapshotTag);
break;
case META_PAGE_UPDATE_LAST_ALLOCATED_INDEX:
cacheId = in.readInt();
pageId = in.readLong();
int lastAllocatedIdx = in.readInt();
res = new MetaPageUpdateLastAllocatedIndex(cacheId, pageId, lastAllocatedIdx);
break;
case PART_META_UPDATE_STATE:
cacheId = in.readInt();
partId = in.readInt();
state = in.readByte();
long updateCntr = in.readLong();
GridDhtPartitionState partState = GridDhtPartitionState.fromOrdinal(state);
res = new PartitionMetaStateRecord(cacheId, partId, partState, updateCntr);
break;
case PAGE_LIST_META_RESET_COUNT_RECORD:
cacheId = in.readInt();
pageId = in.readLong();
res = new PageListMetaResetCountRecord(cacheId, pageId);
break;
case SWITCH_SEGMENT_RECORD:
throw new EOFException("END OF SEGMENT");
case TX_RECORD:
res = txRecordSerializer.read(in);
break;
default:
throw new UnsupportedOperationException("Type: " + type);
}
return res;
}
use of org.apache.ignite.internal.pagemem.wal.record.delta.PagesListSetNextRecord in project ignite by apache.
the class PagesList method putReuseBag.
/**
* @param pageId Page ID.
* @param page Page pointer.
* @param pageAddr Page address.
* @param io IO.
* @param bag Reuse bag.
* @param bucket Bucket.
* @return {@code true} If succeeded.
* @throws IgniteCheckedException if failed.
*/
@SuppressWarnings("ForLoopReplaceableByForEach")
private boolean putReuseBag(final long pageId, final long page, final long pageAddr, PagesListNodeIO io, ReuseBag bag, int bucket) throws IgniteCheckedException {
assert bag != null : "bag is null";
assert !bag.isEmpty() : "bag is empty";
if (io.getNextId(pageAddr) != 0L)
// Splitted.
return false;
long nextId;
long prevId = pageId;
long prevPage = page;
long prevAddr = pageAddr;
Boolean walPlc = null;
// TODO may be unlock right away and do not keep all these pages locked?
GridLongList locked = null;
try {
while ((nextId = bag.pollFreePage()) != 0L) {
int idx = io.addPage(prevAddr, nextId, pageSize());
if (idx == -1) {
// Attempt to add page failed: the node page is full.
final long nextPage = acquirePage(nextId);
try {
// Page from reuse bag can't be concurrently recycled.
long nextPageAddr = writeLock(nextId, nextPage);
assert nextPageAddr != 0L;
if (locked == null)
locked = new GridLongList(6);
locked.add(nextId);
locked.add(nextPage);
locked.add(nextPageAddr);
setupNextPage(io, prevId, prevAddr, nextId, nextPageAddr);
if (needWalDeltaRecord(prevId, prevPage, walPlc))
wal.log(new PagesListSetNextRecord(grpId, prevId, nextId));
// Here we should never write full page, because it is known to be new.
if (needWalDeltaRecord(nextId, nextPage, FALSE))
wal.log(new PagesListInitNewPageRecord(grpId, nextId, io.getType(), io.getVersion(), nextId, prevId, 0L));
// In reuse bucket the page itself can be used as a free page.
if (isReuseBucket(bucket))
incrementBucketSize(bucket);
// Switch to this new page, which is now a part of our list
// to add the rest of the bag to the new page.
prevAddr = nextPageAddr;
prevId = nextId;
prevPage = nextPage;
// Starting from tis point all wal records are written for reused pages from the bag.
// This mean that we use delta records only.
walPlc = FALSE;
} finally {
releasePage(nextId, nextPage);
}
} else {
// TODO: use single WAL record for bag?
if (needWalDeltaRecord(prevId, prevPage, walPlc))
wal.log(new PagesListAddPageRecord(grpId, prevId, nextId));
incrementBucketSize(bucket);
}
}
} finally {
if (locked != null) {
// We have to update our bucket with the new tail.
updateTail(bucket, pageId, prevId);
// Release write.
for (int i = 0; i < locked.size(); i += 3) writeUnlock(locked.get(i), locked.get(i + 1), locked.get(i + 2), FALSE, true);
}
}
return true;
}
Aggregations