You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by am...@apache.org on 2021/05/21 13:47:31 UTC

[ignite-3] branch ignite-14759 created (now c3905d2)

This is an automated email from the ASF dual-hosted git repository.

amashenkov pushed a change to branch ignite-14759
in repository https://gitbox.apache.org/repos/asf/ignite-3.git.


      at c3905d2  Fix wrong offset calculation.

This branch includes the following new commits:

     new fd3171a  Add tests.
     new c3905d2  Fix wrong offset calculation.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[ignite-3] 01/02: Add tests.

Posted by am...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

amashenkov pushed a commit to branch ignite-14759
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit fd3171aa70e5ebec1c24483373c4240ea2b6ce85
Author: Andrew Mashenkov <an...@gmail.com>
AuthorDate: Fri May 21 15:25:32 2021 +0300

    Add tests.
---
 .../table/IndexColumnConfigurationSchema.java      |   4 +-
 .../runner/app/DynamicTableCreationTest.java       | 105 ++++++++++++++-----
 .../internal/runner/app/TableCreationTest.java     |  48 +++++++--
 .../ignite/internal/schema/SchemaManager.java      |  16 +--
 .../ignite/internal/schema/SchemaRegistry.java     |   6 +-
 .../org/apache/ignite/internal/schema/RowTest.java | 113 ++++++++++++++++-----
 6 files changed, 219 insertions(+), 73 deletions(-)

diff --git a/modules/api/src/main/java/org/apache/ignite/configuration/schemas/table/IndexColumnConfigurationSchema.java b/modules/api/src/main/java/org/apache/ignite/configuration/schemas/table/IndexColumnConfigurationSchema.java
index e915040..3cf584c 100644
--- a/modules/api/src/main/java/org/apache/ignite/configuration/schemas/table/IndexColumnConfigurationSchema.java
+++ b/modules/api/src/main/java/org/apache/ignite/configuration/schemas/table/IndexColumnConfigurationSchema.java
@@ -30,6 +30,6 @@ public class IndexColumnConfigurationSchema {
     String name;
 
     /** Ascending flag. */
-    @Value
-    boolean asc;
+    @Value(hasDefault = true)
+    boolean asc = true;
 }
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/DynamicTableCreationTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/DynamicTableCreationTest.java
index 13b8217..1cd05b6 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/DynamicTableCreationTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/DynamicTableCreationTest.java
@@ -22,6 +22,7 @@ import java.util.List;
 import java.util.UUID;
 import org.apache.ignite.app.Ignite;
 import org.apache.ignite.app.IgnitionManager;
+import org.apache.ignite.table.KeyValueBinaryView;
 import org.apache.ignite.table.Table;
 import org.apache.ignite.table.Tuple;
 import org.junit.jupiter.api.Disabled;
@@ -77,37 +78,53 @@ class DynamicTableCreationTest {
      */
     @Test
     void testDynamicSimpleTableCreation() {
-        List<Ignite> clusterNodex = new ArrayList<>();
+        List<Ignite> clusterNodes = new ArrayList<>();
 
         for (String nodeBootstrapCfg : nodesBootstrapCfg)
-            clusterNodex.add(IgnitionManager.start(nodeBootstrapCfg));
+            clusterNodes.add(IgnitionManager.start(nodeBootstrapCfg));
 
-        assertEquals(3, clusterNodex.size());
+        assertEquals(3, clusterNodes.size());
 
         // Create table on node 0.
-        clusterNodex.get(0).tables().createTable("tbl1", tbl -> tbl
+        clusterNodes.get(0).tables().createTable("tbl1", tbl -> tbl
+            .changeName("tbl1")
             .changeReplicas(1)
             .changePartitions(10)
             .changeColumns(cols -> cols
-                .create("key", c -> c.changeType(t -> t.changeType("INT64")))
-                .create("val", c -> c.changeType(t -> t.changeType("INT64")))
+                .create("key", c -> c.changeName("key").changeNullable(false).changeType(t -> t.changeType("INT64")))
+                .create("val", c -> c.changeName("val").changeNullable(true).changeType(t -> t.changeType("INT64")))
             )
             .changeIndices(idxs -> idxs
                 .create("PK", idx -> idx
+                    .changeName("PK")
                     .changeType("PRIMARY")
+                    .changeColNames(new String[] {"key"})
                     .changeColumns(c -> c
-                        .create("key", t -> {
-                        }))
+                        .create("key", t -> t.changeName("key")))
                     .changeAffinityColumns(new String[] {"key"}))
             ));
 
         // Put data on node 1.
-        Table tbl1 = clusterNodex.get(1).tables().table("tbl1");
-        tbl1.insert(tbl1.tupleBuilder().set("key", 1L).set("val", 111L).build());
+        Table tbl1 = clusterNodes.get(1).tables().table("tbl1");
+        KeyValueBinaryView kvView1 = tbl1.kvView();
+
+        tbl1.insert(tbl1.tupleBuilder().set("key", 1L).set("val", 111).build());
+        kvView1.put(tbl1.tupleBuilder().set("key", 2L).build(), tbl1.tupleBuilder().set("val", 222).build());
 
         // Get data on node 2.
-        Table tbl2 = clusterNodex.get(2).tables().table("tbl1");
-        assertEquals(111L, tbl2.get(tbl2.tupleBuilder().set("key", 1L).build()));
+        Table tbl2 = clusterNodes.get(2).tables().table("tbl1");
+        KeyValueBinaryView kvView2 = tbl2.kvView();
+
+        final Tuple keyTuple1 = tbl2.tupleBuilder().set("key", 1L).build();
+        final Tuple keyTuple2 = kvView2.tupleBuilder().set("key", 2L).build();
+
+        assertEquals(111, (Integer)kvView2.get(keyTuple1).value("key"));
+        assertEquals(222, (Integer)kvView2.get(keyTuple2).value("key"));
+
+        assertEquals(111, (Integer)tbl2.get(keyTuple1).value("val"));
+        assertEquals(111, (Integer)kvView2.get(keyTuple1).value("val"));
+        assertEquals(222, (Integer)tbl2.get(keyTuple2).value("val"));
+        assertEquals(222, (Integer)kvView2.get(keyTuple2).value("val"));
     }
 
     /**
@@ -124,39 +141,73 @@ class DynamicTableCreationTest {
 
         // Create table on node 0.
         clusterNodes.get(0).tables().createTable("tbl1", tbl -> tbl
+            .changeName("tbl1")
             .changeReplicas(1)
             .changePartitions(10)
             .changeColumns(cols -> cols
-                .create("key", c -> c.changeType(t -> t.changeType("UUID")))
-                .create("affKey", c -> c.changeType(t -> t.changeType("INT64")))
-                .create("valStr", c -> c.changeType(t -> t.changeType("STRING")))
-                .create("valInt", c -> c.changeType(t -> t.changeType("INT32")))
-                .create("valNullable", c -> c.changeType(t -> t.changeType("INT8")).changeNullable(true))
+                .create("key", c -> c.changeName("key").changeNullable(false).changeType(t -> t.changeType("UUID")))
+                .create("affKey", c -> c.changeName("affKey").changeNullable(false).changeType(t -> t.changeType("INT64")))
+                .create("valStr", c -> c.changeName("valStr").changeNullable(true).changeType(t -> t.changeType("STRING")))
+                .create("valInt", c -> c.changeName("valInt").changeNullable(true).changeType(t -> t.changeType("INT32")))
+                .create("valNull", c -> c.changeName("valNull").changeNullable(true).changeType(t -> t.changeType("INT16")).changeNullable(true))
             )
             .changeIndices(idxs -> idxs
                 .create("PK", idx -> idx
+                    .changeName("PK")
                     .changeType("PRIMARY")
+                    .changeColNames(new String[] {"key", "affKey"})
                     .changeColumns(c -> c
-                        .create("key", t -> {
-                        })
-                        .create("affKey", t -> {
-                        }))
+                        .create("key", t -> t.changeName("key").changeAsc(true))
+                        .create("affKey", t -> t.changeName("affKey").changeAsc(false)))
                     .changeAffinityColumns(new String[] {"affKey"}))
             ));
 
         final UUID uuid = UUID.randomUUID();
+        final UUID uuid2 = UUID.randomUUID();
 
         // Put data on node 1.
         Table tbl1 = clusterNodes.get(1).tables().table("tbl1");
+        KeyValueBinaryView kvView1 = tbl1.kvView();
+
         tbl1.insert(tbl1.tupleBuilder().set("key", uuid).set("affKey", 42L)
-            .set("valStr", "String value").set("valInt", 73L).set("valNullable", null).build());
+            .set("valStr", "String value").set("valInt", 73).set("valNull", null).build());
+
+        kvView1.put(kvView1.tupleBuilder().set("key", uuid2).set("affKey", 4242L).build(),
+            kvView1.tupleBuilder().set("valStr", "String value 2").set("valInt", 7373).set("valNull", null).build());
 
         // Get data on node 2.
         Table tbl2 = clusterNodes.get(2).tables().table("tbl1");
-        final Tuple val = tbl2.get(tbl1.tupleBuilder().set("key", uuid).set("affKey", 42L).build());
-
-        assertEquals("String value", val.value("valStr"));
-        assertEquals(73L, (Long)val.value("valInt"));
-        assertNull(val.value("valNullable"));
+        KeyValueBinaryView kvView2 = tbl2.kvView();
+
+        final Tuple keyTuple1 = tbl2.tupleBuilder().set("key", uuid).set("affKey", 42L).build();
+        final Tuple keyTuple2 = kvView2.tupleBuilder().set("key", uuid2).set("affKey", 4242L).build();
+
+        // KV view must NOT return key columns in value.
+        assertNull(kvView2.get(keyTuple1).value("key"));
+        assertNull(kvView2.get(keyTuple1).value("affKey"));
+        assertNull(kvView2.get(keyTuple2).value("key"));
+        assertNull(kvView2.get(keyTuple2).value("affKey"));
+
+        // Record binary view MUST return key columns in value.
+        assertEquals(uuid, tbl2.get(keyTuple1).value("key"));
+        assertEquals(42L, (Long)tbl2.get(keyTuple1).value("affKey"));
+        assertEquals(uuid2, tbl2.get(keyTuple2).value("key"));
+        assertEquals(4242L, (Long)tbl2.get(keyTuple2).value("affKey"));
+
+        assertEquals("String value", tbl2.get(keyTuple1).value("valStr"));
+        assertEquals(73, (Integer)tbl2.get(keyTuple1).value("valInt"));
+        assertNull(tbl2.get(keyTuple1).value("valNull"));
+
+        assertEquals("String value 2", tbl2.get(keyTuple2).value("valStr"));
+        assertEquals(7373, (Integer)tbl2.get(keyTuple2).value("valInt"));
+        assertNull(tbl2.get(keyTuple2).value("valNull"));
+
+        assertEquals("String value", kvView2.get(keyTuple1).value("valStr"));
+        assertEquals(73, (Integer)kvView2.get(keyTuple1).value("valInt"));
+        assertNull(kvView2.get(keyTuple1).value("valNull"));
+
+        assertEquals("String value 2", kvView2.get(keyTuple2).value("valStr"));
+        assertEquals(7373, (Integer)kvView2.get(keyTuple2).value("valInt"));
+        assertNull(kvView2.get(keyTuple2).value("valNull"));
     }
 }
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/TableCreationTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/TableCreationTest.java
index 035caad..e9834ae 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/TableCreationTest.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/TableCreationTest.java
@@ -22,6 +22,7 @@ import java.util.List;
 import java.util.UUID;
 import org.apache.ignite.app.Ignite;
 import org.apache.ignite.app.IgnitionManager;
+import org.apache.ignite.table.KeyValueBinaryView;
 import org.apache.ignite.table.Table;
 import org.apache.ignite.table.Tuple;
 import org.junit.jupiter.api.Assertions;
@@ -162,29 +163,58 @@ class TableCreationTest {
 
         clusterNodes.forEach(Assertions::assertNotNull);
 
-        { /* Table 1.*/
+        { /* Table 1. */
             Table tbl1 = clusterNodes.get(1).tables().table("tbl1");
-            tbl1.insert(tbl1.tupleBuilder().set("key", 1L).set("val", 111L).build());
+            KeyValueBinaryView kvView1 = tbl1.kvView();
+
+            tbl1.insert(tbl1.tupleBuilder().set("key", 1L).set("val", 111).build());
+            kvView1.put(tbl1.tupleBuilder().set("key", 2L).build(), tbl1.tupleBuilder().set("val", 222).build());
 
             Table tbl2 = clusterNodes.get(2).tables().table("tbl1");
-            assertEquals(111L, tbl2.get(tbl2.tupleBuilder().set("key", 1L).build()));
+            KeyValueBinaryView kvView2 = tbl2.kvView();
+
+            final Tuple keyTuple1 = tbl2.tupleBuilder().set("key", 1L).build();
+            final Tuple keyTuple2 = kvView2.tupleBuilder().set("key", 2L).build();
+
+            assertEquals(111, (Integer)tbl2.get(keyTuple1).value("val"));
+            assertEquals(111, (Integer)kvView1.get(keyTuple1).value("val"));
+            assertEquals(222, (Integer)tbl2.get(keyTuple2).value("val"));
+            assertEquals(222, (Integer)kvView1.get(keyTuple2).value("val"));
         }
 
         { /* Table 2. */
             final UUID uuid = UUID.randomUUID();
+            final UUID uuid2 = UUID.randomUUID();
 
             // Put data on node 1.
             Table tbl1 = clusterNodes.get(1).tables().table("tbl1");
+            KeyValueBinaryView kvView1 = tbl1.kvView();
+
             tbl1.insert(tbl1.tupleBuilder().set("key", uuid).set("affKey", 42L)
-                .set("valStr", "String value").set("valInt", 73L).set("valNullable", null).build());
+                .set("valStr", "String value").set("valInt", 73).set("valNullable", null).build());
+
+            kvView1.put(kvView1.tupleBuilder().set("key", uuid2).set("affKey", 4242L).build(),
+                kvView1.tupleBuilder().set("valStr", "String value 2").set("valInt", 7373).set("valNullable", null).build());
 
             // Get data on node 2.
             Table tbl2 = clusterNodes.get(2).tables().table("tbl1");
-            final Tuple val = tbl2.get(tbl1.tupleBuilder().set("key", uuid).set("affKey", 42L).build());
-
-            assertEquals("String value", val.value("valStr"));
-            assertEquals(73L, (Long)val.value("valInt"));
-            assertNull(val.value("valNullable"));
+            KeyValueBinaryView kvView2 = tbl2.kvView();
+
+            final Tuple keyTuple1 = tbl2.tupleBuilder().set("key", uuid).set("affKey", 42L).build();
+            final Tuple keyTuple2 = kvView2.tupleBuilder().set("key", uuid2).set("affKey", 4242L).build();
+
+            assertEquals("String value", tbl2.get(keyTuple1).value("valStr"));
+            assertEquals("String value", kvView2.get(keyTuple1).value("valStr"));
+            assertEquals("String value 2", tbl2.get(keyTuple2).value("valStr"));
+            assertEquals("String value 2", kvView2.get(keyTuple2).value("valStr"));
+            assertEquals(73, (Integer)tbl2.get(keyTuple1).value("valInt"));
+            assertEquals(73, (Integer)kvView2.get(keyTuple1).value("valInt"));
+            assertEquals(7373, (Integer)tbl2.get(keyTuple2).value("valInt"));
+            assertEquals(7373, (Integer)kvView2.get(keyTuple2).value("valInt"));
+            assertNull(tbl2.get(keyTuple1).value("valNullable"));
+            assertNull(kvView2.get(keyTuple1).value("valNullable"));
+            assertNull(tbl2.get(keyTuple2).value("valNullable"));
+            assertNull(kvView2.get(keyTuple2).value("valNullable"));
         }
     }
 }
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaManager.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaManager.java
index 58361d3..90b6fc5 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaManager.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaManager.java
@@ -110,7 +110,7 @@ public class SchemaManager extends Producer<SchemaEvent, SchemaEventParameters>
         metaStorageMgr.registerWatchByPrefix(new ByteArray(INTERNAL_PREFIX), new WatchListener() {
             @Override public boolean onUpdate(@NotNull WatchEvent events) {
                 for (EntryEvent evt : events.entryEvents()) {
-                    String keyTail = evt.newEntry().key().toString().substring(INTERNAL_PREFIX.length() - 1);
+                    String keyTail = evt.newEntry().key().toString().substring(INTERNAL_PREFIX.length());
 
                     int verPos = keyTail.indexOf(INTERNAL_VER_SUFFIX);
 
@@ -254,13 +254,13 @@ public class SchemaManager extends Producer<SchemaEvent, SchemaEventParameters>
      */
     private NativeType createType(ColumnTypeView type) {
         switch (type.type().toLowerCase()) {
-            case "byte":
+            case "int8":
                 return NativeTypes.BYTE;
-            case "short":
+            case "int16":
                 return NativeTypes.SHORT;
-            case "int":
+            case "int32":
                 return NativeTypes.INTEGER;
-            case "long":
+            case "int64":
                 return NativeTypes.LONG;
             case "float":
                 return NativeTypes.FLOAT;
@@ -269,11 +269,13 @@ public class SchemaManager extends Producer<SchemaEvent, SchemaEventParameters>
             case "uuid":
                 return NativeTypes.UUID;
             case "bitmask":
+                assert type.length() > 0;
+
                 return NativeTypes.bitmaskOf(type.length());
             case "string":
-                return NativeTypes.stringOf(type.length());
+                return type.length() == 0 ? NativeTypes.STRING : NativeTypes.stringOf(type.length());
             case "bytes":
-                return NativeTypes.blobOf(type.length());
+                return type.length() == 0 ? NativeTypes.BYTES : NativeTypes.blobOf(type.length());
 
             default:
                 throw new IllegalStateException("Unsupported column type: " + type.type());
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaRegistry.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaRegistry.java
index 8da7278..777adf1 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaRegistry.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/SchemaRegistry.java
@@ -17,6 +17,9 @@
 
 package org.apache.ignite.internal.schema;
 
+import org.apache.ignite.internal.schema.registry.SchemaRegistryException;
+import org.jetbrains.annotations.NotNull;
+
 /**
  * Table schema registry interface.
  */
@@ -29,6 +32,7 @@ public interface SchemaRegistry {
     /**
      * @param ver Schema version.
      * @return Schema of given version.
+     * @throws SchemaRegistryException If schema was not found.
      */
-    SchemaDescriptor schema(int ver);
+    @NotNull SchemaDescriptor schema(int ver) throws SchemaRegistryException;
 }
diff --git a/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowTest.java b/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowTest.java
index cdb1d31..08ef37f 100644
--- a/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowTest.java
+++ b/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowTest.java
@@ -40,11 +40,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
  * Tests row assembling and reading.
  */
 public class RowTest {
-    /** */
+    /** Random. */
     private Random rnd;
 
     /**
-     *
+     * Initialization.
      */
     @BeforeEach
     public void initRandom() {
@@ -56,10 +56,42 @@ public class RowTest {
     }
 
     /**
-     *
+     * Check row serialization for schema with nullable fix-sized columns only.
      */
     @Test
-    public void fixedSizes() {
+    public void nullableFixSizedColumns() {
+        Column[] keyCols = new Column[] {
+            new Column("keyByteCol", BYTE, false),
+            new Column("keyShortCol", SHORT, false),
+            new Column("keyIntCol", INTEGER, false),
+            new Column("keyLongCol", LONG, false),
+            new Column("keyFloatCol", FLOAT, false),
+            new Column("keyDoubleCol", DOUBLE, false),
+            new Column("keyUuidCol", UUID, false),
+            new Column("keyBitmask1Col", NativeTypes.bitmaskOf(4), false),
+            new Column("keyBitmask2Col", NativeTypes.bitmaskOf(22), false)
+        };
+
+        Column[] valCols = new Column[] {
+            new Column("valByteCol", BYTE, false),
+            new Column("valShortCol", SHORT, false),
+            new Column("valIntCol", INTEGER, false),
+            new Column("valLongCol", LONG, false),
+            new Column("valFloatCol", FLOAT, false),
+            new Column("valDoubleCol", DOUBLE, false),
+            new Column("valUuidCol", UUID, false),
+            new Column("valBitmask1Col", NativeTypes.bitmaskOf(4), false),
+            new Column("valBitmask2Col", NativeTypes.bitmaskOf(22), false)
+        };
+
+        checkSchema(keyCols, valCols);
+    }
+
+    /**
+     * Check row serialization for schema with non-nullable fix-sized columns only.
+     */
+    @Test
+    public void fixSizedColumns() {
         Column[] keyCols = new Column[] {
             new Column("keyByteCol", BYTE, true),
             new Column("keyShortCol", SHORT, true),
@@ -88,17 +120,17 @@ public class RowTest {
     }
 
     /**
-     *
+     * Check row serialization for schema with various columns.
      */
     @Test
-    public void variableSizes() {
+    public void mixedColumns() {
         Column[] keyCols = new Column[] {
-            new Column("keyByteCol", BYTE, true),
-            new Column("keyShortCol", SHORT, true),
-            new Column("keyIntCol", INTEGER, true),
-            new Column("keyLongCol", LONG, true),
-            new Column("keyBytesCol", BYTES, true),
-            new Column("keyStringCol", STRING, true),
+            new Column("keyByteCol", BYTE, false),
+            new Column("keyShortCol", SHORT, false),
+            new Column("keyIntCol", INTEGER, false),
+            new Column("keyLongCol", LONG, false),
+            new Column("keyBytesCol", BYTES, false),
+            new Column("keyStringCol", STRING, false),
         };
 
         Column[] valCols = new Column[] {
@@ -114,10 +146,28 @@ public class RowTest {
     }
 
     /**
-     *
+     * Check row serialization for schema with non-nullable varlen columns only.
+     */
+    @Test
+    public void varlenColumns() {
+        Column[] keyCols = new Column[] {
+            new Column("keyBytesCol", BYTES, false),
+            new Column("keyStringCol", STRING, false),
+        };
+
+        Column[] valCols = new Column[] {
+            new Column("valBytesCol", BYTES, false),
+            new Column("valStringCol", STRING, false),
+        };
+
+        checkSchema(keyCols, valCols);
+    }
+
+    /**
+     * Check row serialization for schema with nullable varlen columns only.
      */
     @Test
-    public void mixedSizes() {
+    public void nullableVarlenColumns() {
         Column[] keyCols = new Column[] {
             new Column("keyBytesCol", BYTES, true),
             new Column("keyStringCol", STRING, true),
@@ -132,7 +182,10 @@ public class RowTest {
     }
 
     /**
+     * Checks schema is independent from prodived column order.
      *
+     * @param keyCols Key columns.
+     * @param valCols Value columns.
      */
     private void checkSchema(Column[] keyCols, Column[] valCols) {
         checkSchemaShuffled(keyCols, valCols);
@@ -144,38 +197,38 @@ public class RowTest {
     }
 
     /**
+     * Checks schema for given columns.
      *
+     * @param keyCols Key columns.
+     * @param valCols Value columns.
      */
     private void checkSchemaShuffled(Column[] keyCols, Column[] valCols) {
         SchemaDescriptor sch = new SchemaDescriptor(java.util.UUID.randomUUID(), 1, keyCols, valCols);
 
-        Object[] checkArr = sequence(sch);
+        Object[] checkArr = generateRowValues(sch);
 
         checkValues(sch, checkArr);
 
-        while (checkArr[0] != null) {
-            int idx = 0;
+        for (int idx = 0; idx < checkArr.length; idx++) {
+            if (!sch.column(idx).nullable())
+                continue;
 
             Object prev = checkArr[idx];
             checkArr[idx] = null;
 
             checkValues(sch, checkArr);
 
-            while (idx < checkArr.length - 1 && checkArr[idx + 1] != null) {
-                checkArr[idx] = prev;
-                prev = checkArr[idx + 1];
-                checkArr[idx + 1] = null;
-                idx++;
-
-                checkValues(sch, checkArr);
-            }
+            checkArr[idx] = prev;
         }
     }
 
     /**
+     * Generate row values for given row schema.
      *
+     * @param schema Row schema.
+     * @return Row values.
      */
-    private Object[] sequence(SchemaDescriptor schema) {
+    private Object[] generateRowValues(SchemaDescriptor schema) {
         Object[] res = new Object[schema.length()];
 
         for (int i = 0; i < res.length; i++) {
@@ -188,14 +241,20 @@ public class RowTest {
     }
 
     /**
+     * Generates random value of a given type.
      *
+     * @param type Value type.
+     * @return Random value of requested type.
      */
     private Object generateRandomValue(NativeType type) {
         return TestUtils.generateRandomValue(rnd, type);
     }
 
     /**
+     * Validates row values after serialization-deserialization.
      *
+     * @param schema Row schema.
+     * @param vals Row values.
      */
     private void checkValues(SchemaDescriptor schema, Object... vals) {
         assertEquals(schema.keyColumns().length() + schema.valueColumns().length(), vals.length);
@@ -312,7 +371,7 @@ public class RowTest {
     }
 
     /**
-     *
+     * Suffle columns.
      */
     private void shuffle(Column[] cols) {
         Collections.shuffle(Arrays.asList(cols));

[ignite-3] 02/02: Fix wrong offset calculation.

Posted by am...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

amashenkov pushed a commit to branch ignite-14759
in repository https://gitbox.apache.org/repos/asf/ignite-3.git

commit c3905d2468dc034844f5557bdd1159cfa285c6ae
Author: Andrew Mashenkov <an...@gmail.com>
AuthorDate: Fri May 21 16:43:52 2021 +0300

    Fix wrong offset calculation.
---
 .../org/apache/ignite/internal/schema/Row.java     | 42 +++++++++++++---------
 .../org/apache/ignite/internal/schema/RowTest.java |  4 +--
 2 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/Row.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/Row.java
index 9d967d3..bed6afc 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/Row.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/Row.java
@@ -492,33 +492,43 @@ public class Row implements BinaryRow {
      * @return Encoded offset (from the row start) of the requested fixlen column.
      */
     int fixlenColumnOffset(Columns cols, int baseOff, int idx, boolean hasVarTbl, boolean hasNullMap) {
-        int off = 0;
+        int colOff = 0;
 
         int payloadOff = baseOff + CHUNK_LEN_FIELD_SIZE;
 
-        if (hasNullMap) {
-            payloadOff += cols.nullMapSize();
-
-            int nullMapOff = nullMapOffset(baseOff);
-
-            int nullMapIdx = idx / 8;
-
-            // Fold offset based on the whole map bytes in the schema
-            for (int i = 0; i < nullMapIdx; i++)
-                off += cols.foldFixedLength(i, readByte(nullMapOff + i));
+        // Calculate fixlen column offset.
+        {
+            int colByteIdx = idx / 8;
 
             // Set bits starting from posInByte, inclusive, up to either the end of the byte or the last column index, inclusive
             int startBit = idx % 8;
-            int endBit = nullMapIdx == cols.nullMapSize() - 1 ? ((cols.numberOfFixsizeColumns() - 1) % 8) : 7;
+            int endBit = colByteIdx == (cols.length() + 7) / 8 - 1 ? ((cols.numberOfFixsizeColumns() - 1) % 8) : 7;
             int mask = (0xFF >> (7 - endBit)) & (0xFF << startBit);
 
-            off += cols.foldFixedLength(nullMapIdx, readByte(nullMapOff + nullMapIdx) | mask);
+            if (hasNullMap) {
+                payloadOff += cols.nullMapSize();
+
+                // Fold offset based on the whole map bytes in the schema
+                for (int i = 0; i < colByteIdx; i++)
+                    colOff += cols.foldFixedLength(i, readByte(nullMapOffset(baseOff) + i));
+
+                colOff += cols.foldFixedLength(colByteIdx, readByte(nullMapOffset(baseOff) + colByteIdx) | mask);
+            }
+            else {
+                for (int i = 0; i < colByteIdx; i++)
+                    colOff += cols.foldFixedLength(i, 0);
+
+                colOff += cols.foldFixedLength(colByteIdx,  mask);
+            }
         }
 
-        if (hasVarTbl)
-            payloadOff += varlenItemOffset(readShort(payloadOff));
+        if (hasVarTbl) {
+            short verlenItems = readShort(payloadOff);
+
+            payloadOff += varlenItemOffset(verlenItems);
+        }
 
-        return payloadOff + off;
+        return payloadOff + colOff;
     }
 
     /**
diff --git a/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowTest.java b/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowTest.java
index 08ef37f..659dd5f 100644
--- a/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowTest.java
+++ b/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowTest.java
@@ -251,7 +251,7 @@ public class RowTest {
     }
 
     /**
-     * Validates row values after serialization-deserialization.
+     * Validates row values after serialization-then-deserialization.
      *
      * @param schema Row schema.
      * @param vals Row values.
@@ -371,7 +371,7 @@ public class RowTest {
     }
 
     /**
-     * Suffle columns.
+     * Shuffle columns.
      */
     private void shuffle(Column[] cols) {
         Collections.shuffle(Arrays.asList(cols));