This is an automated email from the ASF dual-hosted git repository.
ibessonov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new c6761344e6 IGNITE-17535 Implemented a hash index B+Tree (#1021)
c6761344e6 is described below
commit c6761344e635b7c7798a2fd3bcb9316d932936be
Author: Kirill Tkalenko <[email protected]>
AuthorDate: Wed Aug 31 13:18:48 2022 +0300
IGNITE-17535 Implemented a hash index B+Tree (#1021)
---
.../pagememory/datastructure/DataStructure.java | 4 +-
.../pagememory/freelist/AbstractFreeList.java | 2 +-
.../internal/pagememory/freelist/PagesList.java | 10 +-
.../internal/pagememory/io/AbstractDataPageIo.java | 114 ++++---------
.../pagememory/persistence/PageStoreWriter.java | 1 -
.../replacement/DelayedDirtyPageWrite.java | 1 -
.../persistence/store/AbstractFilePageStoreIo.java | 2 +-
.../internal/pagememory/util/PageIdUtils.java | 70 ++++----
.../pagememory/util}/PartitionlessLinks.java | 17 +-
.../pagememory/freelist/TestDataPageIo.java | 6 +-
.../internal/pagememory/util/PageIdUtilsTest.java | 4 +-
.../pagememory/index/IndexPageIoModule.java | 12 +-
.../storage/pagememory/index/IndexPageTypes.java | 44 +++++
.../pagememory/index/freelist/IndexColumns.java | 120 +++++++++++++
.../index/freelist/IndexColumnsFreeList.java | 77 +++++++++
.../ReadIndexColumnsValue.java} | 32 ++--
.../index/freelist/io/IndexColumnsDataIo.java | 83 +++++++++
.../pagememory/index/hash/HashIndexRow.java | 61 +++++++
.../pagememory/index/hash/HashIndexRowKey.java | 55 ++++++
.../IndexMetaTree.java => hash/HashIndexTree.java} | 66 ++++----
.../hash/InsertHashIndexRowInvokeClosure.java | 83 +++++++++
.../hash/RemoveHashIndexRowInvokeClosure.java | 99 +++++++++++
.../index/hash/io/HashIndexTreeInnerIo.java | 61 +++++++
.../pagememory/index/hash/io/HashIndexTreeIo.java | 188 +++++++++++++++++++++
.../index/hash/io/HashIndexTreeLeafIo.java | 61 +++++++
.../io/HashIndexTreeMetaIo.java} | 18 +-
.../pagememory/index/meta/IndexMetaTree.java | 16 +-
.../pagememory/index/meta/io/IndexMetaInnerIo.java | 6 +-
.../pagememory/index/meta/io/IndexMetaIo.java | 3 +-
.../pagememory/index/meta/io/IndexMetaLeafIo.java | 6 +-
.../index/meta/io/IndexMetaTreeMetaIo.java | 6 +-
.../mv/AbstractPageMemoryMvPartitionStorage.java | 8 +-
.../storage/pagememory/mv/ReadRowVersion.java | 2 +-
.../internal/storage/pagememory/mv/RowVersion.java | 5 +-
.../storage/pagememory/mv/RowVersionFreeList.java | 3 -
.../pagememory/mv/ScanVersionChainByTimestamp.java | 5 +-
.../storage/pagememory/mv/VersionChain.java | 4 +-
.../storage/pagememory/mv/io/RowVersionDataIo.java | 35 ++--
.../storage/pagememory/mv/io/VersionChainIo.java | 6 +-
39 files changed, 1125 insertions(+), 271 deletions(-)
diff --git
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
index 355ec47a09..16d0559ff7 100644
---
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
+++
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/datastructure/DataStructure.java
@@ -19,7 +19,7 @@ package org.apache.ignite.internal.pagememory.datastructure;
import static org.apache.ignite.internal.pagememory.PageIdAllocator.FLAG_DATA;
import static
org.apache.ignite.internal.pagememory.PageIdAllocator.MAX_PARTITION_ID;
-import static
org.apache.ignite.internal.pagememory.util.PageIdUtils.MAX_ITEMID_NUM;
+import static
org.apache.ignite.internal.pagememory.util.PageIdUtils.MAX_ITEM_ID_NUM;
import static org.apache.ignite.internal.pagememory.util.PageIdUtils.flag;
import static org.apache.ignite.internal.pagememory.util.PageIdUtils.itemId;
import static
org.apache.ignite.internal.pagememory.util.PageIdUtils.partitionId;
@@ -453,7 +453,7 @@ public abstract class DataStructure {
recycled = PageIdUtils.rotatePageId(pageId);
}
- assert itemId(recycled) > 0 && itemId(recycled) <= MAX_ITEMID_NUM :
IgniteUtils.hexLong(recycled);
+ assert itemId(recycled) > 0 && itemId(recycled) <= MAX_ITEM_ID_NUM :
IgniteUtils.hexLong(recycled);
PageIo.setPageId(pageAddr, recycled);
diff --git
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/AbstractFreeList.java
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/AbstractFreeList.java
index 287caa5ff7..9c104cd9a0 100644
---
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/AbstractFreeList.java
+++
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/AbstractFreeList.java
@@ -81,7 +81,7 @@ public abstract class AbstractFreeList<T extends Storable>
extends PagesList imp
private final @Nullable AtomicLong pageListCacheLimit;
/** Page eviction tracker. */
- private final PageEvictionTracker evictionTracker;
+ protected final PageEvictionTracker evictionTracker;
private final PageHandler<T, Boolean> updateRow = new UpdateRowHandler();
diff --git
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/PagesList.java
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/PagesList.java
index 11b54485d3..724396b9f9 100644
---
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/PagesList.java
+++
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/freelist/PagesList.java
@@ -25,8 +25,8 @@ import static
org.apache.ignite.internal.pagememory.PageIdAllocator.FLAG_DATA;
import static
org.apache.ignite.internal.pagememory.freelist.io.PagesListNodeIo.T_PAGE_LIST_NODE;
import static org.apache.ignite.internal.pagememory.io.PageIo.getPageId;
import static org.apache.ignite.internal.pagememory.io.PageIo.getType;
-import static
org.apache.ignite.internal.pagememory.util.PageIdUtils.MAX_ITEMID_NUM;
-import static
org.apache.ignite.internal.pagememory.util.PageIdUtils.changeType;
+import static
org.apache.ignite.internal.pagememory.util.PageIdUtils.MAX_ITEM_ID_NUM;
+import static
org.apache.ignite.internal.pagememory.util.PageIdUtils.changeFlag;
import static org.apache.ignite.internal.pagememory.util.PageIdUtils.itemId;
import static org.apache.ignite.internal.pagememory.util.PageIdUtils.pageId;
import static
org.apache.ignite.internal.pagememory.util.PageIdUtils.partitionId;
@@ -988,7 +988,7 @@ public abstract class PagesList extends DataStructure {
assert dataIo.isEmpty(dataAddr); // We can put only empty data
pages to reuse bucket.
// Change page type to index and add it as next node page to this
list.
- long newDataId = changeType(dataId, FLAG_AUX);
+ long newDataId = changeFlag(dataId, FLAG_AUX);
setupNextPage(io, pageId, pageAddr, newDataId, dataAddr);
@@ -1065,7 +1065,7 @@ public abstract class PagesList extends DataStructure {
try {
while ((nextId = bag.pollFreePage()) != 0L) {
- assert itemId(nextId) > 0 && itemId(nextId) <= MAX_ITEMID_NUM
: hexLong(nextId);
+ assert itemId(nextId) > 0 && itemId(nextId) <= MAX_ITEM_ID_NUM
: hexLong(nextId);
int idx = io.addPage(prevAddr, nextId, pageSize());
@@ -1266,7 +1266,7 @@ public abstract class PagesList extends DataStructure {
dirty = true;
- if (isReuseBucket(bucket) && !(itemId(pageId) > 0 &&
itemId(pageId) <= MAX_ITEMID_NUM)) {
+ if (isReuseBucket(bucket) && !(itemId(pageId) > 0 &&
itemId(pageId) <= MAX_ITEM_ID_NUM)) {
throw corruptedFreeListException("Incorrectly
recycled pageId in reuse bucket: " + hexLong(pageId), pageId);
}
diff --git
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/io/AbstractDataPageIo.java
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/io/AbstractDataPageIo.java
index c63fac03e0..ac7b967b7f 100644
---
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/io/AbstractDataPageIo.java
+++
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/io/AbstractDataPageIo.java
@@ -1235,99 +1235,32 @@ public abstract class AbstractDataPageIo<T extends
Storable> extends PageIo {
) throws IgniteInternalCheckedException {
assertPageType(pageAddr);
- return addRowFragment(pageMem, pageId, pageAddr, written, rowSize,
row.link(), row, null, pageSize);
- }
-
- /**
- * Adds this payload as a fragment to this data page.
- *
- * @param pageId Page ID to use to construct a link.
- * @param pageAddr Page address.
- * @param payload Payload bytes.
- * @param lastLink Link to the previous written fragment (link to the
tail).
- * @param pageSize Page size.
- * @throws IgniteInternalCheckedException If failed.
- */
- public void addRowFragment(
- long pageId,
- long pageAddr,
- byte[] payload,
- long lastLink,
- int pageSize
- ) throws IgniteInternalCheckedException {
- assertPageType(pageAddr);
+ assert row != null;
- addRowFragment(null, pageId, pageAddr, 0, 0, lastLink, null, payload,
pageSize);
- }
-
- /**
- * Adds maximum possible fragment of the given row to this data page and
sets respective link to the row.
- *
- * @param pageMem Page memory.
- * @param pageId Page ID to use to construct a link.
- * @param pageAddr Page address.
- * @param written Number of bytes of row size that was already written.
- * @param rowSize Row size.
- * @param lastLink Link to the previous written fragment (link to the
tail).
- * @param row Row.
- * @param payload Payload bytes.
- * @param pageSize Page size.
- * @return Written payload size.
- * @throws IgniteInternalCheckedException If failed.
- */
- private int addRowFragment(
- PageMemory pageMem,
- long pageId,
- long pageAddr,
- int written,
- int rowSize,
- long lastLink,
- T row,
- byte[] payload,
- int pageSize
- ) throws IgniteInternalCheckedException {
- assert payload == null ^ row == null;
+ long lastLink = row.link();
int directCnt = getDirectCount(pageAddr);
int indirectCnt = getIndirectCount(pageAddr);
- int payloadSize = payload != null ? payload.length :
- Math.min(rowSize - written, getFreeSpace(pageAddr));
+ int payloadSize = Math.min(rowSize - written, getFreeSpace(pageAddr));
- if (row != null) {
- int remain = rowSize - written - payloadSize;
- int hdrSize = row.headerSize();
-
- // We need page header (i.e. MVCC info) is located entirely on the
very first page in chain.
- // So we force moving it to the next page if it could not fit
entirely on this page.
- if (remain > 0 && remain < hdrSize) {
- payloadSize -= hdrSize - remain;
- }
- }
+ assert payloadSize >= row.headerSize() || written >= row.headerSize();
int fullEntrySize = getPageEntrySize(payloadSize, SHOW_PAYLOAD_LEN |
SHOW_LINK | SHOW_ITEM);
int dataOff = getDataOffsetForWrite(pageAddr, fullEntrySize,
directCnt, indirectCnt, pageSize);
- if (payload == null) {
- ByteBuffer buf = pageMem.pageBuffer(pageAddr);
-
- buf.position(dataOff);
+ ByteBuffer buf = pageMem.pageBuffer(pageAddr);
- short p = (short) (payloadSize | FRAGMENTED_FLAG);
+ buf.position(dataOff);
- buf.putShort(p);
- buf.putLong(lastLink);
+ short fragmentSize = (short) (payloadSize | FRAGMENTED_FLAG);
- int rowOff = rowSize - written - payloadSize;
+ buf.putShort(fragmentSize);
+ buf.putLong(lastLink);
- writeFragmentData(row, buf, rowOff, payloadSize);
- } else {
- PageUtils.putShort(pageAddr, dataOff, (short) (payloadSize |
FRAGMENTED_FLAG));
+ int rowOff = rowSize - written - payloadSize;
- PageUtils.putLong(pageAddr, dataOff + 2, lastLink);
-
- PageUtils.putBytes(pageAddr, dataOff + 10, payload);
- }
+ writeFragmentData(row, buf, rowOff, payloadSize);
int itemId = addItem(pageAddr, fullEntrySize, directCnt, indirectCnt,
dataOff, pageSize);
@@ -1353,18 +1286,39 @@ public abstract class AbstractDataPageIo<T extends
Storable> extends PageIo {
* Writes row data fragment.
*
* @param row Row.
- * @param buf Byte buffer.
+ * @param pageBuf Byte buffer.
* @param rowOff Offset in row data bytes.
* @param payloadSize Data length that should be written in a fragment.
* @throws IgniteInternalCheckedException If failed.
*/
protected abstract void writeFragmentData(
final T row,
- final ByteBuffer buf,
+ final ByteBuffer pageBuf,
final int rowOff,
final int payloadSize
) throws IgniteInternalCheckedException;
+ /**
+ * Writes a content of a byte buffer into a page.
+ *
+ * @param pageBuffer Direct page buffer.
+ * @param valueBuffer Byte buffer with value bytes.
+ * @param offset Offset within the value buffer.
+ * @param payloadSize Number of bytes to write.
+ */
+ protected void putValueBufferIntoPage(ByteBuffer pageBuffer, ByteBuffer
valueBuffer, int offset, int payloadSize) {
+ int oldPosition = valueBuffer.position();
+ int oldLimit = valueBuffer.limit();
+
+ valueBuffer.position(offset);
+ valueBuffer.limit(offset + payloadSize);
+
+ pageBuffer.put(valueBuffer);
+
+ valueBuffer.position(oldPosition);
+ valueBuffer.limit(oldLimit);
+ }
+
/**
* Inserts an item.
*
diff --git
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PageStoreWriter.java
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PageStoreWriter.java
index 8aeb212f8c..519ce986f7 100644
---
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PageStoreWriter.java
+++
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/PageStoreWriter.java
@@ -26,7 +26,6 @@ import org.apache.ignite.lang.IgniteInternalCheckedException;
/**
* Interface for write page to {@link PageStore}.
*/
-// TODO: IGNITE-15818 Maybe refactor.
public interface PageStoreWriter {
/**
* Callback for write page. {@link PersistentPageMemory} will copy page
content to buffer before call.
diff --git
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/replacement/DelayedDirtyPageWrite.java
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/replacement/DelayedDirtyPageWrite.java
index 8e4bd74d24..97b3469633 100644
---
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/replacement/DelayedDirtyPageWrite.java
+++
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/replacement/DelayedDirtyPageWrite.java
@@ -32,7 +32,6 @@ import org.jetbrains.annotations.Nullable;
* segment lock. Page data is copied into temp buffer during {@link
#write(PersistentPageMemory, FullPageId, ByteBuffer)} and then sent to
* real implementation by {@link #finishReplacement}.
*/
-// TODO: IGNITE-15818 Maybe refactor.
public class DelayedDirtyPageWrite implements WriteDirtyPage {
/** Real flush dirty page implementation. */
private final WriteDirtyPage flushDirtyPage;
diff --git
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/AbstractFilePageStoreIo.java
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/AbstractFilePageStoreIo.java
index 7043f90abf..dbe36c50dd 100644
---
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/AbstractFilePageStoreIo.java
+++
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/persistence/store/AbstractFilePageStoreIo.java
@@ -54,7 +54,7 @@ public abstract class AbstractFilePageStoreIo implements
Closeable {
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
/** Skip CRC calculation flag. */
- // TODO: IGNITE-17011 Move to config
+ // TODO: IGNITE-16350 Move to config
private final boolean skipCrc = getBoolean("IGNITE_PDS_SKIP_CRC");
private volatile Path filePath;
diff --git
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageIdUtils.java
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageIdUtils.java
index 9712ad3cc1..67eaac3766 100644
---
a/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageIdUtils.java
+++
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PageIdUtils.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.pagememory.util;
+import static org.apache.ignite.internal.pagememory.PageIdAllocator.FLAG_DATA;
+
import org.apache.ignite.internal.pagememory.FullPageId;
import org.apache.ignite.internal.pagememory.PageIdAllocator;
import org.apache.ignite.internal.util.IgniteUtils;
@@ -27,6 +29,9 @@ import org.apache.ignite.internal.util.IgniteUtils;
* @see FullPageId
*/
public final class PageIdUtils {
+ /** Represents an absent or missing link. */
+ public static final long NULL_LINK = 0;
+
/** Size of the page index portion. */
public static final int PAGE_IDX_SIZE = Integer.SIZE;
@@ -40,7 +45,7 @@ public final class PageIdUtils {
public static final int OFFSET_SIZE = Byte.SIZE;
/** Size of a tag portion. */
- public static final int TAG_SIZE = 2 * Byte.SIZE;
+ public static final int TAG_SIZE = Short.SIZE;
/** Page index mask. */
public static final long PAGE_IDX_MASK = ~(-1L << PAGE_IDX_SIZE);
@@ -54,74 +59,64 @@ public final class PageIdUtils {
/** Page Index is a monotonically growing number within each partition. */
public static final long PART_ID_MASK = ~(-1L << PART_ID_SIZE);
- /** Flags mask. Flags consists of a number of reserved bits, and page type
(data/index page). */
+ /** Flag mask {@link PageIdAllocator#FLAG_DATA} of {@link
PageIdAllocator#FLAG_AUX}. */
public static final long FLAG_MASK = ~(-1L << FLAG_SIZE);
/** Effective page ID mask. */
private static final long EFFECTIVE_PAGE_ID_MASK = ~(-1L << (PAGE_IDX_SIZE
+ PART_ID_SIZE));
- /**
- * Offset of a Rotation ID inside a Page ID.
- */
+ /** Offset of a rotation ID inside a Page ID. */
private static final long ROTATION_ID_OFFSET = PAGE_IDX_SIZE +
PART_ID_SIZE + FLAG_SIZE;
/** Page ID mask that excludes link. */
private static final long PAGE_ID_MASK = ~(-1L << ROTATION_ID_OFFSET);
- /** Max itemid number. */
- public static final int MAX_ITEMID_NUM = 0xFE;
+ /** Max item ID number. */
+ public static final int MAX_ITEM_ID_NUM = 0xFE;
/** Maximum page number. */
public static final long MAX_PAGE_NUM = (1L << PAGE_IDX_SIZE) - 1;
- /** Maximum page number. */
+ /** Maximum partition ID. */
public static final int MAX_PART_ID = (1 << PART_ID_SIZE) - 1;
- /** Private constructor. */
- private PageIdUtils() {
- // No-op.
- }
-
/**
* Constructs a page link by the given page ID and 8-byte words within the
page.
*
* @param pageId Page ID.
* @param itemId Item ID.
- * @return Page link.
*/
public static long link(long pageId, int itemId) {
- assert itemId >= 0 && itemId <= MAX_ITEMID_NUM : itemId;
+ assert itemId >= 0 && itemId <= MAX_ITEM_ID_NUM : itemId;
assert (pageId >> ROTATION_ID_OFFSET) == 0 :
IgniteUtils.hexLong(pageId);
return pageId | (((long) itemId) << ROTATION_ID_OFFSET);
}
/**
- * Extracts a page index from the given page ID.
+ * Extracts a page index from the page ID.
*
* @param pageId Page ID.
- * @return Page index.
*/
public static int pageIndex(long pageId) {
return (int) (pageId & PAGE_IDX_MASK); // 4 bytes
}
/**
- * Extracts a page ID from the given page link.
+ * Extracts a page ID from the page link.
*
* @param link Page link.
- * @return Page ID.
*/
public static long pageId(long link) {
- return flag(link) == PageIdAllocator.FLAG_DATA ? link & PAGE_ID_MASK :
link;
+ return flag(link) == FLAG_DATA ? link & PAGE_ID_MASK : link;
}
/**
* Creates page ID from its components.
*
* @param partitionId Partition ID.
- * @param flag Flags (a number of reserved bits, and page type
(data/index page))
- * @param pageIdx Page index, monotonically growing number within each
partition
+ * @param flag Flag: {@link PageIdAllocator#FLAG_DATA} of {@link
PageIdAllocator#FLAG_AUX}.
+ * @param pageIdx Page index, monotonically growing number within each
partition.
* @return Page ID constructed from the given pageIdx and partition ID,
see {@link FullPageId}
*/
public static long pageId(int partitionId, byte flag, int pageIdx) {
@@ -134,10 +129,9 @@ public final class PageIdUtils {
}
/**
- * Converts link into an effective page ID: pageId with only pageIdx and
partitionId.
+ * Converts page link into an effective page ID: page ID with only page
index and partition ID.
*
* @param link Page link.
- * @return Effective page id.
*/
public static long effectivePageId(long link) {
return link & EFFECTIVE_PAGE_ID_MASK;
@@ -147,37 +141,33 @@ public final class PageIdUtils {
* Checks whether page ID matches effective page ID.
*
* @param pageId Page id.
- * @return {@code True} if page id is equal to effective page id.
*/
public static boolean isEffectivePageId(long pageId) {
return (pageId & ~EFFECTIVE_PAGE_ID_MASK) == 0;
}
/**
- * Index of the item inside of data page.
+ * Extracts item id (Offset in 8-byte words) from the page link.
*
* @param link Page link.
- * @return Offset in 8-byte words.
*/
public static int itemId(long link) {
return (int) ((link >> ROTATION_ID_OFFSET) & OFFSET_MASK);
}
/**
- * Tag of pageId.
+ * Extracts tag (item id + flag) from the page link.
*
* @param link Page link.
- * @return tag - item id + flags
*/
public static int tag(long link) {
return (int) ((link >> (PAGE_IDX_SIZE + PART_ID_SIZE)) & TAG_MASK);
}
/**
- * Extracts flags byte from the page ID.
+ * Extracts flag ({@link PageIdAllocator#FLAG_DATA} of {@link
PageIdAllocator#FLAG_AUX}) from the page ID.
*
* @param pageId Page ID.
- * @return Flag.
*/
public static byte flag(long pageId) {
return (byte) ((pageId >>> (PART_ID_SIZE + PAGE_IDX_SIZE)) &
FLAG_MASK);
@@ -187,14 +177,15 @@ public final class PageIdUtils {
* Extracts partition ID from the page ID.
*
* @param pageId Page ID.
- * @return Partition ID.
*/
public static int partitionId(long pageId) {
return (int) ((pageId >>> PAGE_IDX_SIZE) & PART_ID_MASK);
}
/**
- * Returns the Rotation ID of a page identified by the given ID.
+ * Extracts rotation ID from the page ID.
+ *
+ * @param pageId Page ID.
*/
public static long rotationId(long pageId) {
return pageId >>> ROTATION_ID_OFFSET;
@@ -209,7 +200,7 @@ public final class PageIdUtils {
public static long rotatePageId(long pageId) {
long updatedRotationId = rotationId(pageId) + 1;
- if (updatedRotationId > MAX_ITEMID_NUM) {
+ if (updatedRotationId > MAX_ITEM_ID_NUM) {
updatedRotationId = 1; // We always want non-zero updatedRotationId
}
@@ -227,14 +218,14 @@ public final class PageIdUtils {
}
/**
- * Change page type.
+ * Change page flag.
*
* @param pageId Old page ID.
- * @param type New page type.
+ * @param flag New page flag: {@link PageIdAllocator#FLAG_AUX} or {@link
PageIdAllocator#FLAG_DATA}.
* @return Changed page ID.
*/
- public static long changeType(long pageId, byte type) {
- return pageId(partitionId(pageId), type, pageIndex(pageId));
+ public static long changeFlag(long pageId, byte flag) {
+ return pageId(partitionId(pageId), flag, pageIndex(pageId));
}
/**
@@ -254,8 +245,9 @@ public final class PageIdUtils {
/**
* Replaces partition ID in the page ID.
*
- * @param pageId Page ID.
+ * @param pageId Page ID.
* @param partitionId Partition ID.
+ * @return Changed page ID.
*/
public static long changePartitionId(long pageId, int partitionId) {
byte flag = flag(pageId);
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PartitionlessLinks.java
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PartitionlessLinks.java
similarity index 86%
rename from
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PartitionlessLinks.java
rename to
modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PartitionlessLinks.java
index 26bb54a421..996d8db58e 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/PartitionlessLinks.java
+++
b/modules/page-memory/src/main/java/org/apache/ignite/internal/pagememory/util/PartitionlessLinks.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.storage.pagememory.mv;
+package org.apache.ignite.internal.pagememory.util;
import static org.apache.ignite.internal.pagememory.util.PageIdUtils.link;
import static org.apache.ignite.internal.pagememory.util.PageIdUtils.pageId;
@@ -27,23 +27,22 @@ import static
org.apache.ignite.internal.pagememory.util.PageUtils.putInt;
import static org.apache.ignite.internal.pagememory.util.PageUtils.putShort;
import java.nio.ByteBuffer;
-import org.apache.ignite.internal.pagememory.util.PageIdUtils;
/**
- * Handling of <em>partitionless links</em>, that is, page memory links from
which partition ID is removed. They are used to spare storage
- * space in cases when we know the partition ID from the context.
+ * Handling of <em>partitionless links</em>, that is, page memory links from
which partition ID is removed.
+ *
+ * <p>They are used to save storage space in cases when we know the partition
ID from the context.
*
* @see PageIdUtils#link(long, int)
*/
public class PartitionlessLinks {
- /**
- * Number of bytes a partitionless link takes in storage.
- */
+ /** Number of bytes a partitionless link takes in storage. */
public static final int PARTITIONLESS_LINK_SIZE_BYTES = 6;
/**
* Reads a partitionless link from the memory.
*
+ * @param partitionId Partition ID.
* @param pageAddr Page address.
* @param offset Data offset.
* @return Partitionless link.
@@ -52,11 +51,11 @@ public class PartitionlessLinks {
int tag = getShort(pageAddr, offset) & 0xFFFF;
int pageIdx = getInt(pageAddr, offset + Short.BYTES);
- // Links to metapages are impossible. For the sake of simplicity,
NULL_LINK is returned in this case.
+ // NULL_LINK is stored as zeroes. This is fine, because no real link
can be like this. Page with index 0 is never a data page.
if (pageIdx == 0) {
assert tag == 0 : tag;
- return RowVersion.NULL_LINK;
+ return PageIdUtils.NULL_LINK;
}
byte flags = (byte) tag;
diff --git
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/TestDataPageIo.java
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/TestDataPageIo.java
index 336fe16032..0a9567b1b5 100644
---
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/TestDataPageIo.java
+++
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/freelist/TestDataPageIo.java
@@ -57,11 +57,11 @@ class TestDataPageIo extends
AbstractDataPageIo<TestDataRow> {
/** {@inheritDoc} */
@Override
- protected void writeFragmentData(TestDataRow row, ByteBuffer buf, int
rowOff, int payloadSize) {
- assertPageType(buf);
+ protected void writeFragmentData(TestDataRow row, ByteBuffer pageBuf, int
rowOff, int payloadSize) {
+ assertPageType(pageBuf);
if (payloadSize > 0) {
- buf.put(row.bytes, rowOff, payloadSize);
+ pageBuf.put(row.bytes, rowOff, payloadSize);
}
}
diff --git
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/util/PageIdUtilsTest.java
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/util/PageIdUtilsTest.java
index 7760e22d0e..10ad125185 100644
---
a/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/util/PageIdUtilsTest.java
+++
b/modules/page-memory/src/test/java/org/apache/ignite/internal/pagememory/util/PageIdUtilsTest.java
@@ -121,11 +121,11 @@ public class PageIdUtilsTest {
}
@Test
- public void testRandomIds() throws Exception {
+ public void testRandomIds() {
Random rnd = new Random();
for (int i = 0; i < 50_000; i++) {
- int off = rnd.nextInt(PageIdUtils.MAX_ITEMID_NUM + 1);
+ int off = rnd.nextInt(PageIdUtils.MAX_ITEM_ID_NUM + 1);
int partId = rnd.nextInt(PageIdUtils.MAX_PART_ID + 1);
int pageNum = rnd.nextInt();
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/IndexPageIoModule.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/IndexPageIoModule.java
index d463333673..a00368d279 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/IndexPageIoModule.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/IndexPageIoModule.java
@@ -22,6 +22,10 @@ import java.util.List;
import org.apache.ignite.internal.pagememory.PageMemory;
import org.apache.ignite.internal.pagememory.io.IoVersions;
import org.apache.ignite.internal.pagememory.io.PageIoModule;
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.io.IndexColumnsDataIo;
+import
org.apache.ignite.internal.storage.pagememory.index.hash.io.HashIndexTreeInnerIo;
+import
org.apache.ignite.internal.storage.pagememory.index.hash.io.HashIndexTreeLeafIo;
+import
org.apache.ignite.internal.storage.pagememory.index.hash.io.HashIndexTreeMetaIo;
import
org.apache.ignite.internal.storage.pagememory.index.meta.io.IndexMetaInnerIo;
import
org.apache.ignite.internal.storage.pagememory.index.meta.io.IndexMetaLeafIo;
import
org.apache.ignite.internal.storage.pagememory.index.meta.io.IndexMetaTreeMetaIo;
@@ -34,9 +38,15 @@ public class IndexPageIoModule implements PageIoModule {
@Override
public Collection<IoVersions<?>> ioVersions() {
return List.of(
+ IndexColumnsDataIo.VERSIONS,
+ // Meta tree IO.
IndexMetaTreeMetaIo.VERSIONS,
IndexMetaInnerIo.VERSIONS,
- IndexMetaLeafIo.VERSIONS
+ IndexMetaLeafIo.VERSIONS,
+ // Hash index IO.
+ HashIndexTreeMetaIo.VERSIONS,
+ HashIndexTreeInnerIo.VERSIONS,
+ HashIndexTreeLeafIo.VERSIONS
);
}
}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/IndexPageTypes.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/IndexPageTypes.java
new file mode 100644
index 0000000000..1621b2af26
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/IndexPageTypes.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index;
+
+/**
+ * Collection of all page types that relate to indexes.
+ */
+public interface IndexPageTypes {
+ /** Page IO type. */
+ short T_VALUE_VERSION_DATA_IO = 100;
+
+ /** Index meta tree meta IO type. */
+ short T_INDEX_META_TREE_META_IO = 101;
+
+ /** Index meta tree inner IO type. */
+ short T_INDEX_META_INNER_IO = 102;
+
+ /** Index meta tree leaf IO type. */
+ short T_INDEX_META_LEAF_IO = 103;
+
+ /** Hash index tree meta IO type. */
+ short T_HASH_INDEX_META_IO = 10_000;
+
+ /** Hash index tree inner IO type. */
+ short T_HASH_INDEX_INNER_IO = 10_001;
+
+ /** Hash index tree meta IO type. */
+ short T_HASH_INDEX_LEAF_IO = 10_002;
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/IndexColumns.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/IndexColumns.java
new file mode 100644
index 0000000000..803bb9940c
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/IndexColumns.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index.freelist;
+
+import static org.apache.ignite.internal.pagememory.util.PageIdUtils.NULL_LINK;
+
+import java.nio.ByteBuffer;
+import org.apache.ignite.internal.pagememory.Storable;
+import org.apache.ignite.internal.pagememory.io.AbstractDataPageIo;
+import org.apache.ignite.internal.pagememory.io.IoVersions;
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.io.IndexColumnsDataIo;
+import org.apache.ignite.lang.IgniteInternalCheckedException;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Index columns to store in free list.
+ */
+public class IndexColumns implements Storable {
+ /** Size offset. */
+ public static final int SIZE_OFFSET = 0;
+
+ /** Value offset. Value goes right after the size. */
+ public static final int VALUE_OFFSET = SIZE_OFFSET + Integer.BYTES;
+
+ /** Partition ID. */
+ private final int partitionId;
+
+ /** Link value. */
+ private long link = NULL_LINK;
+
+ /** Byte buffer with binary tuple data. */
+ private final @Nullable ByteBuffer valueBuffer;
+
+ /**
+ * Constructor.
+ *
+ * @param partitionId Partition ID.
+ * @param valueBuffer Value buffer.
+ */
+
+ public IndexColumns(int partitionId, @Nullable ByteBuffer valueBuffer) {
+ this.partitionId = partitionId;
+ this.valueBuffer = valueBuffer;
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param partitionId Partition ID.
+ * @param link Link.
+ * @param valueBuffer Value buffer.
+ */
+ public IndexColumns(int partitionId, long link, @Nullable ByteBuffer
valueBuffer) {
+ this.partitionId = partitionId;
+ this.link = link;
+ this.valueBuffer = valueBuffer;
+ }
+
+ /**
+ * Returns the size of binary tuple.
+ */
+ public int valueSize() {
+ assert valueBuffer != null;
+
+ return valueBuffer.limit();
+ }
+
+ /**
+ * Returns a byte buffer that contains binary tuple data.
+ */
+ public ByteBuffer valueBuffer() {
+ return valueBuffer;
+ }
+
+ @Override
+ public void link(long link) {
+ this.link = link;
+ }
+
+ @Override
+ public long link() {
+ return link;
+ }
+
+ @Override
+ public int partition() {
+ return partitionId;
+ }
+
+ @Override
+ public int size() throws IgniteInternalCheckedException {
+ return VALUE_OFFSET + valueSize();
+ }
+
+ @Override
+ public int headerSize() {
+ // Size of the tuple and its header. For further use in future
optimizations.
+ return VALUE_OFFSET + Byte.BYTES;
+ }
+
+ @Override
+ public IoVersions<? extends AbstractDataPageIo<?>> ioVersions() {
+ return IndexColumnsDataIo.VERSIONS;
+ }
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/IndexColumnsFreeList.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/IndexColumnsFreeList.java
new file mode 100644
index 0000000000..b66373bcfc
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/IndexColumnsFreeList.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index.freelist;
+
+import java.util.concurrent.atomic.AtomicLong;
+import org.apache.ignite.internal.logger.IgniteLogger;
+import org.apache.ignite.internal.pagememory.PageMemory;
+import org.apache.ignite.internal.pagememory.evict.PageEvictionTracker;
+import org.apache.ignite.internal.pagememory.freelist.AbstractFreeList;
+import org.apache.ignite.internal.pagememory.metric.IoStatisticsHolder;
+import org.apache.ignite.internal.pagememory.reuse.ReuseList;
+import org.apache.ignite.internal.pagememory.util.PageLockListener;
+import org.apache.ignite.lang.IgniteInternalCheckedException;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Free list implementation to store {@link IndexColumns} values.
+ */
+public class IndexColumnsFreeList extends AbstractFreeList<IndexColumns> {
+ /**
+ * Constructor.
+ *
+ * @param grpId Group ID.
+ * @param partId Partition ID.
+ * @param pageMem Page memory.
+ * @param reuseList Reuse list or {@code null} if this free list will be a
reuse list for itself.
+ * @param lockLsnr Page lock listener.
+ * @param log Logger.
+ * @param metaPageId Metadata page ID.
+ * @param initNew {@code True} if new metadata should be initialized.
+ * @param pageListCacheLimit Page list cache limit.
+ * @param evictionTracker Page eviction tracker.
+ * @throws IgniteInternalCheckedException If failed.
+ */
+ public IndexColumnsFreeList(
+ int grpId,
+ int partId,
+ PageMemory pageMem,
+ @Nullable ReuseList reuseList,
+ PageLockListener lockLsnr,
+ IgniteLogger log,
+ long metaPageId,
+ boolean initNew,
+ @Nullable AtomicLong pageListCacheLimit,
+ PageEvictionTracker evictionTracker,
+ IoStatisticsHolder statHolder
+ ) throws IgniteInternalCheckedException {
+ super(
+ grpId,
+ partId,
+ "IndexColumnsFreeList_" + grpId,
+ pageMem,
+ reuseList,
+ lockLsnr,
+ log,
+ metaPageId,
+ initNew,
+ pageListCacheLimit,
+ evictionTracker
+ );
+ }
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaTreeMetaIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/ReadIndexColumnsValue.java
similarity index 51%
copy from
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaTreeMetaIo.java
copy to
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/ReadIndexColumnsValue.java
index 9e8d229c15..9c30911e0a 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaTreeMetaIo.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/ReadIndexColumnsValue.java
@@ -15,28 +15,24 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.storage.pagememory.index.meta.io;
+package org.apache.ignite.internal.storage.pagememory.index.freelist;
-import org.apache.ignite.internal.pagememory.io.IoVersions;
-import org.apache.ignite.internal.pagememory.tree.io.BplusMetaIo;
-import org.apache.ignite.internal.storage.pagememory.index.meta.IndexMetaTree;
+import org.apache.ignite.internal.pagememory.datapage.ReadPageMemoryRowValue;
+import org.apache.ignite.internal.storage.pagememory.mv.RowVersion;
/**
- * IO routines for {@link IndexMetaTree} meta pages.
+ * Reads {@link RowVersion#value()} from page-memory.
*/
-public class IndexMetaTreeMetaIo extends BplusMetaIo {
- /** Page IO type. */
- public static final short T_INDEX_META_TREE_META_IO = 13;
-
- /** I/O versions. */
- public static final IoVersions<IndexMetaTreeMetaIo> VERSIONS = new
IoVersions<>(new IndexMetaTreeMetaIo(1));
+public class ReadIndexColumnsValue extends ReadPageMemoryRowValue {
+ /** {@inheritDoc} */
+ @Override
+ protected int valueSizeOffsetInFirstSlot() {
+ return IndexColumns.SIZE_OFFSET;
+ }
- /**
- * Constructor.
- *
- * @param ver Page format version.
- */
- protected IndexMetaTreeMetaIo(int ver) {
- super(T_INDEX_META_TREE_META_IO, ver);
+ /** {@inheritDoc} */
+ @Override
+ protected int valueOffsetInFirstSlot() {
+ return IndexColumns.VALUE_OFFSET;
}
}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/io/IndexColumnsDataIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/io/IndexColumnsDataIo.java
new file mode 100644
index 0000000000..002c86b949
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/freelist/io/IndexColumnsDataIo.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index.freelist.io;
+
+import static
org.apache.ignite.internal.pagememory.util.PageUtils.putByteBuffer;
+import static org.apache.ignite.internal.pagememory.util.PageUtils.putInt;
+
+import java.nio.ByteBuffer;
+import org.apache.ignite.internal.pagememory.io.AbstractDataPageIo;
+import org.apache.ignite.internal.pagememory.io.IoVersions;
+import org.apache.ignite.internal.storage.pagememory.index.IndexPageTypes;
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.IndexColumns;
+import org.apache.ignite.lang.IgniteStringBuilder;
+
+/**
+ * Data pages IO for {@link IndexColumns}.
+ */
+public class IndexColumnsDataIo extends AbstractDataPageIo<IndexColumns> {
+ /** I/O versions. */
+ public static final IoVersions<IndexColumnsDataIo> VERSIONS = new
IoVersions<>(new IndexColumnsDataIo(1));
+
+ /**
+ * Constructor.
+ *
+ * @param ver Page format version.
+ */
+ protected IndexColumnsDataIo(int ver) {
+ super(IndexPageTypes.T_VALUE_VERSION_DATA_IO, ver);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void writeRowData(long pageAddr, int dataOff, int payloadSize,
IndexColumns row, boolean newRow) {
+ assertPageType(pageAddr);
+
+ putInt(pageAddr, dataOff + IndexColumns.SIZE_OFFSET, row.valueSize());
+
+ putByteBuffer(pageAddr, dataOff + IndexColumns.VALUE_OFFSET,
row.valueBuffer());
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void writeFragmentData(IndexColumns row, ByteBuffer pageBuf, int
rowOff, int payloadSize) {
+ assertPageType(pageBuf);
+
+ if (rowOff == 0) {
+ // First fragment.
+ assert row.headerSize() <= payloadSize;
+
+ pageBuf.putInt(row.valueSize());
+
+ putValueBufferIntoPage(pageBuf, row.valueBuffer(), 0, payloadSize
- IndexColumns.VALUE_OFFSET);
+ } else {
+ // Not a first fragment.
+ assert rowOff >= row.headerSize();
+
+ putValueBufferIntoPage(pageBuf, row.valueBuffer(), rowOff -
IndexColumns.VALUE_OFFSET, payloadSize);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void printPage(long addr, int pageSize, IgniteStringBuilder sb) {
+ sb.app("IndexColumnsDataIo [\n");
+ printPageLayout(addr, pageSize, sb);
+ sb.app("\n]");
+ }
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexRow.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexRow.java
new file mode 100644
index 0000000000..320a4033e1
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexRow.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index.hash;
+
+import org.apache.ignite.internal.storage.RowId;
+import org.apache.ignite.internal.storage.index.IndexRow;
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.IndexColumns;
+import org.apache.ignite.internal.util.HashUtils;
+
+/**
+ * {@link IndexRow} implementation used in the {@link HashIndexTree}.
+ */
+public class HashIndexRow extends HashIndexRowKey {
+ /** Row id. */
+ private final RowId rowId;
+
+ /**
+ * Constructor.
+ *
+ * @param indexColumns Index columns.
+ * @param rowId Row id.
+ */
+ public HashIndexRow(IndexColumns indexColumns, RowId rowId) {
+ this(HashUtils.hash32(indexColumns.valueBuffer()), indexColumns,
rowId);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param indexColumnsHash Hash of the index columns.
+ * @param indexColumns Index columns.
+ * @param rowId Row id.
+ */
+ public HashIndexRow(int indexColumnsHash, IndexColumns indexColumns, RowId
rowId) {
+ super(indexColumnsHash, indexColumns);
+
+ this.rowId = rowId;
+ }
+
+ /**
+ * Returns a row id of the row.
+ */
+ public RowId rowId() {
+ return rowId;
+ }
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexRowKey.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexRowKey.java
new file mode 100644
index 0000000000..62e520fd56
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexRowKey.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index.hash;
+
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.IndexColumns;
+
+/**
+ * Key to search for a {@link HashIndexRow} in the {@link HashIndexTree}.
+ */
+public class HashIndexRowKey {
+ private final int indexColumnsHash;
+
+ private final IndexColumns indexColumns;
+
+ /**
+ * Constructor.
+ *
+ * @param indexColumnsHash Hash of the index columns.
+ * @param indexColumns Index columns.
+ */
+ public HashIndexRowKey(int indexColumnsHash, IndexColumns indexColumns) {
+ this.indexColumnsHash = indexColumnsHash;
+
+ this.indexColumns = indexColumns;
+ }
+
+ /**
+ * Returns the hash of the index columns.
+ */
+ public int indexColumnsHash() {
+ return indexColumnsHash;
+ }
+
+ /**
+ * Returns an indexed columns value.
+ */
+ public IndexColumns indexColumns() {
+ return indexColumns;
+ }
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexTree.java
similarity index 51%
copy from
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
copy to
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexTree.java
index e3d55bb0d6..d9ebdc48d2 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/HashIndexTree.java
@@ -15,25 +15,29 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.storage.pagememory.index.meta;
+package org.apache.ignite.internal.storage.pagememory.index.hash;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.ignite.internal.pagememory.PageMemory;
+import org.apache.ignite.internal.pagememory.datapage.DataPageReader;
import org.apache.ignite.internal.pagememory.reuse.ReuseList;
import org.apache.ignite.internal.pagememory.tree.BplusTree;
import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
import org.apache.ignite.internal.pagememory.util.PageLockListener;
-import
org.apache.ignite.internal.storage.pagememory.index.meta.io.IndexMetaInnerIo;
-import org.apache.ignite.internal.storage.pagememory.index.meta.io.IndexMetaIo;
-import
org.apache.ignite.internal.storage.pagememory.index.meta.io.IndexMetaLeafIo;
-import
org.apache.ignite.internal.storage.pagememory.index.meta.io.IndexMetaTreeMetaIo;
+import
org.apache.ignite.internal.storage.pagememory.index.hash.io.HashIndexTreeInnerIo;
+import
org.apache.ignite.internal.storage.pagememory.index.hash.io.HashIndexTreeIo;
+import
org.apache.ignite.internal.storage.pagememory.index.hash.io.HashIndexTreeLeafIo;
+import
org.apache.ignite.internal.storage.pagememory.index.hash.io.HashIndexTreeMetaIo;
import org.apache.ignite.lang.IgniteInternalCheckedException;
import org.jetbrains.annotations.Nullable;
/**
- * Tree for storing index meta-information, such as the root of an index tree.
+ * {@link BplusTree} implementation for storing {@link HashIndexRow}.
*/
-public class IndexMetaTree extends BplusTree<IndexMeta, IndexMeta> {
+public class HashIndexTree extends BplusTree<HashIndexRowKey, HashIndexRow> {
+ /** Data page reader instance to read payload from data pages. */
+ private final DataPageReader dataPageReader;
+
/**
* Constructor.
*
@@ -48,9 +52,9 @@ public class IndexMetaTree extends BplusTree<IndexMeta,
IndexMeta> {
* @param initNew {@code True} if new tree should be created.
* @throws IgniteInternalCheckedException If failed.
*/
- public IndexMetaTree(
+ public HashIndexTree(
int grpId,
- String grpName,
+ @Nullable String grpName,
int partId,
PageMemory pageMem,
PageLockListener lockLsnr,
@@ -59,36 +63,40 @@ public class IndexMetaTree extends BplusTree<IndexMeta,
IndexMeta> {
@Nullable ReuseList reuseList,
boolean initNew
) throws IgniteInternalCheckedException {
- super(
- "IndexMetaTree_" + grpId,
- grpId,
- grpName,
- partId,
- pageMem,
- lockLsnr,
- globalRmvId,
- metaPageId,
- reuseList
- );
+ super("HashIndexTree_" + grpId, grpId, grpName, partId, pageMem,
lockLsnr, globalRmvId, metaPageId, reuseList);
+
+ setIos(HashIndexTreeInnerIo.VERSIONS, HashIndexTreeLeafIo.VERSIONS,
HashIndexTreeMetaIo.VERSIONS);
- setIos(IndexMetaInnerIo.VERSIONS, IndexMetaLeafIo.VERSIONS,
IndexMetaTreeMetaIo.VERSIONS);
+ dataPageReader = new DataPageReader(pageMem, grpId,
statisticsHolder());
initTree(initNew);
}
- /** {@inheritDoc} */
+ /**
+ * Returns a partition id.
+ */
+ public int partitionId() {
+ return partId;
+ }
+
+ /**
+ * Returns a data page reader instance to read payload from data pages.
+ */
+ public DataPageReader dataPageReader() {
+ return dataPageReader;
+ }
+
@Override
- protected int compare(BplusIo<IndexMeta> io, long pageAddr, int idx,
IndexMeta row) {
- IndexMetaIo indexMetaIo = (IndexMetaIo) io;
+ protected int compare(BplusIo<HashIndexRowKey> io, long pageAddr, int idx,
HashIndexRowKey row) throws IgniteInternalCheckedException {
+ HashIndexTreeIo hashIndexTreeIo = (HashIndexTreeIo) io;
- return indexMetaIo.compare(pageAddr, idx, row);
+ return hashIndexTreeIo.compare(dataPageReader, partId, pageAddr, idx,
row);
}
- /** {@inheritDoc} */
@Override
- public IndexMeta getRow(BplusIo<IndexMeta> io, long pageAddr, int idx,
Object x) {
- IndexMetaIo indexMetaIo = (IndexMetaIo) io;
+ public HashIndexRow getRow(BplusIo<HashIndexRowKey> io, long pageAddr, int
idx, Object x) throws IgniteInternalCheckedException {
+ HashIndexTreeIo hashIndexTreeIo = (HashIndexTreeIo) io;
- return indexMetaIo.getRow(pageAddr, idx);
+ return hashIndexTreeIo.getRow(dataPageReader, partId, pageAddr, idx);
}
}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/InsertHashIndexRowInvokeClosure.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/InsertHashIndexRowInvokeClosure.java
new file mode 100644
index 0000000000..c6099ead0a
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/InsertHashIndexRowInvokeClosure.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index.hash;
+
+
+import static org.apache.ignite.internal.pagememory.util.PageIdUtils.NULL_LINK;
+
+import org.apache.ignite.internal.pagememory.metric.IoStatisticsHolder;
+import org.apache.ignite.internal.pagememory.tree.IgniteTree.InvokeClosure;
+import org.apache.ignite.internal.pagememory.tree.IgniteTree.OperationType;
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.IndexColumns;
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.IndexColumnsFreeList;
+import org.apache.ignite.lang.IgniteInternalCheckedException;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Insert closure that inserts corresponding {@link IndexColumns} into a
{@link IndexColumnsFreeList} before writing to the
+ * {@link HashIndexTree}.
+ */
+public class InsertHashIndexRowInvokeClosure implements
InvokeClosure<HashIndexRow> {
+ /** Hash index row instance for insertion. */
+ private final HashIndexRow hashIndexRow;
+
+ /** Free list to insert data into in case of necessity. */
+ private final IndexColumnsFreeList freeList;
+
+ /** Statistics holder to track IO operations. */
+ private final IoStatisticsHolder statHolder;
+
+ /** Operation type, either {@link OperationType#PUT} or {@link
OperationType#NOOP} depending on the tree state. */
+ private OperationType operationType = OperationType.PUT;
+
+ /**
+ * Constructor.
+ *
+ * @param hashIndexRow Hash index row instance for insertion.
+ * @param freeList Free list to insert data into in case of necessity.
+ * @param statHolder Statistics holder to track IO operations.
+ */
+ public InsertHashIndexRowInvokeClosure(HashIndexRow hashIndexRow,
IndexColumnsFreeList freeList, IoStatisticsHolder statHolder) {
+ assert hashIndexRow.indexColumns().link() == NULL_LINK;
+
+ this.hashIndexRow = hashIndexRow;
+ this.freeList = freeList;
+ this.statHolder = statHolder;
+ }
+
+ @Override
+ public void call(@Nullable HashIndexRow oldRow) throws
IgniteInternalCheckedException {
+ if (oldRow != null) {
+ operationType = OperationType.NOOP;
+
+ return;
+ }
+
+ freeList.insertDataRow(hashIndexRow.indexColumns(), statHolder);
+ }
+
+ @Override
+ public @Nullable HashIndexRow newRow() {
+ return hashIndexRow;
+ }
+
+ @Override
+ public OperationType operationType() {
+ return operationType;
+ }
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/RemoveHashIndexRowInvokeClosure.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/RemoveHashIndexRowInvokeClosure.java
new file mode 100644
index 0000000000..bdd342bc75
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/RemoveHashIndexRowInvokeClosure.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index.hash;
+
+
+import static org.apache.ignite.internal.pagememory.util.PageIdUtils.NULL_LINK;
+
+import org.apache.ignite.internal.pagememory.metric.IoStatisticsHolder;
+import org.apache.ignite.internal.pagememory.tree.BplusTree;
+import org.apache.ignite.internal.pagememory.tree.IgniteTree.InvokeClosure;
+import org.apache.ignite.internal.pagememory.tree.IgniteTree.OperationType;
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.IndexColumns;
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.IndexColumnsFreeList;
+import org.apache.ignite.lang.IgniteInternalCheckedException;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Insert closure that removes corresponding {@link IndexColumns} from a
{@link IndexColumnsFreeList} after removing it from the
+ * {@link HashIndexTree}.
+ */
+public class RemoveHashIndexRowInvokeClosure implements
InvokeClosure<HashIndexRow> {
+ /** Hash index row instance for removal. */
+ private final HashIndexRow hashIndexRow;
+
+ /** Free list to insert data into in case of necessity. */
+ private final IndexColumnsFreeList freeList;
+
+ /** Statistics holder to track IO operations. */
+ private final IoStatisticsHolder statHolder;
+
+ /** Operation type, either {@link OperationType#REMOVE} or {@link
OperationType#NOOP} if row is missing. */
+ private OperationType operationType = OperationType.REMOVE;
+
+ /**
+ * Constructor.
+ *
+ * @param hashIndexRow Hash index row instance for removal.
+ * @param freeList Free list to insert data into in case of necessity.
+ * @param statHolder Statistics holder to track IO operations.
+ */
+ public RemoveHashIndexRowInvokeClosure(HashIndexRow hashIndexRow,
IndexColumnsFreeList freeList, IoStatisticsHolder statHolder) {
+ assert hashIndexRow.indexColumns().link() == 0L;
+
+ this.hashIndexRow = hashIndexRow;
+ this.freeList = freeList;
+ this.statHolder = statHolder;
+ }
+
+ @Override
+ public void call(@Nullable HashIndexRow oldRow) {
+ if (oldRow == null) {
+ operationType = OperationType.NOOP;
+ } else {
+ hashIndexRow.indexColumns().link(oldRow.indexColumns().link());
+ }
+ }
+
+ @Override
+ public @Nullable HashIndexRow newRow() {
+ return null;
+ }
+
+ @Override
+ public OperationType operationType() {
+ return operationType;
+ }
+
+ /**
+ * Method to call after {@link BplusTree#invoke(Object, Object,
InvokeClosure)} has completed.
+ *
+ * @throws IgniteInternalCheckedException If failed to remove data from
the free list.
+ */
+ public void afterCompletion() throws IgniteInternalCheckedException {
+ IndexColumns indexColumns = hashIndexRow.indexColumns();
+
+ if (indexColumns.link() != NULL_LINK) {
+ assert operationType == OperationType.REMOVE;
+
+ freeList.removeDataRowByLink(indexColumns.link(), statHolder);
+
+ indexColumns.link(NULL_LINK);
+ }
+ }
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeInnerIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeInnerIo.java
new file mode 100644
index 0000000000..ffd3fe93b1
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeInnerIo.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index.hash.io;
+
+import org.apache.ignite.internal.pagememory.io.IoVersions;
+import org.apache.ignite.internal.pagememory.tree.BplusTree;
+import org.apache.ignite.internal.pagememory.tree.io.BplusInnerIo;
+import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
+import org.apache.ignite.internal.storage.pagememory.index.IndexPageTypes;
+import
org.apache.ignite.internal.storage.pagememory.index.hash.HashIndexRowKey;
+import org.apache.ignite.internal.storage.pagememory.index.hash.HashIndexTree;
+import org.apache.ignite.lang.IgniteInternalCheckedException;
+
+/**
+ * {@link BplusInnerIo} implementation for {@link HashIndexTree}.
+ */
+public class HashIndexTreeInnerIo extends BplusInnerIo<HashIndexRowKey>
implements HashIndexTreeIo {
+ /** I/O versions. */
+ public static final IoVersions<HashIndexTreeInnerIo> VERSIONS = new
IoVersions<>(new HashIndexTreeInnerIo(1));
+
+ /**
+ * Constructor.
+ *
+ * @param ver Page format version.
+ */
+ protected HashIndexTreeInnerIo(int ver) {
+ super(IndexPageTypes.T_HASH_INDEX_INNER_IO, ver, true, SIZE_IN_BYTES);
+ }
+
+ @Override
+ public void store(long dstPageAddr, int dstIdx, BplusIo<HashIndexRowKey>
srcIo, long srcPageAddr, int srcIdx) {
+ HashIndexTreeIo.super.store(dstPageAddr, dstIdx, srcIo, srcPageAddr,
srcIdx);
+ }
+
+ @Override
+ public void storeByOffset(long pageAddr, int off, HashIndexRowKey row) {
+ HashIndexTreeIo.super.storeByOffset(pageAddr, off, row);
+ }
+
+ @Override
+ public HashIndexRowKey getLookupRow(BplusTree<HashIndexRowKey, ?> tree,
long pageAddr, int idx) throws IgniteInternalCheckedException {
+ HashIndexTree hashIndexTree = (HashIndexTree) tree;
+
+ return getRow(hashIndexTree.dataPageReader(),
hashIndexTree.partitionId(), pageAddr, idx);
+ }
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeIo.java
new file mode 100644
index 0000000000..395bbb3f05
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeIo.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index.hash.io;
+
+import static org.apache.ignite.internal.pagememory.util.PageUtils.getInt;
+import static org.apache.ignite.internal.pagememory.util.PageUtils.getLong;
+import static org.apache.ignite.internal.pagememory.util.PageUtils.putInt;
+import static org.apache.ignite.internal.pagememory.util.PageUtils.putLong;
+import static
org.apache.ignite.internal.pagememory.util.PartitionlessLinks.PARTITIONLESS_LINK_SIZE_BYTES;
+import static
org.apache.ignite.internal.pagememory.util.PartitionlessLinks.readPartitionlessLink;
+import static
org.apache.ignite.internal.pagememory.util.PartitionlessLinks.writePartitionlessLink;
+
+import java.nio.ByteBuffer;
+import java.util.UUID;
+import org.apache.ignite.internal.pagememory.datapage.DataPageReader;
+import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
+import org.apache.ignite.internal.pagememory.util.PageUtils;
+import org.apache.ignite.internal.storage.RowId;
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.IndexColumns;
+import
org.apache.ignite.internal.storage.pagememory.index.freelist.ReadIndexColumnsValue;
+import org.apache.ignite.internal.storage.pagememory.index.hash.HashIndexRow;
+import
org.apache.ignite.internal.storage.pagememory.index.hash.HashIndexRowKey;
+import org.apache.ignite.internal.storage.pagememory.index.meta.IndexMeta;
+import org.apache.ignite.lang.IgniteInternalCheckedException;
+
+/**
+ * Interface for {@link IndexMeta} B+Tree-related IO.
+ *
+ * <p>Defines a following data layout:
+ * <ul>
+ * <li>Index ID - {@link UUID} (16 bytes);</li>
+ * <li>Index root page ID - long (8 bytes).</li>
+ * </ul>
+ */
+public interface HashIndexTreeIo {
+ /** Offset of the index columns hash (4 bytes). */
+ int INDEX_COLUMNS_HASH_OFFSET = 0;
+
+ /** Offset of the index column link (6 bytes). */
+ int INDEX_COLUMNS_LINK_OFFSET = INDEX_COLUMNS_HASH_OFFSET + Integer.BYTES;
+
+ /** Offset of rowId's most significant bits, 8 bytes. */
+ int ROW_ID_MSB_OFFSET = INDEX_COLUMNS_LINK_OFFSET +
PARTITIONLESS_LINK_SIZE_BYTES;
+
+ /** Offset of rowId's least significant bits, 8 bytes. */
+ int ROW_ID_LSB_OFFSET = ROW_ID_MSB_OFFSET + Long.BYTES;
+
+ /** Payload size in bytes. */
+ int SIZE_IN_BYTES = ROW_ID_LSB_OFFSET + Long.BYTES;
+
+ /**
+ * Returns an offset of the element inside the page.
+ *
+ * @see BplusIo#offset(int)
+ */
+ int offset(int idx);
+
+ /**
+ * Stores a hash index row, copied from another page.
+ *
+ * @see BplusIo#store(long, int, BplusIo, long, int)
+ */
+ default void store(long dstPageAddr, int dstIdx, BplusIo<HashIndexRowKey>
srcIo, long srcPageAddr, int srcIdx) {
+ int dstOffset = offset(dstIdx);
+ int srcOffset = offset(srcIdx);
+
+ PageUtils.copyMemory(srcPageAddr, srcOffset, dstPageAddr, dstOffset,
SIZE_IN_BYTES);
+ }
+
+ /**
+ * Stores a hash index row in the page.
+ *
+ * @see BplusIo#storeByOffset(long, int, Object)
+ */
+ default void storeByOffset(long pageAddr, int off, HashIndexRowKey rowKey)
{
+ assert rowKey instanceof HashIndexRow;
+
+ HashIndexRow hashIndexRow = (HashIndexRow) rowKey;
+
+ putInt(pageAddr, off + INDEX_COLUMNS_HASH_OFFSET,
hashIndexRow.indexColumnsHash());
+
+ writePartitionlessLink(pageAddr + off + INDEX_COLUMNS_LINK_OFFSET,
hashIndexRow.indexColumns().link());
+
+ RowId rowId = hashIndexRow.rowId();
+
+ putLong(pageAddr, off + ROW_ID_MSB_OFFSET,
rowId.mostSignificantBits());
+ putLong(pageAddr, off + ROW_ID_LSB_OFFSET,
rowId.leastSignificantBits());
+ }
+
+ /**
+ * Compare the {@link HashIndexRowKey} from the page with passed {@link
HashIndexRowKey}.
+ *
+ * @param pageAddr Page address.
+ * @param idx Element's index.
+ * @param rowKey Lookup index row key.
+ * @return Comparison result.
+ */
+ default int compare(DataPageReader dataPageReader, int partitionId, long
pageAddr, int idx, HashIndexRowKey rowKey)
+ throws IgniteInternalCheckedException {
+ assert rowKey instanceof HashIndexRow;
+
+ HashIndexRow hashIndexRow = (HashIndexRow) rowKey;
+
+ int off = offset(idx);
+
+ int cmp = Integer.compare(getInt(pageAddr, off +
INDEX_COLUMNS_HASH_OFFSET), hashIndexRow.indexColumnsHash());
+
+ if (cmp != 0) {
+ return cmp;
+ }
+
+ long link = readPartitionlessLink(partitionId, pageAddr, off +
INDEX_COLUMNS_LINK_OFFSET);
+
+ //TODO Add in-place compare in IGNITE-17536
+ ReadIndexColumnsValue indexColumnsTraversal = new
ReadIndexColumnsValue();
+
+ dataPageReader.traverse(link, indexColumnsTraversal, null);
+
+ ByteBuffer indexColumnsBuffer =
ByteBuffer.wrap(indexColumnsTraversal.result());
+
+ cmp =
indexColumnsBuffer.compareTo(hashIndexRow.indexColumns().valueBuffer());
+
+ if (cmp != 0) {
+ return cmp;
+ }
+
+ long rowIdMsb = getLong(pageAddr, off + ROW_ID_MSB_OFFSET);
+
+ cmp = Long.compare(rowIdMsb,
hashIndexRow.rowId().mostSignificantBits());
+
+ if (cmp != 0) {
+ return cmp;
+ }
+
+ long rowIdLsb = getLong(pageAddr, off + ROW_ID_LSB_OFFSET);
+
+ return Long.compare(rowIdLsb,
hashIndexRow.rowId().leastSignificantBits());
+ }
+
+ /**
+ * Reads a hash index row value.
+ *
+ * @param dataPageReader Data page reader instance to read payload from
data pages.
+ * @param partitionId Partition id.
+ * @param pageAddr Page address.
+ * @param idx Element's index.
+ * @return Hash index row.
+ * @throws IgniteInternalCheckedException If failed to read payload from
data pages.
+ */
+ default HashIndexRow getRow(DataPageReader dataPageReader, int
partitionId, long pageAddr, int idx)
+ throws IgniteInternalCheckedException {
+ int off = offset(idx);
+
+ int hash = getInt(pageAddr, off + INDEX_COLUMNS_HASH_OFFSET);
+
+ long link = readPartitionlessLink(partitionId, pageAddr, off +
INDEX_COLUMNS_LINK_OFFSET);
+
+ ReadIndexColumnsValue indexColumnsTraversal = new
ReadIndexColumnsValue();
+
+ dataPageReader.traverse(link, indexColumnsTraversal, null);
+
+ ByteBuffer indexColumnsBuffer =
ByteBuffer.wrap(indexColumnsTraversal.result());
+
+ IndexColumns indexColumns = new IndexColumns(partitionId, link,
indexColumnsBuffer);
+
+ long rowIdMsb = getLong(pageAddr, off + ROW_ID_MSB_OFFSET);
+ long rowIdLsb = getLong(pageAddr, off + ROW_ID_LSB_OFFSET);
+
+ RowId rowId = new RowId(partitionId, rowIdMsb, rowIdLsb);
+
+ return new HashIndexRow(hash, indexColumns, rowId);
+ }
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeLeafIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeLeafIo.java
new file mode 100644
index 0000000000..02affe53ec
--- /dev/null
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeLeafIo.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.storage.pagememory.index.hash.io;
+
+import org.apache.ignite.internal.pagememory.io.IoVersions;
+import org.apache.ignite.internal.pagememory.tree.BplusTree;
+import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
+import org.apache.ignite.internal.pagememory.tree.io.BplusLeafIo;
+import org.apache.ignite.internal.storage.pagememory.index.IndexPageTypes;
+import
org.apache.ignite.internal.storage.pagememory.index.hash.HashIndexRowKey;
+import org.apache.ignite.internal.storage.pagememory.index.hash.HashIndexTree;
+import org.apache.ignite.lang.IgniteInternalCheckedException;
+
+/**
+ * {@link BplusLeafIo} implementation for {@link HashIndexTree}.
+ */
+public class HashIndexTreeLeafIo extends BplusLeafIo<HashIndexRowKey>
implements HashIndexTreeIo {
+ /** I/O versions. */
+ public static final IoVersions<HashIndexTreeLeafIo> VERSIONS = new
IoVersions<>(new HashIndexTreeLeafIo(1));
+
+ /**
+ * Constructor.
+ *
+ * @param ver Page format version.
+ */
+ protected HashIndexTreeLeafIo(int ver) {
+ super(IndexPageTypes.T_HASH_INDEX_LEAF_IO, ver, SIZE_IN_BYTES);
+ }
+
+ @Override
+ public void store(long dstPageAddr, int dstIdx, BplusIo<HashIndexRowKey>
srcIo, long srcPageAddr, int srcIdx) {
+ HashIndexTreeIo.super.store(dstPageAddr, dstIdx, srcIo, srcPageAddr,
srcIdx);
+ }
+
+ @Override
+ public void storeByOffset(long pageAddr, int off, HashIndexRowKey row) {
+ HashIndexTreeIo.super.storeByOffset(pageAddr, off, row);
+ }
+
+ @Override
+ public HashIndexRowKey getLookupRow(BplusTree<HashIndexRowKey, ?> tree,
long pageAddr, int idx) throws IgniteInternalCheckedException {
+ HashIndexTree hashIndexTree = (HashIndexTree) tree;
+
+ return getRow(hashIndexTree.dataPageReader(),
hashIndexTree.partitionId(), pageAddr, idx);
+ }
+}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaTreeMetaIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeMetaIo.java
similarity index 66%
copy from
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaTreeMetaIo.java
copy to
modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeMetaIo.java
index 9e8d229c15..46a7ad0760 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaTreeMetaIo.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/hash/io/HashIndexTreeMetaIo.java
@@ -15,28 +15,26 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.storage.pagememory.index.meta.io;
+package org.apache.ignite.internal.storage.pagememory.index.hash.io;
import org.apache.ignite.internal.pagememory.io.IoVersions;
import org.apache.ignite.internal.pagememory.tree.io.BplusMetaIo;
-import org.apache.ignite.internal.storage.pagememory.index.meta.IndexMetaTree;
+import org.apache.ignite.internal.storage.pagememory.index.IndexPageTypes;
+import org.apache.ignite.internal.storage.pagememory.index.hash.HashIndexTree;
/**
- * IO routines for {@link IndexMetaTree} meta pages.
+ * IO routines for {@link HashIndexTree} meta pages.
*/
-public class IndexMetaTreeMetaIo extends BplusMetaIo {
- /** Page IO type. */
- public static final short T_INDEX_META_TREE_META_IO = 13;
-
+public class HashIndexTreeMetaIo extends BplusMetaIo {
/** I/O versions. */
- public static final IoVersions<IndexMetaTreeMetaIo> VERSIONS = new
IoVersions<>(new IndexMetaTreeMetaIo(1));
+ public static final IoVersions<HashIndexTreeMetaIo> VERSIONS = new
IoVersions<>(new HashIndexTreeMetaIo(1));
/**
* Constructor.
*
* @param ver Page format version.
*/
- protected IndexMetaTreeMetaIo(int ver) {
- super(T_INDEX_META_TREE_META_IO, ver);
+ protected HashIndexTreeMetaIo(int ver) {
+ super(IndexPageTypes.T_HASH_INDEX_META_IO, ver);
}
}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
index e3d55bb0d6..99daf6b7ef 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/IndexMetaTree.java
@@ -31,7 +31,7 @@ import org.apache.ignite.lang.IgniteInternalCheckedException;
import org.jetbrains.annotations.Nullable;
/**
- * Tree for storing index meta-information, such as the root of an index tree.
+ * {@link BplusTree} implementation for storing {@link IndexMeta}.
*/
public class IndexMetaTree extends BplusTree<IndexMeta, IndexMeta> {
/**
@@ -59,24 +59,13 @@ public class IndexMetaTree extends BplusTree<IndexMeta,
IndexMeta> {
@Nullable ReuseList reuseList,
boolean initNew
) throws IgniteInternalCheckedException {
- super(
- "IndexMetaTree_" + grpId,
- grpId,
- grpName,
- partId,
- pageMem,
- lockLsnr,
- globalRmvId,
- metaPageId,
- reuseList
- );
+ super("IndexMetaTree_" + grpId, grpId, grpName, partId, pageMem,
lockLsnr, globalRmvId, metaPageId, reuseList);
setIos(IndexMetaInnerIo.VERSIONS, IndexMetaLeafIo.VERSIONS,
IndexMetaTreeMetaIo.VERSIONS);
initTree(initNew);
}
- /** {@inheritDoc} */
@Override
protected int compare(BplusIo<IndexMeta> io, long pageAddr, int idx,
IndexMeta row) {
IndexMetaIo indexMetaIo = (IndexMetaIo) io;
@@ -84,7 +73,6 @@ public class IndexMetaTree extends BplusTree<IndexMeta,
IndexMeta> {
return indexMetaIo.compare(pageAddr, idx, row);
}
- /** {@inheritDoc} */
@Override
public IndexMeta getRow(BplusIo<IndexMeta> io, long pageAddr, int idx,
Object x) {
IndexMetaIo indexMetaIo = (IndexMetaIo) io;
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaInnerIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaInnerIo.java
index 0dca86a381..18507991c9 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaInnerIo.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaInnerIo.java
@@ -21,6 +21,7 @@ import org.apache.ignite.internal.pagememory.io.IoVersions;
import org.apache.ignite.internal.pagememory.tree.BplusTree;
import org.apache.ignite.internal.pagememory.tree.io.BplusInnerIo;
import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
+import org.apache.ignite.internal.storage.pagememory.index.IndexPageTypes;
import org.apache.ignite.internal.storage.pagememory.index.meta.IndexMeta;
import org.apache.ignite.internal.storage.pagememory.index.meta.IndexMetaTree;
@@ -28,9 +29,6 @@ import
org.apache.ignite.internal.storage.pagememory.index.meta.IndexMetaTree;
* IO routines for {@link IndexMetaTree} inner pages.
*/
public class IndexMetaInnerIo extends BplusInnerIo<IndexMeta> implements
IndexMetaIo {
- /** Page IO type. */
- public static final short T_INDEX_META_INNER_IO = 15;
-
/** I/O versions. */
public static final IoVersions<IndexMetaInnerIo> VERSIONS = new
IoVersions<>(new IndexMetaInnerIo(1));
@@ -40,7 +38,7 @@ public class IndexMetaInnerIo extends BplusInnerIo<IndexMeta>
implements IndexMe
* @param ver Page format version.
*/
private IndexMetaInnerIo(int ver) {
- super(T_INDEX_META_INNER_IO, ver, true, SIZE_IN_BYTES);
+ super(IndexPageTypes.T_INDEX_META_INNER_IO, ver, true, SIZE_IN_BYTES);
}
/** {@inheritDoc} */
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaIo.java
index 92b5996912..61e8e95dd4 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaIo.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaIo.java
@@ -24,7 +24,6 @@ import java.util.UUID;
import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
import org.apache.ignite.internal.pagememory.util.PageUtils;
import org.apache.ignite.internal.storage.pagememory.index.meta.IndexMeta;
-import org.apache.ignite.internal.storage.pagememory.index.meta.IndexMetaTree;
/**
* Interface for {@link IndexMeta} B+Tree-related IO.
@@ -56,7 +55,7 @@ public interface IndexMetaIo {
int offset(int idx);
/**
- * Compare the index meta from the page with passed index meta, thus
defining the order of element in the {@link IndexMetaTree}.
+ * Compare the {@link IndexMeta} from the page with passed {@link
IndexMeta}.
*
* @param pageAddr Page address.
* @param idx Element's index.
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaLeafIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaLeafIo.java
index c5d938d786..5314020808 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaLeafIo.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaLeafIo.java
@@ -21,6 +21,7 @@ import org.apache.ignite.internal.pagememory.io.IoVersions;
import org.apache.ignite.internal.pagememory.tree.BplusTree;
import org.apache.ignite.internal.pagememory.tree.io.BplusIo;
import org.apache.ignite.internal.pagememory.tree.io.BplusLeafIo;
+import org.apache.ignite.internal.storage.pagememory.index.IndexPageTypes;
import org.apache.ignite.internal.storage.pagememory.index.meta.IndexMeta;
import org.apache.ignite.internal.storage.pagememory.index.meta.IndexMetaTree;
@@ -28,9 +29,6 @@ import
org.apache.ignite.internal.storage.pagememory.index.meta.IndexMetaTree;
* IO routines for {@link IndexMetaTree} leaf pages.
*/
public class IndexMetaLeafIo extends BplusLeafIo<IndexMeta> implements
IndexMetaIo {
- /** Page IO type. */
- public static final short T_INDEX_META_LEAF_IO = 14;
-
/** I/O versions. */
public static final IoVersions<IndexMetaLeafIo> VERSIONS = new
IoVersions<>(new IndexMetaLeafIo(1));
@@ -40,7 +38,7 @@ public class IndexMetaLeafIo extends BplusLeafIo<IndexMeta>
implements IndexMeta
* @param ver Page format version.
*/
private IndexMetaLeafIo(int ver) {
- super(T_INDEX_META_LEAF_IO, ver, SIZE_IN_BYTES);
+ super(IndexPageTypes.T_INDEX_META_LEAF_IO, ver, SIZE_IN_BYTES);
}
/** {@inheritDoc} */
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaTreeMetaIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaTreeMetaIo.java
index 9e8d229c15..9b67160131 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaTreeMetaIo.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/index/meta/io/IndexMetaTreeMetaIo.java
@@ -19,15 +19,13 @@ package
org.apache.ignite.internal.storage.pagememory.index.meta.io;
import org.apache.ignite.internal.pagememory.io.IoVersions;
import org.apache.ignite.internal.pagememory.tree.io.BplusMetaIo;
+import org.apache.ignite.internal.storage.pagememory.index.IndexPageTypes;
import org.apache.ignite.internal.storage.pagememory.index.meta.IndexMetaTree;
/**
* IO routines for {@link IndexMetaTree} meta pages.
*/
public class IndexMetaTreeMetaIo extends BplusMetaIo {
- /** Page IO type. */
- public static final short T_INDEX_META_TREE_META_IO = 13;
-
/** I/O versions. */
public static final IoVersions<IndexMetaTreeMetaIo> VERSIONS = new
IoVersions<>(new IndexMetaTreeMetaIo(1));
@@ -37,6 +35,6 @@ public class IndexMetaTreeMetaIo extends BplusMetaIo {
* @param ver Page format version.
*/
protected IndexMetaTreeMetaIo(int ver) {
- super(T_INDEX_META_TREE_META_IO, ver);
+ super(IndexPageTypes.T_INDEX_META_TREE_META_IO, ver);
}
}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/AbstractPageMemoryMvPartitionStorage.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/AbstractPageMemoryMvPartitionStorage.java
index 0261dde770..5c89a17678 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/AbstractPageMemoryMvPartitionStorage.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/AbstractPageMemoryMvPartitionStorage.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.storage.pagememory.mv;
+import static org.apache.ignite.internal.pagememory.util.PageIdUtils.NULL_LINK;
+
import java.nio.ByteBuffer;
import java.util.NoSuchElementException;
import java.util.UUID;
@@ -226,9 +228,9 @@ public abstract class AbstractPageMemoryMvPartitionStorage
implements MvPartitio
VersionChain currentChain = findVersionChain(rowId);
if (currentChain == null) {
- RowVersion newVersion = insertRowVersion(row,
RowVersion.NULL_LINK);
+ RowVersion newVersion = insertRowVersion(row, NULL_LINK);
- VersionChain versionChain = new VersionChain(rowId, txId,
newVersion.link(), RowVersion.NULL_LINK);
+ VersionChain versionChain = new VersionChain(rowId, txId,
newVersion.link(), NULL_LINK);
updateVersionChain(versionChain);
@@ -277,7 +279,7 @@ public abstract class AbstractPageMemoryMvPartitionStorage
implements MvPartitio
// Next can be safely replaced with any value (like 0), because
this field is only used when there
// is some uncommitted value, but when we add an uncommitted
value, we 'fix' such placeholder value
// (like 0) by replacing it with a valid value.
- VersionChain versionChainReplacement = new VersionChain(rowId,
null, latestVersion.nextLink(), RowVersion.NULL_LINK);
+ VersionChain versionChainReplacement = new VersionChain(rowId,
null, latestVersion.nextLink(), NULL_LINK);
updateVersionChain(versionChainReplacement);
} else {
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/ReadRowVersion.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/ReadRowVersion.java
index 3441318ef6..20f5988449 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/ReadRowVersion.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/ReadRowVersion.java
@@ -17,7 +17,7 @@
package org.apache.ignite.internal.storage.pagememory.mv;
-import static
org.apache.ignite.internal.storage.pagememory.mv.PartitionlessLinks.readPartitionlessLink;
+import static
org.apache.ignite.internal.pagememory.util.PartitionlessLinks.readPartitionlessLink;
import java.nio.ByteBuffer;
import java.util.function.Predicate;
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RowVersion.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RowVersion.java
index 2b13ab7ccd..60425a0402 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RowVersion.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RowVersion.java
@@ -18,6 +18,7 @@
package org.apache.ignite.internal.storage.pagememory.mv;
import static org.apache.ignite.hlc.HybridTimestamp.HYBRID_TIMESTAMP_SIZE;
+import static org.apache.ignite.internal.pagememory.util.PageIdUtils.NULL_LINK;
import java.nio.ByteBuffer;
import java.util.Objects;
@@ -25,6 +26,7 @@ import org.apache.ignite.hlc.HybridTimestamp;
import org.apache.ignite.internal.pagememory.Storable;
import org.apache.ignite.internal.pagememory.io.AbstractDataPageIo;
import org.apache.ignite.internal.pagememory.io.IoVersions;
+import org.apache.ignite.internal.pagememory.util.PartitionlessLinks;
import org.apache.ignite.internal.storage.pagememory.mv.io.RowVersionDataIo;
import org.apache.ignite.internal.tostring.IgniteToStringExclude;
import org.apache.ignite.internal.tostring.S;
@@ -34,9 +36,6 @@ import org.jetbrains.annotations.Nullable;
* Represents row version inside row version chain.
*/
public final class RowVersion implements Storable {
- /** Represents an absent partitionless link. */
- public static final long NULL_LINK = 0;
-
private static final int NEXT_LINK_STORE_SIZE_BYTES =
PartitionlessLinks.PARTITIONLESS_LINK_SIZE_BYTES;
private static final int VALUE_SIZE_STORE_SIZE_BYTES = Integer.BYTES;
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RowVersionFreeList.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RowVersionFreeList.java
index a3a20abb06..c853b4da95 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RowVersionFreeList.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/RowVersionFreeList.java
@@ -39,8 +39,6 @@ import org.jetbrains.annotations.Nullable;
public class RowVersionFreeList extends AbstractFreeList<RowVersion> {
private static final IgniteLogger LOG =
Loggers.forClass(RowVersionFreeList.class);
- private final PageEvictionTracker evictionTracker;
-
private final IoStatisticsHolder statHolder;
private final UpdateTimestampHandler updateTimestampHandler = new
UpdateTimestampHandler();
@@ -87,7 +85,6 @@ public class RowVersionFreeList extends
AbstractFreeList<RowVersion> {
evictionTracker
);
- this.evictionTracker = evictionTracker;
this.statHolder = statHolder;
}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/ScanVersionChainByTimestamp.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/ScanVersionChainByTimestamp.java
index 569c2086aa..7d5fd1616e 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/ScanVersionChainByTimestamp.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/ScanVersionChainByTimestamp.java
@@ -17,7 +17,8 @@
package org.apache.ignite.internal.storage.pagememory.mv;
-import static
org.apache.ignite.internal.storage.pagememory.mv.PartitionlessLinks.readPartitionlessLink;
+import static org.apache.ignite.internal.pagememory.util.PageIdUtils.NULL_LINK;
+import static
org.apache.ignite.internal.pagememory.util.PartitionlessLinks.readPartitionlessLink;
import org.apache.ignite.hlc.HybridTimestamp;
import org.apache.ignite.internal.pagememory.datapage.PageMemoryTraversal;
@@ -80,7 +81,7 @@ class ScanVersionChainByTimestamp implements
PageMemoryTraversal<HybridTimestamp
private long advanceToNextVersion(long pageAddr, DataPagePayload payload) {
long nextLink = readPartitionlessLink(partitionId, pageAddr,
payload.offset() + RowVersion.NEXT_LINK_OFFSET);
- if (nextLink == RowVersion.NULL_LINK) {
+ if (nextLink == NULL_LINK) {
return STOP_TRAVERSAL;
}
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/VersionChain.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/VersionChain.java
index 022c1cf94a..c650bed4dc 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/VersionChain.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/VersionChain.java
@@ -17,6 +17,8 @@
package org.apache.ignite.internal.storage.pagememory.mv;
+import static org.apache.ignite.internal.pagememory.util.PageIdUtils.NULL_LINK;
+
import java.util.UUID;
import org.apache.ignite.internal.storage.RowId;
import org.apache.ignite.internal.tostring.S;
@@ -91,7 +93,7 @@ public class VersionChain extends VersionChainKey {
* Returns {@code true} if this version chain has at least one committed
version.
*/
public boolean hasCommittedVersions() {
- return newestCommittedLink() != RowVersion.NULL_LINK;
+ return newestCommittedLink() != NULL_LINK;
}
/** {@inheritDoc} */
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/io/RowVersionDataIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/io/RowVersionDataIo.java
index c7d8846112..23c6b17988 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/io/RowVersionDataIo.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/io/RowVersionDataIo.java
@@ -20,14 +20,14 @@ package org.apache.ignite.internal.storage.pagememory.mv.io;
import static
org.apache.ignite.internal.pagememory.util.PageUtils.putByteBuffer;
import static org.apache.ignite.internal.pagememory.util.PageUtils.putInt;
import static org.apache.ignite.internal.pagememory.util.PageUtils.putShort;
-import static
org.apache.ignite.internal.storage.pagememory.mv.PartitionlessLinks.writePartitionlessLink;
+import static
org.apache.ignite.internal.pagememory.util.PartitionlessLinks.writePartitionlessLink;
import java.nio.ByteBuffer;
import org.apache.ignite.hlc.HybridTimestamp;
import org.apache.ignite.internal.pagememory.io.AbstractDataPageIo;
import org.apache.ignite.internal.pagememory.io.IoVersions;
+import org.apache.ignite.internal.pagememory.util.PartitionlessLinks;
import org.apache.ignite.internal.storage.pagememory.mv.HybridTimestamps;
-import org.apache.ignite.internal.storage.pagememory.mv.PartitionlessLinks;
import org.apache.ignite.internal.storage.pagememory.mv.RowVersion;
import org.apache.ignite.lang.IgniteStringBuilder;
import org.jetbrains.annotations.Nullable;
@@ -73,44 +73,29 @@ public class RowVersionDataIo extends
AbstractDataPageIo<RowVersion> {
/** {@inheritDoc} */
@Override
- protected void writeFragmentData(RowVersion row, ByteBuffer buf, int
rowOff, int payloadSize) {
- assertPageType(buf);
+ protected void writeFragmentData(RowVersion row, ByteBuffer pageBuf, int
rowOff, int payloadSize) {
+ assertPageType(pageBuf);
if (rowOff == 0) {
// first fragment
assert row.headerSize() <= payloadSize : "Header must entirely fit
in the first fragment, but header size is "
+ row.headerSize() + " and payload size is " + payloadSize;
- HybridTimestamps.writeTimestampToBuffer(buf, row.timestamp());
+ HybridTimestamps.writeTimestampToBuffer(pageBuf, row.timestamp());
- PartitionlessLinks.writeToBuffer(buf, row.nextLink());
+ PartitionlessLinks.writeToBuffer(pageBuf, row.nextLink());
- buf.putInt(row.valueSize());
+ pageBuf.putInt(row.valueSize());
- int valueBytesToWrite = payloadSize - row.headerSize();
- putValueFragmentToBuffer(row, buf, 0, valueBytesToWrite);
+ putValueBufferIntoPage(pageBuf, row.value(), 0, payloadSize -
row.headerSize());
} else {
// non-first fragment
- assert rowOff > row.headerSize();
+ assert rowOff >= row.headerSize();
- putValueFragmentToBuffer(row, buf, rowOff - row.headerSize(),
payloadSize);
+ putValueBufferIntoPage(pageBuf, row.value(), rowOff -
row.headerSize(), payloadSize);
}
}
- private void putValueFragmentToBuffer(RowVersion row, ByteBuffer buf, int
readBufferPosition, int valueBytesToWrite) {
- ByteBuffer valueBuffer = row.value();
-
- int oldLimit = valueBuffer.limit();
- int oldPosition = valueBuffer.position();
-
- valueBuffer.position(readBufferPosition);
- valueBuffer.limit(valueBuffer.position() + valueBytesToWrite);
- buf.put(valueBuffer);
-
- valueBuffer.position(oldPosition);
- valueBuffer.limit(oldLimit);
- }
-
/**
* Updates timestamp leaving the rest untouched.
*
diff --git
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/io/VersionChainIo.java
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/io/VersionChainIo.java
index 63461d1257..7e5fcbe202 100644
---
a/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/io/VersionChainIo.java
+++
b/modules/storage-page-memory/src/main/java/org/apache/ignite/internal/storage/pagememory/mv/io/VersionChainIo.java
@@ -19,9 +19,9 @@ package org.apache.ignite.internal.storage.pagememory.mv.io;
import static org.apache.ignite.internal.pagememory.util.PageUtils.getLong;
import static org.apache.ignite.internal.pagememory.util.PageUtils.putLong;
-import static
org.apache.ignite.internal.storage.pagememory.mv.PartitionlessLinks.PARTITIONLESS_LINK_SIZE_BYTES;
-import static
org.apache.ignite.internal.storage.pagememory.mv.PartitionlessLinks.readPartitionlessLink;
-import static
org.apache.ignite.internal.storage.pagememory.mv.PartitionlessLinks.writePartitionlessLink;
+import static
org.apache.ignite.internal.pagememory.util.PartitionlessLinks.PARTITIONLESS_LINK_SIZE_BYTES;
+import static
org.apache.ignite.internal.pagememory.util.PartitionlessLinks.readPartitionlessLink;
+import static
org.apache.ignite.internal.pagememory.util.PartitionlessLinks.writePartitionlessLink;
import static
org.apache.ignite.internal.storage.pagememory.mv.VersionChain.NULL_UUID_COMPONENT;
import java.util.UUID;