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

bereng pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 2a458ba01d Improved DeletionTime serialization
2a458ba01d is described below

commit 2a458ba01dae3b35b62ad2ef361e1acb567c97f0
Author: Bereng <[email protected]>
AuthorDate: Wed Jun 14 09:41:44 2023 +0200

    Improved DeletionTime serialization
---
 src/java/org/apache/cassandra/db/DeletionTime.java |  95 +++++-
 .../io/sstable/format/bti/PartitionIndex.java      |   2 +-
 .../io/sstable/format/bti/RowIndexReader.java      |  15 +-
 .../format/bti/RowIndexReverseIterator.java        |   5 +-
 src/java/org/apache/cassandra/io/tries/Walker.java |  15 +-
 .../legacy_da_clust/da-1-bti-CompressionInfo.db    | Bin 207 -> 207 bytes
 .../legacy_tables/legacy_da_clust/da-1-bti-Data.db | Bin 8660 -> 8616 bytes
 .../legacy_da_clust/da-1-bti-Digest.crc32          |   2 +-
 .../legacy_da_clust/da-1-bti-Partitions.db         | Bin 62 -> 62 bytes
 .../legacy_tables/legacy_da_clust/da-1-bti-Rows.db | Bin 563 -> 508 bytes
 .../legacy_da_clust/da-1-bti-Statistics.db         | Bin 7312 -> 7312 bytes
 .../da-1-bti-CompressionInfo.db                    | Bin 199 -> 199 bytes
 .../legacy_da_clust_counter/da-1-bti-Data.db       | Bin 7767 -> 7408 bytes
 .../legacy_da_clust_counter/da-1-bti-Digest.crc32  |   2 +-
 .../legacy_da_clust_counter/da-1-bti-Partitions.db | Bin 62 -> 62 bytes
 .../legacy_da_clust_counter/da-1-bti-Rows.db       | Bin 563 -> 508 bytes
 .../legacy_da_clust_counter/da-1-bti-Statistics.db | Bin 7321 -> 7321 bytes
 .../legacy_da_simple/da-1-bti-CompressionInfo.db   | Bin 47 -> 47 bytes
 .../legacy_da_simple/da-1-bti-Data.db              | Bin 88 -> 79 bytes
 .../legacy_da_simple/da-1-bti-Digest.crc32         |   2 +-
 .../legacy_da_simple/da-1-bti-Partitions.db        | Bin 59 -> 58 bytes
 .../legacy_da_simple/da-1-bti-Statistics.db        | Bin 4822 -> 4822 bytes
 .../da-1-bti-CompressionInfo.db                    | Bin 47 -> 47 bytes
 .../legacy_da_simple_counter/da-1-bti-Data.db      | Bin 140 -> 133 bytes
 .../legacy_da_simple_counter/da-1-bti-Digest.crc32 |   2 +-
 .../da-1-bti-Partitions.db                         | Bin 60 -> 60 bytes
 .../da-1-bti-Statistics.db                         | Bin 4831 -> 4831 bytes
 .../legacy_oa_clust/oa-1-big-CompressionInfo.db    | Bin 207 -> 207 bytes
 .../legacy_tables/legacy_oa_clust/oa-1-big-Data.db | Bin 8630 -> 8609 bytes
 .../legacy_oa_clust/oa-1-big-Digest.crc32          |   2 +-
 .../legacy_oa_clust/oa-1-big-Index.db              | Bin 157553 -> 157498 bytes
 .../legacy_oa_clust/oa-1-big-Statistics.db         | Bin 7312 -> 7312 bytes
 .../oa-1-big-CompressionInfo.db                    | Bin 199 -> 199 bytes
 .../legacy_oa_clust_counter/oa-1-big-Data.db       | Bin 7718 -> 7352 bytes
 .../legacy_oa_clust_counter/oa-1-big-Digest.crc32  |   2 +-
 .../legacy_oa_clust_counter/oa-1-big-Index.db      | Bin 157553 -> 157498 bytes
 .../legacy_oa_clust_counter/oa-1-big-Statistics.db | Bin 7321 -> 7321 bytes
 .../legacy_oa_simple/oa-1-big-CompressionInfo.db   | Bin 47 -> 47 bytes
 .../legacy_oa_simple/oa-1-big-Data.db              | Bin 88 -> 78 bytes
 .../legacy_oa_simple/oa-1-big-Digest.crc32         |   2 +-
 .../legacy_oa_simple/oa-1-big-Index.db             | Bin 26 -> 25 bytes
 .../legacy_oa_simple/oa-1-big-Statistics.db        | Bin 4822 -> 4822 bytes
 .../oa-1-big-CompressionInfo.db                    | Bin 47 -> 47 bytes
 .../legacy_oa_simple_counter/oa-1-big-Data.db      | Bin 141 -> 134 bytes
 .../legacy_oa_simple_counter/oa-1-big-Digest.crc32 |   2 +-
 .../legacy_oa_simple_counter/oa-1-big-Index.db     | Bin 27 -> 27 bytes
 .../oa-1-big-Statistics.db                         | Bin 4831 -> 4831 bytes
 .../test/microbench/DeletionTimeDeSerBench.java    | 366 +++++++++++++++++++++
 .../cassandra/db/compaction/CompactionsTest.java   |   8 +-
 .../io/sstable/format/big/RowIndexEntryTest.java   |  16 +-
 .../cassandra/transport/DeletionTimeDeSerTest.java |  97 ++++++
 51 files changed, 589 insertions(+), 46 deletions(-)

diff --git a/src/java/org/apache/cassandra/db/DeletionTime.java 
b/src/java/org/apache/cassandra/db/DeletionTime.java
index 60ac407a76..a0450a0fd1 100644
--- a/src/java/org/apache/cassandra/db/DeletionTime.java
+++ b/src/java/org/apache/cassandra/db/DeletionTime.java
@@ -195,42 +195,103 @@ public class DeletionTime implements 
Comparable<DeletionTime>, IMeasurableMemory
             return legacySerializer;
     }
 
-    // Serializer for Usigned Integer ldt
+    /* Serializer for Usigned Integer ldt
+     *
+     * ldt is encoded as a uint in seconds since unix epoch, it can go up o 
2106-02-07T06:28:13+00:00 only. 
+     * mfda is a positive timestamp. We use the sign bit to encode LIVE 
DeletionTimes
+     * Throw IOException to mark sstable as corrupt.
+     */
     public static class Serializer implements ISerializer<DeletionTime>
     {
+        // We use the sign bit to signal LIVE DeletionTimes
+        private final static int IS_LIVE_DELETION = 0b1000_0000;
+
         public void serialize(DeletionTime delTime, DataOutputPlus out) throws 
IOException
         {
-            out.writeInt(delTime.localDeletionTimeUnsignedInteger);
-            out.writeLong(delTime.markedForDeleteAt());
+            if (delTime == LIVE)
+                out.writeByte(IS_LIVE_DELETION);
+            else
+            {
+                // The sign bit is zero here, so we can write a long directly
+                out.writeLong(delTime.markedForDeleteAt());
+                out.writeInt(delTime.localDeletionTimeUnsignedInteger);
+            }
         }
 
         public DeletionTime deserialize(DataInputPlus in) throws IOException
         {
-            int localDeletionTimeUnsignedInteger = in.readInt();
-            long mfda = in.readLong();
-            return mfda == Long.MIN_VALUE && localDeletionTimeUnsignedInteger 
== Cell.NO_DELETION_TIME_UNSIGNED_INTEGER
-                 ? LIVE
-                 : new DeletionTime(mfda, localDeletionTimeUnsignedInteger);
+            int flags = in.readByte();
+            if ((flags & IS_LIVE_DELETION) != 0)
+            {
+                if ((flags & 0xFF) != IS_LIVE_DELETION)
+                    throw new IOException("Corrupted sstable. Invalid flags 
found deserializing DeletionTime: " + Integer.toBinaryString(flags & 0xFF));
+                return LIVE;
+            }
+            else
+            {
+                // Read the remaining 7 bytes
+                int bytes1 = in.readByte();
+                int bytes2 = in.readShort();
+                int bytes4 = in.readInt();
+
+                long mfda = readBytesToMFDA(flags, bytes1, bytes2, bytes4);
+                int localDeletionTimeUnsignedInteger = in.readInt();
+
+                return new DeletionTime(mfda, 
localDeletionTimeUnsignedInteger);
+            }
         }
 
-        public DeletionTime deserialize(ByteBuffer buf, int offset)
+        public DeletionTime deserialize(ByteBuffer buf, int offset) throws 
IOException
         {
-            int localDeletionTimeUnsignedInteger = buf.getInt(offset);
-            long mfda = buf.getLong(offset + 4);
-            return mfda == Long.MIN_VALUE && localDeletionTimeUnsignedInteger 
== Cell.NO_DELETION_TIME_UNSIGNED_INTEGER
-                   ? LIVE
-                   : new DeletionTime(mfda, localDeletionTimeUnsignedInteger);
+            int flags = buf.get(offset);
+            if ((flags & IS_LIVE_DELETION) != 0)
+            {
+                if ((flags & 0xFF) != IS_LIVE_DELETION)
+                    throw new IOException("Corrupted sstable. Invalid flags 
found deserializing DeletionTime: " + Integer.toBinaryString(flags & 0xFF));
+                return LIVE;
+            }
+            else
+            {
+                long mfda = buf.getLong(offset);
+                int localDeletionTimeUnsignedInteger = buf.getInt(offset + 
TypeSizes.LONG_SIZE);
+
+                return new DeletionTime(mfda, 
localDeletionTimeUnsignedInteger);
+            }
         }
 
         public void skip(DataInputPlus in) throws IOException
         {
-            in.skipBytesFully(4 + 8);
+            int flags = in.readByte();
+            if ((flags & IS_LIVE_DELETION) != 0)
+            {
+                if ((flags & 0xFF) != IS_LIVE_DELETION)
+                    throw new IOException("Corrupted sstable. Invalid flags 
found deserializing DeletionTime: " + Integer.toBinaryString(flags & 0xFF));
+                // We read the flags already and there's nothing left to skip 
over
+                return;
+            }
+            else
+                // We read the flags already but there is mfda and ldt to skip 
over still
+                in.skipBytesFully(TypeSizes.LONG_SIZE - 1 + 
TypeSizes.INT_SIZE);
         }
 
         public long serializedSize(DeletionTime delTime)
         {
-            return TypeSizes.sizeof(Integer.MAX_VALUE)
-                   + TypeSizes.sizeof(delTime.markedForDeleteAt());
+            if (delTime == LIVE)
+                // Just the flags
+                return 1;
+            else
+                // 1 for the flags, 7 for mfda and 4 for ldt
+                return TypeSizes.LONG_SIZE
+                       + TypeSizes.INT_SIZE;
+        }
+
+        private long readBytesToMFDA(int flagsByte, int bytes1, int bytes2, 
int bytes4)
+        {
+                long mfda = flagsByte & 0xFFL;
+                mfda = (mfda << 8) + (bytes1 & 0xFFL);
+                mfda = (mfda << 16) + (bytes2 & 0xFFFFL);
+                mfda = (mfda << 32) + (bytes4 & 0xFFFFFFFFL);
+                return mfda;
         }
     }
 
diff --git 
a/src/java/org/apache/cassandra/io/sstable/format/bti/PartitionIndex.java 
b/src/java/org/apache/cassandra/io/sstable/format/bti/PartitionIndex.java
index e71355007a..12d35d7cd6 100644
--- a/src/java/org/apache/cassandra/io/sstable/format/bti/PartitionIndex.java
+++ b/src/java/org/apache/cassandra/io/sstable/format/bti/PartitionIndex.java
@@ -443,7 +443,7 @@ public class PartitionIndex implements SharedCloseable
         }
     }
 
-    private void dumpTrie(PrintStream out)
+    private void dumpTrie(PrintStream out) throws IOException
     {
         try (Reader rdr = openReader())
         {
diff --git 
a/src/java/org/apache/cassandra/io/sstable/format/bti/RowIndexReader.java 
b/src/java/org/apache/cassandra/io/sstable/format/bti/RowIndexReader.java
index 3bb75f45db..3bfd2903fc 100644
--- a/src/java/org/apache/cassandra/io/sstable/format/bti/RowIndexReader.java
+++ b/src/java/org/apache/cassandra/io/sstable/format/bti/RowIndexReader.java
@@ -76,8 +76,9 @@ public class RowIndexReader extends Walker<RowIndexReader>
 
     /**
      * Computes the floor for a given key.
+     * @throws IOException 
      */
-    public IndexInfo separatorFloor(ByteComparable key)
+    public IndexInfo separatorFloor(ByteComparable key) throws IOException
     {
         // Check for a prefix and find closest smaller branch.
         IndexInfo res = prefixAndNeighbours(key, RowIndexReader::readPayload);
@@ -96,23 +97,23 @@ public class RowIndexReader extends Walker<RowIndexReader>
         return getCurrentIndexInfo();
     }
 
-    public IndexInfo min()
+    public IndexInfo min() throws IOException
     {
         goMin(root);
         return getCurrentIndexInfo();
     }
 
-    protected IndexInfo getCurrentIndexInfo()
+    protected IndexInfo getCurrentIndexInfo() throws IOException
     {
         return readPayload(payloadPosition(), payloadFlags());
     }
 
-    protected IndexInfo readPayload(int ppos, int bits)
+    protected IndexInfo readPayload(int ppos, int bits) throws IOException
     {
         return readPayload(buf, ppos, bits, version);
     }
 
-    static IndexInfo readPayload(ByteBuffer buf, int ppos, int bits, Version 
version)
+    static IndexInfo readPayload(ByteBuffer buf, int ppos, int bits, Version 
version) throws IOException
     {
         long dataOffset;
         if (bits == 0)
@@ -183,12 +184,12 @@ public class RowIndexReader extends Walker<RowIndexReader>
 
     // debug/test code
     @SuppressWarnings("unused")
-    public void dumpTrie(PrintStream out)
+    public void dumpTrie(PrintStream out) throws IOException
     {
         dumpTrie(out, RowIndexReader::dumpRowIndexEntry, version);
     }
 
-    static String dumpRowIndexEntry(ByteBuffer buf, int ppos, int bits, 
Version version)
+    static String dumpRowIndexEntry(ByteBuffer buf, int ppos, int bits, 
Version version) throws IOException
     {
         IndexInfo ii = readPayload(buf, ppos, bits, version);
 
diff --git 
a/src/java/org/apache/cassandra/io/sstable/format/bti/RowIndexReverseIterator.java
 
b/src/java/org/apache/cassandra/io/sstable/format/bti/RowIndexReverseIterator.java
index 0a0ee00ffd..0d7878973b 100644
--- 
a/src/java/org/apache/cassandra/io/sstable/format/bti/RowIndexReverseIterator.java
+++ 
b/src/java/org/apache/cassandra/io/sstable/format/bti/RowIndexReverseIterator.java
@@ -17,6 +17,7 @@
  */
 package org.apache.cassandra.io.sstable.format.bti;
 
+import java.io.IOException;
 import java.io.PrintStream;
 
 import org.apache.cassandra.io.sstable.format.Version;
@@ -44,7 +45,7 @@ class RowIndexReverseIterator extends 
ReverseValueIterator<RowIndexReverseIterat
         this(file, entry.indexTrieRoot, ByteComparable.EMPTY, end, version);
     }
 
-    public IndexInfo nextIndexInfo()
+    public IndexInfo nextIndexInfo() throws IOException
     {
         if (currentNode == -1)
         {
@@ -62,7 +63,7 @@ class RowIndexReverseIterator extends 
ReverseValueIterator<RowIndexReverseIterat
 
     // debug/test code
     @SuppressWarnings("unused")
-    public void dumpTrie(PrintStream out)
+    public void dumpTrie(PrintStream out) throws IOException
     {
         dumpTrie(out, RowIndexReader::dumpRowIndexEntry, version);
     }
diff --git a/src/java/org/apache/cassandra/io/tries/Walker.java 
b/src/java/org/apache/cassandra/io/tries/Walker.java
index 3655dd74cc..be65952397 100644
--- a/src/java/org/apache/cassandra/io/tries/Walker.java
+++ b/src/java/org/apache/cassandra/io/tries/Walker.java
@@ -17,6 +17,7 @@
  */
 package org.apache.cassandra.io.tries;
 
+import java.io.IOException;
 import java.io.PrintStream;
 import java.nio.ByteBuffer;
 
@@ -184,7 +185,7 @@ public class Walker<CONCRETE extends Walker<CONCRETE>> 
implements AutoCloseable
 
     public interface Extractor<RESULT, VALUE>
     {
-        RESULT extract(VALUE walker, int payloadPosition, int payloadFlags);
+        RESULT extract(VALUE walker, int payloadPosition, int payloadFlags) 
throws IOException;
     }
 
     /**
@@ -268,9 +269,10 @@ public class Walker<CONCRETE extends Walker<CONCRETE>> 
implements AutoCloseable
      * is in the trie when looking for 'abc' or 'ac', but accepted when 
looking for 'aa').
      * In order to not have to go back to data that may have exited cache, 
payloads are extracted when the node is
      * visited (instead of saving the node's position), which requires an 
extractor to be passed as parameter.
+     * @throws IOException 
      */
     @SuppressWarnings("unchecked")
-    public <RESULT> RESULT prefix(ByteComparable key, Extractor<RESULT, 
CONCRETE> extractor)
+    public <RESULT> RESULT prefix(ByteComparable key, Extractor<RESULT, 
CONCRETE> extractor) throws IOException
     {
         RESULT payload = null;
 
@@ -304,9 +306,10 @@ public class Walker<CONCRETE extends Walker<CONCRETE>> 
implements AutoCloseable
      * does not take that into account. E.g. if trie contains "abba", "as" and 
"ask", looking for "asking" will find
      * "ask" as the match, but max(lesserBranch) will point to "abba" instead 
of the correct "as". This problem can
      * only occur if there is a valid prefix match.
+     * @throws IOException 
      */
     @SuppressWarnings("unchecked")
-    public <RESULT> RESULT prefixAndNeighbours(ByteComparable key, 
Extractor<RESULT, CONCRETE> extractor)
+    public <RESULT> RESULT prefixAndNeighbours(ByteComparable key, 
Extractor<RESULT, CONCRETE> extractor) throws IOException
     {
         RESULT payload = null;
         greaterBranch = NONE;
@@ -358,16 +361,16 @@ public class Walker<CONCRETE extends Walker<CONCRETE>> 
implements AutoCloseable
 
     public interface PayloadToString
     {
-        String payloadAsString(ByteBuffer buf, int payloadPos, int 
payloadFlags, Version version);
+        String payloadAsString(ByteBuffer buf, int payloadPos, int 
payloadFlags, Version version) throws IOException;
     }
 
-    public void dumpTrie(PrintStream out, PayloadToString payloadReader, 
Version version)
+    public void dumpTrie(PrintStream out, PayloadToString payloadReader, 
Version version) throws IOException
     {
         out.print("ROOT");
         dumpTrie(out, payloadReader, root, "", version);
     }
 
-    private void dumpTrie(PrintStream out, PayloadToString payloadReader, long 
node, String indent, Version version)
+    private void dumpTrie(PrintStream out, PayloadToString payloadReader, long 
node, String indent, Version version) throws IOException
     {
         go(node);
         int bits = payloadFlags();
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-CompressionInfo.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-CompressionInfo.db
index 4f8f029e9a..a0dbaf1f88 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-CompressionInfo.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-CompressionInfo.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Data.db 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Data.db
index ed53ab7cb3..4daf0fcb64 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Data.db 
and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Data.db 
differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Digest.crc32
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Digest.crc32
index 4a59ffcab2..4c59b00640 100644
--- 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Digest.crc32
+++ 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Digest.crc32
@@ -1 +1 @@
-1178851237
\ No newline at end of file
+1983729251
\ No newline at end of file
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Partitions.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Partitions.db
index daf1b01ec1..6e4273411f 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Partitions.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Partitions.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Rows.db 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Rows.db
index a8301fedae..61741774b8 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Rows.db 
and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Rows.db 
differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Statistics.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Statistics.db
index bfb5b1fe09..9a47c5fde9 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Statistics.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust/da-1-bti-Statistics.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-CompressionInfo.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-CompressionInfo.db
index a15fed64cf..849043e8d1 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-CompressionInfo.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-CompressionInfo.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Data.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Data.db
index 476fbae69b..4458afd2be 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Data.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Data.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Digest.crc32
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Digest.crc32
index 79735e8a66..947363bf18 100644
--- 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Digest.crc32
+++ 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Digest.crc32
@@ -1 +1 @@
-1260299575
\ No newline at end of file
+2020062012
\ No newline at end of file
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Partitions.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Partitions.db
index daf1b01ec1..6e4273411f 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Partitions.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Partitions.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Rows.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Rows.db
index d964845504..843544e52d 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Rows.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Rows.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Statistics.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Statistics.db
index 771b182596..13391d0142 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Statistics.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_clust_counter/da-1-bti-Statistics.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-CompressionInfo.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-CompressionInfo.db
index ef683177e8..f30e3ceb79 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-CompressionInfo.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-CompressionInfo.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Data.db 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Data.db
index 33d7cdac7d..827bcc2784 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Data.db 
and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Data.db 
differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Digest.crc32
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Digest.crc32
index 1397dbf01a..1027de9860 100644
--- 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Digest.crc32
+++ 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Digest.crc32
@@ -1 +1 @@
-2099476497
\ No newline at end of file
+1689908368
\ No newline at end of file
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Partitions.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Partitions.db
index e20b4e2f27..dc31ba9d1a 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Partitions.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Partitions.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Statistics.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Statistics.db
index e3f6687067..25875803b5 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Statistics.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple/da-1-bti-Statistics.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-CompressionInfo.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-CompressionInfo.db
index 1db9aa06b3..0476db58d0 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-CompressionInfo.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-CompressionInfo.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Data.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Data.db
index cf0cf6037b..ba53b39936 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Data.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Data.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Digest.crc32
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Digest.crc32
index a4b6f172c8..eeb0df5bf1 100644
--- 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Digest.crc32
+++ 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Digest.crc32
@@ -1 +1 @@
-1213045656
\ No newline at end of file
+2128362302
\ No newline at end of file
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Partitions.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Partitions.db
index 773d3c8891..dafb436f43 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Partitions.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Partitions.db
 differ
diff --git 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Statistics.db
 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Statistics.db
index be65831af8..e49dc56577 100644
Binary files 
a/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Statistics.db
 and 
b/test/data/legacy-sstables/da/legacy_tables/legacy_da_simple_counter/da-1-bti-Statistics.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-CompressionInfo.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-CompressionInfo.db
index f0da520ba8..36e56d0806 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-CompressionInfo.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-CompressionInfo.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Data.db 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Data.db
index 84cf2cf377..ac4a8f4a77 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Data.db 
and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Data.db 
differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Digest.crc32
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Digest.crc32
index 8b26bdb90c..206a90a9a7 100644
--- 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Digest.crc32
+++ 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Digest.crc32
@@ -1 +1 @@
-1331566588
\ No newline at end of file
+103182460
\ No newline at end of file
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Index.db 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Index.db
index 5270679377..7c22f31957 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Index.db 
and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Index.db 
differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Statistics.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Statistics.db
index 0893527153..6c4d020b85 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Statistics.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust/oa-1-big-Statistics.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-CompressionInfo.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-CompressionInfo.db
index 77fb7011fe..a002214c5d 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-CompressionInfo.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-CompressionInfo.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Data.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Data.db
index 665e2d7e8c..1c583572d1 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Data.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Data.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Digest.crc32
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Digest.crc32
index 7e4c746c63..ebca35dfe9 100644
--- 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Digest.crc32
+++ 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Digest.crc32
@@ -1 +1 @@
-1886131535
\ No newline at end of file
+3206431625
\ No newline at end of file
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Index.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Index.db
index e61eea8289..41c78956fb 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Index.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Index.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Statistics.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Statistics.db
index 8a56ecf9d4..f07515b1dd 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Statistics.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_clust_counter/oa-1-big-Statistics.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-CompressionInfo.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-CompressionInfo.db
index ef683177e8..f30e3ceb79 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-CompressionInfo.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-CompressionInfo.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Data.db 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Data.db
index 376296d5af..baee7e3b0f 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Data.db 
and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Data.db 
differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Digest.crc32
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Digest.crc32
index 4a4c86e1e5..ade6ab1cb8 100644
--- 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Digest.crc32
+++ 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Digest.crc32
@@ -1 +1 @@
-1899914505
\ No newline at end of file
+309360903
\ No newline at end of file
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Index.db 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Index.db
index b3094bffba..e4ed7172a1 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Index.db 
and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Index.db 
differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Statistics.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Statistics.db
index b1553b5058..ce9a9507ce 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Statistics.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple/oa-1-big-Statistics.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-CompressionInfo.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-CompressionInfo.db
index 1db9aa06b3..0476db58d0 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-CompressionInfo.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-CompressionInfo.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Data.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Data.db
index 32f381c004..f87d977f0a 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Data.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Data.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Digest.crc32
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Digest.crc32
index 497ae8200d..f7414d2c73 100644
--- 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Digest.crc32
+++ 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Digest.crc32
@@ -1 +1 @@
-3169912797
\ No newline at end of file
+2437993698
\ No newline at end of file
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Index.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Index.db
index 59e65cab85..4cb2af35d1 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Index.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Index.db
 differ
diff --git 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Statistics.db
 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Statistics.db
index 92f2831480..9171309ff9 100644
Binary files 
a/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Statistics.db
 and 
b/test/data/legacy-sstables/oa/legacy_tables/legacy_oa_simple_counter/oa-1-big-Statistics.db
 differ
diff --git 
a/test/microbench/org/apache/cassandra/test/microbench/DeletionTimeDeSerBench.java
 
b/test/microbench/org/apache/cassandra/test/microbench/DeletionTimeDeSerBench.java
new file mode 100644
index 0000000000..3009f20ce5
--- /dev/null
+++ 
b/test/microbench/org/apache/cassandra/test/microbench/DeletionTimeDeSerBench.java
@@ -0,0 +1,366 @@
+/*
+ * 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.cassandra.test.microbench;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.NoSuchFileException;
+import java.util.ArrayList;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.cassandra.db.DeletionTime;
+import org.apache.cassandra.db.DeletionTime.Serializer;
+import org.apache.cassandra.io.util.DataInputBuffer;
+import org.apache.cassandra.io.util.DataInputPlus;
+import org.apache.cassandra.io.util.DataOutputBuffer;
+import org.apache.cassandra.io.util.DataOutputStreamPlus;
+import org.apache.cassandra.io.util.FileInputStreamPlus;
+import org.apache.cassandra.io.util.FileOutputStreamPlus;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS)
+@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
+@Fork(value = 3, jvmArgsAppend = "-Xmx512M")
+@Threads(1)
+@State(Scope.Benchmark)
+public class DeletionTimeDeSerBench
+{
+    final static int BUFFER_SIZE = 1024 * 1024;
+    final static int DT_STD_SIZE = 8 + 4; // Long + Int
+
+    final static Random random = new Random(100);
+    final static ArrayList<DeletionTime> TEST_DTS_70PC_LIVE = generateDTs(70);
+    final static ArrayList<DeletionTime> TEST_DTS_30PC_LIVE = generateDTs(30);
+
+    // Parameters
+    final static String ncSstableParam = "NC";
+    final static String oaSstableParam = "OA";
+    @Param({ ncSstableParam, oaSstableParam })
+    String sstableParam;
+
+    final static String live70PcParam = "70PcLive";
+    final static String live30PcParam = "30PcLive";
+    @Param({ live70PcParam, live30PcParam })
+    String liveDTPcParam;
+
+    final static String RAMParam = "RAM";
+    final static String diskParam = "Disk";
+    @Param({ RAMParam,  diskParam })
+    String diskRAMParam;
+
+    // Files
+    File serMMapedFile = new File(DeletionTimeDeSerBench.class + "_Sermmap");
+    ByteBuffer serMMap = allocateMmapedByteBuffer(serMMapedFile, BUFFER_SIZE);
+    File deserMMapedFile = new File(DeletionTimeDeSerBench.class + 
"_Desermmap");
+    ByteBuffer deserMMap = allocateMmapedByteBuffer(deserMMapedFile, 
BUFFER_SIZE);
+    File diskFile = new File(DeletionTimeDeSerBench.class + "_DTBenchTest");
+
+    @TearDown
+    public void tearDown()
+    {
+        serMMapedFile.delete();
+        deserMMapedFile.delete();
+        diskFile.delete();
+    }
+
+    @Benchmark
+    public void testE2ESerializeDT(final Blackhole bh) throws IOException
+    {
+        ByteBuffer buffer = serMMap;
+        Serializer serializer = getSerializer(sstableParam);
+        ArrayList<DeletionTime> dts = getDTs(liveDTPcParam);
+        
+        try(DataOutputStreamPlus out = getSerOut(diskRAMParam, serMMap))
+        {
+            for (int i = 0, m = dts.size(); i < m; i++)
+                serializer.serialize(dts.get(i), out);
+            bh.consume(out);
+        }
+
+        bh.consume(buffer);
+        bh.consume(serializer);
+        bh.consume(dts);
+        buffer.clear();
+    }
+
+    @Benchmark
+    public void testE2EDeSerializeDT(final Blackhole bh) throws IOException
+    {
+        ByteBuffer buffer = deserMMap;
+        Serializer serializer = getSerializer(sstableParam);
+        ArrayList<DeletionTime> dts = getDTs(liveDTPcParam);
+        
+        try(DataOutputStreamPlus out = getSerOut(diskRAMParam, deserMMap))
+        {
+            for (int i = 0, m = dts.size(); i < m; i++)
+                serializer.serialize(dts.get(i), out);
+            bh.consume(out);
+        }
+
+        DataInputPlus in = getDeSerIn(diskRAMParam, deserMMap);
+        for (int i = 0, m = dts.size(); i < m; i++)
+            serializer.deserialize(in);
+
+        bh.consume(buffer);
+        bh.consume(serializer);
+        bh.consume(dts);
+        bh.consume(in);
+        buffer.clear();
+    }
+
+    /**
+     * Test the impact of the different bit ops and write calls. Against 
memory only.
+     */
+    @Benchmark
+    public void testRawAlgWrites(final Blackhole bh)
+    {
+        if (diskRAMParam != RAMParam)
+            return;
+
+        ArrayList<DeletionTime> dts = getDTs(liveDTPcParam);
+        ByteBuffer buffer = ByteBuffer.allocate(DT_STD_SIZE);
+
+        if (sstableParam == oaSstableParam)
+        {
+            for (int i = 0, m = dts.size(); i < m; i++)
+            {
+                buffer.clear();
+                if (dts.get(i).equals(DeletionTime.LIVE))
+                    buffer.put((byte) 0b1000_0000);
+                else
+                {
+                    buffer.putLong(Math.abs(random.nextLong()));
+                    buffer.putInt(Math.abs(random.nextInt()));
+                }
+            }
+        }
+        else
+        {
+            for (int i = 0, m = dts.size(); i < m; i++)
+            {
+                buffer.clear();
+                buffer.putLong(Math.abs(random.nextLong()));
+                buffer.putInt(Math.abs(random.nextInt()));
+            }
+        }
+
+        bh.consume(dts);
+        bh.consume(buffer);
+    }
+
+    /**
+     * Test the impact of the different bit ops and read calls. Against memory 
only.
+     */
+    @Benchmark
+    public void testRawAlgReads(final Blackhole bh)
+    {
+        if (diskRAMParam != RAMParam)
+            return;
+
+        ArrayList<DeletionTime> dts = getDTs(liveDTPcParam);
+        ByteBuffer buffer = ByteBuffer.allocate(DT_STD_SIZE);
+        buffer.putLong(random.nextLong() & Long.MAX_VALUE); // to prevent 
Match.abs(MIN_VALUE) == MIN_VALUE
+        buffer.putInt(random.nextInt() & Integer.MAX_VALUE);
+
+        if (sstableParam == oaSstableParam)
+        {
+            for (int i = 0, m = dts.size(); i < m; i++)
+            {
+                buffer.clear();
+
+                if (dts.get(i).equals(DeletionTime.LIVE))
+                {
+                    // LIVE: we only read the flags Byte
+                    byte b = buffer.get();
+                    b = (byte) (b & 0b1000_0000 & 0xFF);
+                    bh.consume(b);
+                }
+                else
+                {
+                    // The flag
+                    byte flag = buffer.get();
+
+                    // 7 bytes mfda
+                    int bytes4 = buffer.getInt();
+                    int bytes2 = buffer.getShort();
+                    int bytes1 = buffer.get();
+
+                    long mfda = flag & 0xFFL;
+                    mfda = (mfda << 32) + (bytes4 & 0xFFFFFFFFL);
+                    mfda = (mfda << 16) + (bytes2 & 0xFFFFL);
+                    mfda = (mfda << 8) + (bytes1 & 0xFFL);
+                    
+                    // The ldt
+                    int ldt = buffer.getInt();
+
+                    bh.consume(flag);
+                    bh.consume(bytes4);
+                    bh.consume(bytes2);
+                    bh.consume(bytes1);
+                    bh.consume(mfda);
+                    bh.consume(ldt);
+                }
+            }
+        }
+        else
+        {
+            for (int i = 0, m = dts.size(); i < m; i++)
+            {
+                buffer.clear();
+                long mfda = buffer.getLong();
+                int ldt = buffer.getInt();
+
+                bh.consume(mfda);
+                bh.consume(ldt);
+            }
+        }
+
+        bh.consume(dts);
+        bh.consume(buffer);
+    }
+
+    private DataInputPlus getDeSerIn(String value, ByteBuffer maybeBackingBB)
+    {
+        switch (value)
+        {
+            case RAMParam:
+                maybeBackingBB.rewind();
+                return new DataInputBuffer(maybeBackingBB, false);
+
+            case diskParam:
+                try
+                {
+                    return new FileInputStreamPlus(new 
org.apache.cassandra.io.util.File(diskFile));
+                }
+                catch(NoSuchFileException e)
+                {
+                    throw new RuntimeException(e);
+                }
+
+            default:
+                throw new IllegalStateException("Unknown backing media for 
deser.");
+        }
+    }
+
+    private DataOutputStreamPlus getSerOut(String value, ByteBuffer 
maybeBackingBB)
+    {
+        switch (value)
+        {
+            case RAMParam:
+                maybeBackingBB.rewind();
+                return new DataOutputBuffer(maybeBackingBB);
+
+            case diskParam:
+                try
+                {
+                    return new FileOutputStreamPlus(new 
org.apache.cassandra.io.util.File(diskFile));
+                }
+                catch(NoSuchFileException e)
+                {
+                    throw new RuntimeException(e);
+                }
+
+            default:
+                throw new IllegalStateException("Unknown backing media for 
ser.");
+        }
+    }
+
+    /**
+     * Generates DeletionTimes where livePercentage are DeletionTime.LIVE
+     * @param livePercentage
+     * @return
+     */
+    private static ArrayList<DeletionTime> generateDTs(int livePercentage)
+    {
+        ArrayList<DeletionTime> dts = new ArrayList<>(BUFFER_SIZE / 
DT_STD_SIZE);
+        for (int i = 0; i < (BUFFER_SIZE / (DT_STD_SIZE)); i++)
+        {
+            DeletionTime dt;
+
+            if ((random.nextInt() % 100) < livePercentage)
+                dt = DeletionTime.LIVE;
+            else
+                dt = DeletionTime.build(Math.abs(random.nextLong()), 
Math.abs(random.nextInt()));
+
+            dts.add(dt);
+        }
+
+        return dts;
+    }
+
+    private static ArrayList<DeletionTime> getDTs(String value)
+    {
+        switch (value)
+        {
+            case live70PcParam:
+                return TEST_DTS_70PC_LIVE;
+
+            case live30PcParam:
+                return TEST_DTS_30PC_LIVE;
+
+            default:
+                throw new IllegalStateException("Unknown live DT PC");
+        }
+    }
+
+    private static Serializer getSerializer(String value)
+    {
+        switch (value)
+        {
+            case ncSstableParam:
+                return new DeletionTime.LegacySerializer();
+
+            case oaSstableParam:
+                return new DeletionTime.Serializer();
+
+            default:
+                throw new IllegalStateException("Unknown serializer");
+        }
+    }
+
+    private static ByteBuffer allocateMmapedByteBuffer(File mmapFile, int 
bufferSize)
+    {
+        try(RandomAccessFile file = new RandomAccessFile(mmapFile, "rw"); 
FileChannel ch = file.getChannel())
+        {
+            return ch.map(FileChannel.MapMode.READ_WRITE, 0, bufferSize);
+        }
+        catch(IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java 
b/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
index 6fbf0261a3..435b19ad03 100644
--- a/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
+++ b/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
@@ -186,12 +186,14 @@ public class CompactionsTest
         // disable compaction while flushing
         store.disableAutoCompaction();
 
-        //Populate sstable1 with with keys [0a..29a]
-        populate(KEYSPACE1, CF_STANDARD1, 0, 29, "a",3); //ttl=3s
+        //Populate sstable1 with with keys [0a..29aaaaaaaaaaa] Partitions have 
to be big enough 
+        //that prevent the size dependent 
AbstractCompactionStrategy.worthDroppingTombstones to trigger 
+        //a compaction.
+        populate(KEYSPACE1, CF_STANDARD1, 0, 29, "aaaaaaaaaaa",3); //ttl=3s
         Util.flush(store);
 
         //Populate sstable2 with with keys [0b..29b] (keys do not overlap with 
SSTable1, but the range is almost fully covered)
-        long timestamp2 = populate(KEYSPACE1, CF_STANDARD1, 0, 29, "b", 3); 
//ttl=3s
+        long timestamp2 = populate(KEYSPACE1, CF_STANDARD1, 0, 29, 
"bbbbbbbbbbb", 3); //ttl=3s
         Util.flush(store);
 
         assertEquals(2, store.getLiveSSTables().size());
diff --git 
a/test/unit/org/apache/cassandra/io/sstable/format/big/RowIndexEntryTest.java 
b/test/unit/org/apache/cassandra/io/sstable/format/big/RowIndexEntryTest.java
index 13fb3a7fc0..9a5673dc6e 100644
--- 
a/test/unit/org/apache/cassandra/io/sstable/format/big/RowIndexEntryTest.java
+++ 
b/test/unit/org/apache/cassandra/io/sstable/format/big/RowIndexEntryTest.java
@@ -135,7 +135,13 @@ public class RowIndexEntryTest extends CQLTester
             doubleSerializer.build(null, partitionKey(42L),
                                    Arrays.asList(cn(42), cn(43), cn(44)),
                                    0L);
-            assertEquals(doubleSerializer.rieOldSerialized, 
doubleSerializer.rieNewSerialized);
+
+            RowIndexEntry newRie = 
doubleSerializer.rieSerializer.deserialize(new 
DataInputBuffer(doubleSerializer.rieNewSerialized, false), 0);
+            Pre_C_11206_RowIndexEntry oldRie = 
doubleSerializer.oldSerializer.deserialize(new 
DataInputBuffer(doubleSerializer.rieOldSerialized, false));
+
+            assertEquals(oldRie.position, newRie.getPosition());
+            assertEquals(oldRie.deletionTime(), newRie.deletionTime());
+            assertEquals(oldRie.columnsIndex().size(), newRie.blockCount());
         }
 
         // partition with multiple IndexInfo
@@ -144,7 +150,13 @@ public class RowIndexEntryTest extends CQLTester
             doubleSerializer.build(null, partitionKey(42L),
                                    Arrays.asList(cn(42), cn(43), cn(44), 
cn(45), cn(46), cn(47), cn(48), cn(49), cn(50), cn(51)),
                                    0L);
-            assertEquals(doubleSerializer.rieOldSerialized, 
doubleSerializer.rieNewSerialized);
+
+            RowIndexEntry newRie = 
doubleSerializer.rieSerializer.deserialize(new 
DataInputBuffer(doubleSerializer.rieNewSerialized, false), 0);
+            Pre_C_11206_RowIndexEntry oldRie = 
doubleSerializer.oldSerializer.deserialize(new 
DataInputBuffer(doubleSerializer.rieOldSerialized, false));
+
+            assertEquals(oldRie.position, newRie.getPosition());
+            assertEquals(oldRie.deletionTime(), newRie.deletionTime());
+            assertEquals(oldRie.columnsIndex().size(), newRie.blockCount());
         }
     }
 
diff --git 
a/test/unit/org/apache/cassandra/transport/DeletionTimeDeSerTest.java 
b/test/unit/org/apache/cassandra/transport/DeletionTimeDeSerTest.java
new file mode 100644
index 0000000000..670b5daf09
--- /dev/null
+++ b/test/unit/org/apache/cassandra/transport/DeletionTimeDeSerTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.cassandra.transport;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.db.DeletionTime;
+import org.apache.cassandra.io.sstable.format.big.BigFormat;
+import org.apache.cassandra.io.util.DataInputBuffer;
+import org.apache.cassandra.io.util.DataOutputBuffer;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * We test here serialization of DTs and some of it's sentinel values 
+ *
+ */
+public class DeletionTimeDeSerTest
+{
+    @BeforeClass
+    public static void setupDD()
+    {
+        DatabaseDescriptor.daemonInitialization();
+    }
+    
+    @Test
+    public void testLDTDeserLive() throws IOException
+    {
+        assertEquals(DeletionTime.LIVE, serDeser(DeletionTime.LIVE));
+    }
+    
+    @Test
+    public void testLDTDeserLongMAX_VALUE() throws IOException
+    {
+        DeletionTime dt = DeletionTime.build(Long.MAX_VALUE, 2147483600);
+        assertEquals(dt, serDeser(dt));
+    }
+    
+    @Test
+    public void testLDTDeser() throws IOException
+    {
+        // Test Serialization in all bit possible positions
+        for (int i = 0; i < 63; i++)
+        {
+            DeletionTime dt = DeletionTime.build(1L << i, 2147483600);
+            assertEquals(dt, serDeser(dt));
+        }
+    }
+    
+    private DeletionTime serDeser(DeletionTime dt) throws IOException
+    {
+        DeletionTime readDt = null;
+        int offset = 2;
+
+        try(DataOutputBuffer out = new DataOutputBuffer(12)) // Long + Int = 8 
+ 4
+        {
+            
DeletionTime.getSerializer(BigFormat.getInstance().getLatestVersion()).serialize(dt,
 out);
+            
+            try(DataInputBuffer in = new DataInputBuffer(out.toByteArray()))
+            {
+                // Test *both* deserializers
+
+                readDt = 
DeletionTime.getSerializer(BigFormat.getInstance().getLatestVersion()).deserialize(in);
+
+                ByteBuffer bbOrig = out.buffer();
+                bbOrig.rewind();
+                ByteBuffer bb = ByteBuffer.allocate(bbOrig.capacity() + 
offset);
+                bb.position(offset);
+                bb.put(bbOrig);
+                DeletionTime readDt2 = 
DeletionTime.getSerializer(BigFormat.getInstance().getLatestVersion()).deserialize(bb,
 offset);
+                assertEquals(readDt, readDt2);
+            }
+        }
+        
+        return readDt;
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to