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/04/22 00:04:38 UTC

[ignite-3] branch ignite-13670 updated: Omit writing null map if all column are non-nullable.

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

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


The following commit(s) were added to refs/heads/ignite-13670 by this push:
     new 1f72d75  Omit writing null map if all column are non-nullable.
1f72d75 is described below

commit 1f72d75e418f6c61c2c2c4dff5b67610e9c37632
Author: Andrew Mashenkov <an...@gmail.com>
AuthorDate: Thu Apr 22 03:04:29 2021 +0300

    Omit writing null map if all column are non-nullable.
---
 .../org/apache/ignite/internal/schema/Columns.java |  14 ++-
 .../org/apache/ignite/internal/schema/Row.java     | 117 +++++++++++----------
 .../ignite/internal/schema/RowAssembler.java       |   7 +-
 .../apache/ignite/internal/schema/ColumnsTest.java |  14 ++-
 .../ignite/internal/schema/RowAssemblerTest.java   |  66 ++++++------
 5 files changed, 123 insertions(+), 95 deletions(-)

diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/Columns.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/Columns.java
index 28a7f9c..10e3965 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/Columns.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/Columns.java
@@ -99,7 +99,7 @@ public class Columns {
 
         firstVarlenColIdx = findFirstVarlenColumn();
 
-        nullMapSize = (cols.length + 7) / 8;
+        nullMapSize = hasNullableColumn() ? (cols.length + 7) / 8 : 0;
 
         buildFoldingTable();
     }
@@ -207,6 +207,18 @@ public class Columns {
     }
 
     /**
+     * @return {@code True} if there is one or more nullable columns, {@code false} otherwise.
+     */
+    private boolean hasNullableColumn() {
+        for (int i = 0; i < cols.length; i++) {
+            if (cols[i].nullable())
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
      *
      */
     private void buildFoldingTable() {
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 f562ded..70ea05e 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
@@ -331,7 +331,10 @@ public class Row implements BinaryRow {
     protected long findColumn(int colIdx, NativeTypeSpec type) throws InvalidTypeException {
         // Get base offset (key start or value start) for the given column.
         boolean keyCol = schema.isKeyColumn(colIdx);
-        Columns cols = keyCol ? schema.keyColumns() : schema.valueColumns();
+
+        final short flags = readShort(FLAGS_FIELD_OFFSET);
+
+        assert keyCol || (flags & RowFlags.NO_VALUE_FLAG) == 0;
 
         int off = KEY_CHUNK_OFFSET;
 
@@ -343,22 +346,23 @@ public class Row implements BinaryRow {
             colIdx -= schema.keyColumns().length();
         }
 
-        Column col = cols.column(colIdx);
+        Columns cols = keyCol ? schema.keyColumns() : schema.valueColumns();
 
-        if (col.type().spec() != type)
+        if (cols.column(colIdx).type().spec() != type)
             throw new InvalidTypeException("Invalid column type requested [requested=" + type +
-                ", column=" + col + ']');
+                ", column=" + cols.column(colIdx) + ']');
 
-        if (isNull(off, colIdx))
-            return -1;
+        boolean hasVarTable = ((keyCol ? RowFlags.OMIT_KEY_VARTBL_FLAG : RowFlags.OMIT_VAL_VARTBL_FLAG) & flags) == 0;
+        boolean hasNullMap = ((keyCol ? RowFlags.OMIT_KEY_NULL_MAP_FLAG : RowFlags.OMIT_VAL_NULL_MAP_FLAG) & flags) == 0;
 
-        short flags = readShort(FLAGS_FIELD_OFFSET);
+        if (hasNullMap && isNull(off, colIdx))
+            return -1;
 
-        boolean noVarTable = ((keyCol ? RowFlags.OMIT_KEY_VARTBL_FLAG : RowFlags.OMIT_VAL_VARTBL_FLAG) & flags) != 0;
+        assert hasVarTable || type.fixedLength();
 
         return type.fixedLength() ?
-            fixlenColumnOffset(cols, off, colIdx, noVarTable) :
-            varlenColumnOffsetAndLength(cols, off, colIdx);
+            fixlenColumnOffset(cols, off, colIdx, hasVarTable, hasNullMap) :
+            varlenColumnOffsetAndLength(cols, off, colIdx, hasNullMap);
     }
 
     /**
@@ -421,40 +425,47 @@ public class Row implements BinaryRow {
      * @param cols Columns chunk.
      * @param baseOff Chunk base offset.
      * @param idx Column index in the chunk.
+     * @param hasNullMap Has null map flag.
      * @return Encoded offset (from the row start) and length of the column with the given index.
      */
-    private long varlenColumnOffsetAndLength(Columns cols, int baseOff, int idx) {
-        int nullMapOff = nullMapOffset(baseOff);
-
-        int nullStartByte = cols.firstVarlengthColumn() / 8;
-        int startBitInByte = cols.firstVarlengthColumn() % 8;
+    private long varlenColumnOffsetAndLength(Columns cols, int baseOff, int idx, boolean hasNullMap) {
+        int vartableOff = baseOff + CHUNK_LEN_FIELD_SIZE;
 
-        int nullEndByte = idx / 8;
-        int endBitInByte = idx % 8;
         int numNullsBefore = 0;
 
-        for (int i = nullStartByte; i <= nullEndByte; i++) {
-            byte nullmapByte = readByte(nullMapOff + i);
+        if (hasNullMap) {
+            vartableOff += cols.nullMapSize();
+
+            int nullMapOff = nullMapOffset(baseOff);
+
+            int nullStartByte = cols.firstVarlengthColumn() / 8;
+            int startBitInByte = cols.firstVarlengthColumn() % 8;
+
+            int nullEndByte = idx / 8;
+            int endBitInByte = idx % 8;
+
+            for (int i = nullStartByte; i <= nullEndByte; i++) {
+                byte nullmapByte = readByte(nullMapOff + i);
 
-            if (i == nullStartByte)
-                // We need to clear startBitInByte least significant bits
-                nullmapByte &= (0xFF << startBitInByte);
+                if (i == nullStartByte)
+                    // We need to clear startBitInByte least significant bits
+                    nullmapByte &= (0xFF << startBitInByte);
 
-            if (i == nullEndByte)
-                // We need to clear 8-endBitInByte most significant bits
-                nullmapByte &= (0xFF >> (8 - endBitInByte));
+                if (i == nullEndByte)
+                    // We need to clear 8-endBitInByte most significant bits
+                    nullmapByte &= (0xFF >> (8 - endBitInByte));
 
-            numNullsBefore += Columns.numberOfNullColumns(nullmapByte);
+                numNullsBefore += Columns.numberOfNullColumns(nullmapByte);
+            }
         }
 
         idx -= cols.numberOfFixsizeColumns() + numNullsBefore;
-        int vartableSize = readShort(vartableOffset(baseOff, cols));
+        int vartableSize = readShort(vartableOff);
 
-        int vartableOff = vartableOffset(baseOff, cols);
         // Offset of idx-th column is from base offset.
         int resOff = readShort(vartableOff + varlenItemOffset(idx));
 
-        long len = idx == vartableSize - 1 ?
+        long len = (idx == vartableSize - 1) ?
             // totalLength - columnStartOffset
             readInteger(baseOff) - resOff :
             // nextColumnStartOffset - columnStartOffset
@@ -470,31 +481,38 @@ public class Row implements BinaryRow {
      * @param cols Columns chunk.
      * @param baseOff Chunk base offset.
      * @param idx Column index in the chunk.
-     * @param noVarlen Varlen table is ommited.
+     * @param hasVarTbl Has varlen table flag.
+     * @param hasNullMap Has null map flag.
      * @return Encoded offset (from the row start) of the requested fixlen column.
      */
-    int fixlenColumnOffset(Columns cols, int baseOff, int idx, boolean noVarlen) {
-        int nullMapOff = nullMapOffset(baseOff);
-
+    int fixlenColumnOffset(Columns cols, int baseOff, int idx, boolean hasVarTbl, boolean hasNullMap) {
         int off = 0;
-        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));
+        int payloadOff = baseOff + CHUNK_LEN_FIELD_SIZE;
+
+        if (hasNullMap) {
+            payloadOff += cols.nullMapSize();
 
-        // 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 mask = (0xFF >> (7 - endBit)) & (0xFF << startBit);
+            int nullMapOff = nullMapOffset(baseOff);
 
-        off += cols.foldFixedLength(nullMapIdx, readByte(nullMapOff + nullMapIdx) | mask);
+            int nullMapIdx = idx / 8;
 
-        int vartableOffset = vartableOffset(baseOff, cols);
+            // 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));
+
+            // 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 mask = (0xFF >> (7 - endBit)) & (0xFF << startBit);
+
+            off += cols.foldFixedLength(nullMapIdx, readByte(nullMapOff + nullMapIdx) | mask);
+        }
 
-        int vartableLen = noVarlen ? 0 : varlenItemOffset(readShort(vartableOffset));
+        if (hasVarTbl)
+            payloadOff += varlenItemOffset(readShort(payloadOff));
 
-        return vartableOffset + vartableLen + off;
+        return payloadOff + off;
     }
 
     /**
@@ -505,15 +523,6 @@ public class Row implements BinaryRow {
         return baseOff + CHUNK_LEN_FIELD_SIZE;
     }
 
-    /**
-     * @param baseOff Chunk base offset.
-     * @param cols Columns.
-     * @return Offset of the varlen table from the row start for the chunk with the given base.
-     */
-    private int vartableOffset(int baseOff, Columns cols) {
-        return baseOff + CHUNK_LEN_FIELD_SIZE + cols.nullMapSize();
-    }
-
     /** {@inheritDoc} */
     @Override public int schemaVersion() {
         return row.schemaVersion();
diff --git a/modules/schema/src/main/java/org/apache/ignite/internal/schema/RowAssembler.java b/modules/schema/src/main/java/org/apache/ignite/internal/schema/RowAssembler.java
index a62715f..9168e63 100644
--- a/modules/schema/src/main/java/org/apache/ignite/internal/schema/RowAssembler.java
+++ b/modules/schema/src/main/java/org/apache/ignite/internal/schema/RowAssembler.java
@@ -172,8 +172,8 @@ public class RowAssembler {
 
         initOffsets(BinaryRow.KEY_CHUNK_OFFSET, nonNullVarlenKeyCols);
 
-//        if (nullMapSize == 0)
-//            flags |= (baseOff == KEY_CHUNK_OFFSET ? RowFlags.NO_KEY_NULL_MAP : RowFlags.NO_VALUE_NULL_MAP);
+        if (curCols.nullMapSize() == 0)
+            flags |= RowFlags.OMIT_KEY_NULL_MAP_FLAG;
 
         buf = new ExpandableByteBuf(size);
 
@@ -468,6 +468,9 @@ public class RowAssembler {
 
             initOffsets(baseOff + keyLen, nonNullVarlenValCols);
 
+            if (curCols.nullMapSize() == 0)
+                flags |= RowFlags.OMIT_VAL_NULL_MAP_FLAG;
+
             if (nonNullVarlenValCols == 0)
                 flags |= RowFlags.OMIT_VAL_VARTBL_FLAG;
             else
diff --git a/modules/schema/src/test/java/org/apache/ignite/internal/schema/ColumnsTest.java b/modules/schema/src/test/java/org/apache/ignite/internal/schema/ColumnsTest.java
index 1823c63..90ed675 100644
--- a/modules/schema/src/test/java/org/apache/ignite/internal/schema/ColumnsTest.java
+++ b/modules/schema/src/test/java/org/apache/ignite/internal/schema/ColumnsTest.java
@@ -45,7 +45,7 @@ public class ColumnsTest {
         for (int c = 0; c < cols.length(); c++)
             assertTrue(cols.isFixedSize(c));
 
-        assertEquals(1, cols.nullMapSize());
+        assertEquals(0, cols.nullMapSize());
         assertEquals(3, cols.numberOfFixsizeColumns());
     }
 
@@ -67,7 +67,7 @@ public class ColumnsTest {
         for (int c = 0; c < cols.length(); c++)
             assertFalse(cols.isFixedSize(c));
 
-        assertEquals(1, cols.nullMapSize());
+        assertEquals(0, cols.nullMapSize());
         assertEquals(0, cols.numberOfFixsizeColumns());
     }
 
@@ -94,7 +94,7 @@ public class ColumnsTest {
                 assertFalse(cols.isFixedSize(c));
         }
 
-        assertEquals(1, cols.nullMapSize());
+        assertEquals(0, cols.nullMapSize());
         assertEquals(3, cols.numberOfFixsizeColumns());
     }
 
@@ -435,8 +435,12 @@ public class ColumnsTest {
     private static Column[] columns(int size) {
         Column[] ret = new Column[size];
 
-        for (int i = 0; i < ret.length; i++)
-            ret[i] = new Column("column-" + i, NativeType.STRING, true);
+        for (int i = 0; i < ret.length; i++) {
+            if (i % 3 == 0)
+                ret[i] = new Column("column-" + i, NativeType.LONG, true);
+            else
+                ret[i] = new Column("column-" + i, NativeType.STRING, true);
+        }
 
         return ret;
     }
diff --git a/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowAssemblerTest.java b/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowAssemblerTest.java
index 3781330..b2c56d5 100644
--- a/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowAssemblerTest.java
+++ b/modules/schema/src/test/java/org/apache/ignite/internal/schema/RowAssemblerTest.java
@@ -49,7 +49,7 @@ public class RowAssemblerTest {
             asm.appendInt(33);
             asm.appendInt(-71);
 
-            assertRowBytesEquals(new byte[] {42, 0, 24, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 0, -71, -1, -1, -1}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 26, 0, 0, 0, 0, 0, 8, 0, 0, 0, 33, 0, 0, 0, 9, 0, 0, 0, 0, -71, -1, -1, -1}, asm.build());
         }
 
         { // Null value.
@@ -58,7 +58,7 @@ public class RowAssemblerTest {
             asm.appendInt(-33);
             asm.appendNull();
 
-            assertRowBytesEquals(new byte[] {42, 0, 24, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, -33, -1, -1, -1, 5, 0, 0, 0, 1}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 26, 0, 0, 0, 0, 0, 8, 0, 0, 0, -33, -1, -1, -1, 5, 0, 0, 0, 1}, asm.build());
         }
 
         { // No value.
@@ -66,7 +66,7 @@ public class RowAssemblerTest {
 
             asm.appendInt(-33);
 
-            assertRowBytesEquals(new byte[] {42, 0, 25, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, -33, -1, -1, -1}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 27, 0, 0, 0, 0, 0, 8, 0, 0, 0, -33, -1, -1, -1}, asm.build());
         }
     }
 
@@ -83,7 +83,7 @@ public class RowAssemblerTest {
             asm.appendShort((short)33);
             asm.appendShort((short)71L);
 
-            assertRowBytesEquals(new byte[] {42, 0, 24, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 33, 0, 7, 0, 0, 0, 0, 71, 0}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 30, 0, 0, 0, 0, 0, 6, 0, 0, 0, 33, 0, 6, 0, 0, 0, 71, 0}, asm.build());
         }
 
         { // No value.
@@ -91,7 +91,7 @@ public class RowAssemblerTest {
 
             asm.appendShort((short)-33);
 
-            assertRowBytesEquals(new byte[] {42, 0, 25, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, -33, -1}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 31, 0, 0, 0, 0, 0, 6, 0, 0, 0, -33, -1}, asm.build());
         }
     }
 
@@ -108,7 +108,7 @@ public class RowAssemblerTest {
             asm.appendShort((short)-33);
             asm.appendString("val");
 
-            assertRowBytesEquals(new byte[] {42, 0, 8, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, -33, -1, 12, 0, 0, 0, 0, 1, 0, 9, 0, 118, 97, 108}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 10, 0, 0, 0, 0, 0, 6, 0, 0, 0, -33, -1, 12, 0, 0, 0, 0, 1, 0, 9, 0, 118, 97, 108}, asm.build());
         }
 
         { // Null value.
@@ -117,7 +117,7 @@ public class RowAssemblerTest {
             asm.appendShort((short)33);
             asm.appendNull();
 
-            assertRowBytesEquals(new byte[] {42, 0, 24, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 33, 0, 5, 0, 0, 0, 1}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 26, 0, 0, 0, 0, 0, 6, 0, 0, 0, 33, 0, 5, 0, 0, 0, 1}, asm.build());
         }
 
         { // No value.
@@ -125,7 +125,7 @@ public class RowAssemblerTest {
 
             asm.appendShort((short)33);
 
-            assertRowBytesEquals(new byte[] {42, 0, 25, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 33, 0}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 27, 0, 0, 0, 0, 0, 6, 0, 0, 0, 33, 0}, asm.build());
         }
     }
 
@@ -142,7 +142,7 @@ public class RowAssemblerTest {
             asm.appendShort((short)-33);
             asm.appendString("val");
 
-            assertRowBytesEquals(new byte[] {42, 0, 8, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, -33, -1, 12, 0, 0, 0, 0, 1, 0, 9, 0, 118, 97, 108}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 14, 0, 0, 0, 0, 0, 6, 0, 0, 0, -33, -1, 11, 0, 0, 0, 1, 0, 8, 0, 118, 97, 108}, asm.build());
         }
 
         { // No value.
@@ -150,7 +150,7 @@ public class RowAssemblerTest {
 
             asm.appendShort((short)33);
 
-            assertRowBytesEquals(new byte[] {42, 0, 25, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 33, 0}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 31, 0, 0, 0, 0, 0, 6, 0, 0, 0, 33, 0}, asm.build());
         }
     }
 
@@ -167,7 +167,7 @@ public class RowAssemblerTest {
             asm.appendShort((short)-33);
             asm.appendByte((byte)71);
 
-            assertRowBytesEquals(new byte[] {42, 0, 24, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, -33, -1, 6, 0, 0, 0, 0, 71}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 28, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, -33, -1, 5, 0, 0, 0, 71}, asm.build());
         }
 
         { // Null key.
@@ -176,7 +176,7 @@ public class RowAssemblerTest {
             asm.appendNull();
             asm.appendByte((byte)-71);
 
-            assertRowBytesEquals(new byte[] {42, 0, 24, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 6, 0, 0, 0, 0, -71}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 28, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 5, 0, 0, 0, -71}, asm.build());
         }
 
         { // No value.
@@ -184,7 +184,7 @@ public class RowAssemblerTest {
 
             asm.appendShort((short)33);
 
-            assertRowBytesEquals(new byte[] {42, 0, 25, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 33, 0}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 29, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 33, 0}, asm.build());
         }
     }
 
@@ -305,7 +305,7 @@ public class RowAssemblerTest {
             asm.appendByte((byte)-33);
             asm.appendString("val");
 
-            assertRowBytesEquals(new byte[] {42, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, -33, 12, 0, 0, 0, 0, 1, 0, 9, 0, 118, 97, 108}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 12, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, -33, 11, 0, 0, 0, 1, 0, 8, 0, 118, 97, 108}, asm.build());
         }
 
         { // Null key.
@@ -314,7 +314,7 @@ public class RowAssemblerTest {
             asm.appendNull();
             asm.appendString("val");
 
-            assertRowBytesEquals(new byte[] {42, 0, 8, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 12, 0, 0, 0, 0, 1, 0, 9, 0, 118, 97, 108}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 12, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 11, 0, 0, 0, 1, 0, 8, 0, 118, 97, 108}, asm.build());
         }
 
         { // No value.
@@ -322,7 +322,7 @@ public class RowAssemblerTest {
 
             asm.appendByte((byte)33);
 
-            assertRowBytesEquals(new byte[] {42, 0, 25, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 33}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 29, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 33}, asm.build());
         }
     }
 
@@ -340,7 +340,7 @@ public class RowAssemblerTest {
             asm.appendUuid(uuidVal);
 
             assertRowBytesEquals(new byte[] {
-                42, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121,
+                42, 0, 18, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 8, 0, 107, 101, 121,
                 21, 0, 0, 0, 0, -117, -61, -31, 85, 61, -32, 57, 68, 111, 67, 56, -3, -99, -37, -58, -73}, asm.build());
         }
 
@@ -350,7 +350,7 @@ public class RowAssemblerTest {
             asm.appendString("key");
             asm.appendNull();
 
-            assertRowBytesEquals(new byte[] {42, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121, 5, 0, 0, 0, 1}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 18, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 8, 0, 107, 101, 121, 5, 0, 0, 0, 1}, asm.build());
         }
 
         { // No value.
@@ -358,7 +358,7 @@ public class RowAssemblerTest {
 
             asm.appendString("key");
 
-            assertRowBytesEquals(new byte[] {42, 0, 17, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 19, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 8, 0, 107, 101, 121}, asm.build());
         }
     }
 
@@ -376,8 +376,8 @@ public class RowAssemblerTest {
             asm.appendUuid(uuidVal);
 
             assertRowBytesEquals(new byte[] {
-                42, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121,
-                21, 0, 0, 0, 0, -117, -61, -31, 85, 61, -32, 57, 68, 111, 67, 56, -3, -99, -37, -58, -73}, asm.build());
+                42, 0, 22, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 8, 0, 107, 101, 121,
+                20, 0, 0, 0, -117, -61, -31, 85, 61, -32, 57, 68, 111, 67, 56, -3, -99, -37, -58, -73}, asm.build());
         }
 
         { // No value.
@@ -385,7 +385,7 @@ public class RowAssemblerTest {
 
             asm.appendString("key");
 
-            assertRowBytesEquals(new byte[] {42, 0, 17, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 23, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 8, 0, 107, 101, 121}, asm.build());
         }
     }
 
@@ -402,7 +402,7 @@ public class RowAssemblerTest {
             asm.appendString("key");
             asm.appendBytes(new byte[] {-1, 1, 0, 120});
 
-            assertRowBytesEquals(new byte[] {42, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121, 13, 0, 0, 0, 0, 1, 0, 9, 0, -1, 1, 0, 120}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 2, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 8, 0, 107, 101, 121, 13, 0, 0, 0, 0, 1, 0, 9, 0, -1, 1, 0, 120}, asm.build());
         }
 
         { // Null value.
@@ -411,7 +411,7 @@ public class RowAssemblerTest {
             asm.appendString("key");
             asm.appendNull();
 
-            assertRowBytesEquals(new byte[] {42, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121, 5, 0, 0, 0, 1}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 18, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 8, 0, 107, 101, 121, 5, 0, 0, 0, 1}, asm.build());
         }
 
         { // No value.
@@ -419,7 +419,7 @@ public class RowAssemblerTest {
 
             asm.appendString("key");
 
-            assertRowBytesEquals(new byte[] {42, 0, 17, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 19, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 8, 0, 107, 101, 121}, asm.build());
         }
     }
 
@@ -436,7 +436,7 @@ public class RowAssemblerTest {
             asm.appendString("key");
             asm.appendBytes(new byte[] {-1, 1, 0, 120});
 
-            assertRowBytesEquals(new byte[] {42, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121, 13, 0, 0, 0, 0, 1, 0, 9, 0, -1, 1, 0, 120}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 6, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 8, 0, 107, 101, 121, 12, 0, 0, 0, 1, 0, 8, 0, -1, 1, 0, 120}, asm.build());
         }
 
         { // No value.
@@ -444,7 +444,7 @@ public class RowAssemblerTest {
 
             asm.appendString("key");
 
-            assertRowBytesEquals(new byte[] {42, 0, 17, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 23, 0, 0, 0, 0, 0, 11, 0, 0, 0, 1, 0, 8, 0, 107, 101, 121}, asm.build());
         }
     }
 
@@ -513,7 +513,7 @@ public class RowAssemblerTest {
             asm.appendString("key");
             asm.appendShort((short)-71L);
 
-            assertRowBytesEquals(new byte[] {42, 0, 16, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121, 7, 0, 0, 0, 0, -71, -1}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 20, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121, 6, 0, 0, 0, -71, -1}, asm.build());
         }
 
         { // Null key.
@@ -522,7 +522,7 @@ public class RowAssemblerTest {
             asm.appendNull();
             asm.appendShort((short)71);
 
-            assertRowBytesEquals(new byte[] {42, 0, 24, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 7, 0, 0, 0, 0, 71, 0}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 28, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 6, 0, 0, 0, 71, 0}, asm.build());
         }
 
         { // No value.
@@ -530,7 +530,7 @@ public class RowAssemblerTest {
 
             asm.appendString("key");
 
-            assertRowBytesEquals(new byte[] {42, 0, 17, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 21, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121}, asm.build());
         }
     }
 
@@ -599,7 +599,7 @@ public class RowAssemblerTest {
             asm.appendString("key");
             asm.appendBytes(new byte[] {-1, 1, 0, 120});
 
-            assertRowBytesEquals(new byte[] {42, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121, 13, 0, 0, 0, 0, 1, 0, 9, 0, -1, 1, 0, 120}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 4, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121, 12, 0, 0, 0, 1, 0, 8, 0, -1, 1, 0, 120}, asm.build());
         }
 
         { // Null key.
@@ -608,7 +608,7 @@ public class RowAssemblerTest {
             asm.appendNull();
             asm.appendBytes(new byte[] {-1, 1, 0, 120});
 
-            assertRowBytesEquals(new byte[] {42, 0, 8, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 13, 0, 0, 0, 0, 1, 0, 9, 0, -1, 1, 0, 120}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 12, 0, 0, 0, 0, 0, 5, 0, 0, 0, 1, 12, 0, 0, 0, 1, 0, 8, 0, -1, 1, 0, 120}, asm.build());
         }
 
         { // No value.
@@ -616,7 +616,7 @@ public class RowAssemblerTest {
 
             asm.appendString("key");
 
-            assertRowBytesEquals(new byte[] {42, 0, 17, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121}, asm.build());
+            assertRowBytesEquals(new byte[] {42, 0, 21, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0, 9, 0, 107, 101, 121}, asm.build());
         }
     }