You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ib...@apache.org on 2022/09/22 15:02:29 UTC

[ignite-3] branch main updated: IGNITE-17740 Fix prefix comparison in RocksDB Sorted Index (#1115)

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 624ae8b449 IGNITE-17740 Fix prefix comparison in RocksDB Sorted Index (#1115)
624ae8b449 is described below

commit 624ae8b449eae300bc3b30779e78592b7923ace5
Author: Alexander Polovtcev <al...@gmail.com>
AuthorDate: Thu Sep 22 18:02:24 2022 +0300

    IGNITE-17740 Fix prefix comparison in RocksDB Sorted Index (#1115)
---
 .../storage/index/BinaryTupleComparator.java       |  4 +++
 .../index/AbstractSortedIndexStorageTest.java      | 36 +++++++++++-----------
 .../index/RocksDbBinaryTupleComparator.java        | 12 ++++++--
 3 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/index/BinaryTupleComparator.java b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/index/BinaryTupleComparator.java
index 4fdc6eb4ed..baf8aabaa9 100644
--- a/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/index/BinaryTupleComparator.java
+++ b/modules/storage-api/src/main/java/org/apache/ignite/internal/storage/index/BinaryTupleComparator.java
@@ -32,6 +32,10 @@ import org.apache.ignite.internal.storage.index.SortedIndexDescriptor.ColumnDesc
 
 /**
  * Comparator implementation for comparing {@link BinaryTuple}s on a per-column basis.
+ *
+ * <p>This comparator is used to compare BinaryTuples as well as {@link BinaryTuplePrefix}es. When comparing a tuple with a prefix,
+ * the following logic is applied: if all N columns of the prefix match the first N columns of the tuple, they are considered equal.
+ * Otherwise comparison result is determined by the first non-matching column.
  */
 public class BinaryTupleComparator implements Comparator<ByteBuffer> {
     private final SortedIndexDescriptor descriptor;
diff --git a/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/index/AbstractSortedIndexStorageTest.java b/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/index/AbstractSortedIndexStorageTest.java
index d3eeec9657..605b77619d 100644
--- a/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/index/AbstractSortedIndexStorageTest.java
+++ b/modules/storage-api/src/test/java/org/apache/ignite/internal/storage/index/AbstractSortedIndexStorageTest.java
@@ -437,73 +437,73 @@ public abstract class AbstractSortedIndexStorageTest {
         SortedIndexStorage index1 = createIndexStorage(index1Definition);
         SortedIndexStorage index2 = createIndexStorage(index2Definition);
 
-        Object[] val9010 = { "10", 90 };
-        Object[] val8010 = { "10", 80 };
-        Object[] val9020 = { "20", 90 };
-        Object[] val8020 = { "20", 80 };
+        Object[] val1090 = { "10", 90 };
+        Object[] val1080 = { "10", 80 };
+        Object[] val2090 = { "20", 90 };
+        Object[] val2080 = { "20", 80 };
 
         for (SortedIndexStorage index : Arrays.asList(index1, index2)) {
             var serializer = new BinaryTupleRowSerializer(index.indexDescriptor());
 
-            put(index, serializer.serializeRow(val9010, new RowId(0)));
-            put(index, serializer.serializeRow(val8010, new RowId(0)));
-            put(index, serializer.serializeRow(val9020, new RowId(0)));
-            put(index, serializer.serializeRow(val8020, new RowId(0)));
+            put(index, serializer.serializeRow(val1090, new RowId(0)));
+            put(index, serializer.serializeRow(val1080, new RowId(0)));
+            put(index, serializer.serializeRow(val2090, new RowId(0)));
+            put(index, serializer.serializeRow(val2080, new RowId(0)));
         }
 
         // Test without bounds.
         assertThat(
                 scan(index1, null, null, 0),
-                contains(val8010, val9010, val8020, val9020)
+                contains(val1080, val1090, val2080, val2090)
         );
 
         assertThat(
                 scan(index2, null, null, 0),
-                contains(val9010, val8010, val9020, val8020)
+                contains(val1090, val1080, val2090, val2080)
         );
 
         // Lower bound exclusive.
         assertThat(
                 scan(index1, prefix(index1, "10"), null, GREATER),
-                contains(val8020, val9020)
+                contains(val2080, val2090)
         );
 
         assertThat(
                 scan(index2, prefix(index2, "10"), null, GREATER),
-                contains(val9020, val8020)
+                contains(val2090, val2080)
         );
 
         // Lower bound inclusive.
         assertThat(
                 scan(index1, prefix(index1, "10"), null, GREATER_OR_EQUAL),
-                contains(val8010, val9010, val8020, val9020)
+                contains(val1080, val1090, val2080, val2090)
         );
 
         assertThat(
                 scan(index2, prefix(index2, "10"), null, GREATER_OR_EQUAL),
-                contains(val9010, val8010, val9020, val8020)
+                contains(val1090, val1080, val2090, val2080)
         );
 
         // Upper bound exclusive.
         assertThat(
                 scan(index1, null, prefix(index1, "20"), LESS),
-                contains(val8010, val9010)
+                contains(val1080, val1090)
         );
 
         assertThat(
                 scan(index2, null, prefix(index2, "20"), LESS),
-                contains(val9010, val8010)
+                contains(val1090, val1080)
         );
 
         // Upper bound inclusive.
         assertThat(
                 scan(index1, null, prefix(index1, "20"), LESS_OR_EQUAL),
-                contains(val8010, val9010, val8020, val9020)
+                contains(val1080, val1090, val2080, val2090)
         );
 
         assertThat(
                 scan(index2, null, prefix(index2, "20"), LESS_OR_EQUAL),
-                contains(val9010, val8010, val9020, val8020)
+                contains(val1090, val1080, val2090, val2080)
         );
     }
 
diff --git a/modules/storage-rocksdb/src/main/java/org/apache/ignite/internal/storage/rocksdb/index/RocksDbBinaryTupleComparator.java b/modules/storage-rocksdb/src/main/java/org/apache/ignite/internal/storage/rocksdb/index/RocksDbBinaryTupleComparator.java
index 36a65b6f84..f2cb91bee6 100644
--- a/modules/storage-rocksdb/src/main/java/org/apache/ignite/internal/storage/rocksdb/index/RocksDbBinaryTupleComparator.java
+++ b/modules/storage-rocksdb/src/main/java/org/apache/ignite/internal/storage/rocksdb/index/RocksDbBinaryTupleComparator.java
@@ -69,12 +69,18 @@ public class RocksDbBinaryTupleComparator extends AbstractComparator {
 
         int compareTuples = comparator.compare(firstBinaryTupleBuffer, secondBinaryTupleBuffer);
 
-        // Binary Tuple Prefixes don't have row IDs, so they can't be compared.
-        if (compareTuples != 0 || isPrefix(firstBinaryTupleBuffer) || isPrefix(secondBinaryTupleBuffer)) {
+        if (compareTuples != 0) {
             return compareTuples;
         }
 
-        return compareRowIds(a, b);
+        // Binary Tuple Prefixes don't have row IDs, so they can't be compared further.
+        if (isPrefix(firstBinaryTupleBuffer)) {
+            return -1;
+        } else if (isPrefix(secondBinaryTupleBuffer)) {
+            return 1;
+        } else {
+            return compareRowIds(a, b);
+        }
     }
 
     private static int compareRowIds(ByteBuffer a, ByteBuffer b) {