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

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

commit 32cfd477df72eab261eaf4a6f16aeb3a892b1e52
Merge: 17cb89208c 2ac701629b
Author: Jon Meredith <jonmered...@apache.org>
AuthorDate: Tue Apr 22 14:42:56 2025 -0600

    Merge branch 'cassandra-4.1' into cassandra-5.0

 CHANGES.txt                                        |  1 +
 src/java/org/apache/cassandra/db/LivenessInfo.java | 11 ++-
 src/java/org/apache/cassandra/db/rows/Cells.java   | 10 +++
 test/unit/org/apache/cassandra/db/CellTest.java    | 84 ++++++++++++++++++++++
 .../org/apache/cassandra/db/LivenessInfoTest.java  |  5 ++
 .../org/apache/cassandra/db/rows/RowsTest.java     | 54 ++++++++++++++
 6 files changed, 163 insertions(+), 2 deletions(-)

diff --cc CHANGES.txt
index 2e5aeed0b5,afb99c4d0b..462d3ed74f
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,35 -1,5 +1,36 @@@
 -4.1.9
 +5.0.5
   * Grant permission on keyspaces system_views and system_virtual_schema not 
possible (CASSANDRA-20171)
 + * Fix marking an SSTable as suspected and BufferPool leakage in case of a 
corrupted SSTable read during a compaction (CASSANDRA-20396)
 + * Introduce SSTableSimpleScanner for compaction (CASSANDRA-20092)
 + * Avoid purging deletions in RowFilter when reconciliation is required 
(CASSANDRA-20541)
 + * Fixed multiple single-node SAI query bugs relating to static columns 
(CASSANDRA-20338)
 + * Upgrade com.datastax.cassandra:cassandra-driver-core:3.11.5 to 
org.apache.cassandra:cassandra-driver-core:3.12.1 (CASSANDRA-17231)
 +Merged from 4.0:
++ * Updating a column with a new TTL but same expiration time is 
non-deterministic and causes repair mismatches. (CASSANDRA-20561)
 + * Avoid computing prepared statement size for unprepared batches 
(CASSANDRA-20556)
 + * Fix Dropwizard Meter causes timeouts when infrequently used 
(CASSANDRA-19332)
 +
 +
 +5.0.4
 + * Update netty to 4.1.119.Final and netty-tcnative to 2.0.70.Final 
(CASSANDRA-20314)
 + * Serialization can lose complex deletions in a mutation with multiple 
collections in a row (CASSANDRA-20449)
 + * Improve error messages when initializing auth classes (CASSANDRA-20368)
 + * Prioritize legacy 2i over SAI for columns with multiple indexes 
(CASSANDRA-20334)
 + * Ensure only offline tools can build IntervalTrees without first/last key 
fields (CASSANDRA-20407)
 + * Improve disk access patterns during compaction and range reads 
(CASSANDRA-15452)
 + * Improve IntervalTree build throughput (CASSANDRA-19596)
 + * Avoid limit on RFP fetch in the case of an unresolved static row 
(CASSANDRA-20323)
 + * Include materialized views to the output of DESCRIBE TABLE statements 
(CASSANDRA-20365)
 + * Heap and GC jvm flags improvements (CASSANDRA-20296)
 + * Fix unparseable YAML in default cassandra.yaml when uncommented for 
downstream tooling (CASSANDRA-20359)
 + * Avoid fetching entire partitions on unresolved static rows in RFP when no 
static column predicates exist (CASSANDRA-20243)
 + * Avoid indexing empty values for non-literals and types that do not allow 
them (CASSANDRA-20313)
 + * Fix incorrect results of min / max in-built functions on clustering 
columns in descending order (CASSANDRA-20295)
 + * Avoid possible consistency violations for SAI intersection queries over 
repaired index matches and multiple non-indexed column matches (CASSANDRA-20189)
 + * Skip check for DirectIO when initializing tools (CASSANDRA-20289)
 + * Avoid under-skipping during intersections when an iterator has mixed 
STATIC and WIDE keys (CASSANDRA-20258)
 + * Correct the default behavior of compareTo() when comparing WIDE and STATIC 
PrimaryKeys (CASSANDRA-20238)
 +Merged from 4.1:
   * Fix mixed mode paxos ttl commit hang (CASSANDRA-20514)
   * Fix paxos mixed mode infinite loop (CASSANDRA-20493)
   * Optionally skip exception logging on invalid legacy protocol magic 
exception (CASSANDRA-19483)
diff --cc test/unit/org/apache/cassandra/db/CellTest.java
index 3a9e0d0dc0,b4cca19920..b9ab25fe50
--- a/test/unit/org/apache/cassandra/db/CellTest.java
+++ b/test/unit/org/apache/cassandra/db/CellTest.java
@@@ -48,10 -39,10 +48,12 @@@ import org.apache.cassandra.schema.Keys
  import org.apache.cassandra.schema.TableMetadata;
  import org.apache.cassandra.serializers.MarshalException;
  import org.apache.cassandra.utils.ByteBufferUtil;
+ import org.apache.cassandra.utils.FBUtilities;
 +import org.assertj.core.api.Assertions;
 +import org.assertj.core.api.ThrowableAssert;
  
  import static java.util.Arrays.asList;
+ import static org.junit.Assert.assertEquals;
  
  public class CellTest
  {
@@@ -282,11 -276,91 +286,91 @@@
          Assert.assertEquals(-1, testExpiring("val", "b", 2, 1, null, "a", 
null, 1));
      }
  
+ 
+     public static void assertCellsEqual(Cell<?> cellA, Cell<?> cellB)
+     {
+         assertEquals(cellA.timestamp(), cellB.timestamp());
+         assertEquals(cellA.ttl(), cellB.ttl());
+         assertEquals(cellA.localDeletionTime(), cellB.localDeletionTime());
+         assertEquals(cellA.buffer(), cellB.buffer());
+     }
+ 
 -    static void checkCommutes(ColumnMetadata cmd, long timestamp, long 
tsDiff, int ttl, int ttlDiff, int nowInSeconds, int nowDiff)
++    static void checkCommutes(ColumnMetadata cmd, long timestamp, long 
tsDiff, int ttl, int ttlDiff, long nowInSeconds, int nowDiff)
+     {
+         long timestampA = timestamp;
+         long timestampB = timestampA + tsDiff;
+         int ttlA = ttl;
+         int ttlB = ttl + ttlDiff;
 -        int nowInSecsA = nowInSeconds;
 -        int nowInSecsB = nowInSecsA + nowDiff;
++        long nowInSecsA = nowInSeconds;
++        long nowInSecsB = nowInSecsA + nowDiff;
+         if (nowInSecsA < 0 || nowInSecsB < 0)
+             return;
+ 
+         Cell<?> cellA = ttlA == 0 ? BufferCell.tombstone(cmd, timestampA, 
nowInSecsA) :
+                         ttlA < 0 ? BufferCell.live(cmd, timestampA, 
TEST_VALUE) :
+                         BufferCell.expiring(cmd, timestampA, ttlA, 
nowInSecsA, TEST_VALUE);
+         Cell<?> cellB = ttlB == 0 ? BufferCell.tombstone(cmd, timestampB, 
nowInSecsB) :
+                         ttlB < 0 ? BufferCell.live(cmd, timestampB, 
TEST_VALUE) :
+                         BufferCell.expiring(cmd, timestampB, ttlB, 
nowInSecsB, TEST_VALUE);
+ 
+         Cell<?> cellAB = Cells.reconcile(cellA, cellB);
+         Cell<?> cellBA = Cells.reconcile(cellB, cellA);
+ 
+         assertCellsEqual(cellAB, cellBA);
+     }
+ 
+     @Test
+     public void checkSameValueDifferentLivenessCommutes()
+     {
+         ColumnMetadata cmd = fakeColumn("c", UTF8Type.instance);
+         long[] tsDiffs = new long[] {0L,
+                                      1L, // microsecond
+                                      1000L, // millisecond
+                                      1000000L, // second
+                                      60000000L}; // minute
+         int[] ttls = new int[] { -1, 0, 1, 3600, 24 * 3600, 7 * 24 * 3600, 60 
* 24 * 3600, 366 * 24 * 3600 };
+         int[] ttlDiffs = new int[] { 0, 1, 60, 3600, 24 * 3600, 7 * 24 * 
3600, 60 * 24 * 3600, 366 * 24 * 3600 };
+ 
 -        int nowInSeconds = FBUtilities.nowInSeconds();
++        long nowInSeconds = FBUtilities.nowInSeconds();
+         long timestamp = FBUtilities.timestampMicros();
+ 
+         for (long tsDiff: tsDiffs)
+         {
+             for (int ttl: ttls)
+             {
+                 for (int ttlDiff : ttlDiffs)
+                 {
+                     for (Integer nowDiff : ttlDiffs)
+                         checkCommutes(cmd, timestamp, tsDiff, ttl, ttlDiff, 
nowInSeconds, nowDiff);
+                 }
+             }
+         }
+     }
+ 
+     // Checks that reconciling a cell with a smaller TTL reconcile 
commutatively
+     // Similar to rewriting data retrieved with SELECT v, TTL(v), 
WRITETIMESTAMP(v) with
+     // INSERT SET v=? USING TTL ? AND TIMESTAMP ?
+     @Test
+     public void rewriteCellWithSmallerTTL()
+     {
+         ColumnMetadata cmd = fakeColumn("c", UTF8Type.instance);
+         int[] nowDiffs = new int[] { 0, 1, 60, 3600, 24 * 3600, 7 * 24 * 
3600, 60 * 24 * 3600, 366 * 24 * 3600 };
+         long timestamp = FBUtilities.timestampMicros();
 -        int nowInSeconds = FBUtilities.nowInSeconds();
++        long nowInSeconds = FBUtilities.nowInSeconds();
+         int ttl = 3600;
+ 
+         for (Integer nowDiff : nowDiffs)
+         {
+             checkCommutes(cmd, timestamp, 0L, ttl, -nowDiff, nowInSeconds, 
nowDiff);
+         }
+     }
+ 
+ 
      class SimplePurger implements DeletionPurger
      {
 -        private final int gcBefore;
 +        private final long gcBefore;
  
 -        public SimplePurger(int gcBefore)
 +        public SimplePurger(long gcBefore)
          {
              this.gcBefore = gcBefore;
          }
diff --cc test/unit/org/apache/cassandra/db/rows/RowsTest.java
index a4436da88a,47e42b2542..865d33a8b6
--- a/test/unit/org/apache/cassandra/db/rows/RowsTest.java
+++ b/test/unit/org/apache/cassandra/db/rows/RowsTest.java
@@@ -526,6 -522,58 +528,58 @@@ public class RowsTes
          Assert.assertEquals(0, merged.columns().size());
      }
  
+ 
 -    public static BufferCell expiringWithExpirationTime(ColumnMetadata 
column, long timestamp, int ttl, int localDeletionTime, ByteBuffer value)
++    public static BufferCell expiringWithExpirationTime(ColumnMetadata 
column, long timestamp, int ttl, long localDeletionTime, ByteBuffer value)
+     {
+         return expiringWithExpirationTime(column, timestamp, ttl, 
localDeletionTime, value, null);
+     }
+ 
 -    public static BufferCell expiringWithExpirationTime(ColumnMetadata 
column, long timestamp, int ttl, int localDeletionTime, ByteBuffer value, 
CellPath path)
++    public static BufferCell expiringWithExpirationTime(ColumnMetadata 
column, long timestamp, int ttl, long localDeletionTime, ByteBuffer value, 
CellPath path)
+     {
+         assert ttl != Cell.NO_TTL;
+         return new BufferCell(column, timestamp, ttl, localDeletionTime, 
value, path);
+     }
+ 
+     @Test
+     public void mergeRowsWithSameExpiryDifferentTTLCommutesLiveness()
+     {
 -        int now1 = FBUtilities.nowInSeconds();
++        long now1 = FBUtilities.nowInSeconds();
+         long ts1 = secondToTs(now1);
 -        int ldt = now1 + 1000;
++        long ldt = now1 + 1000;
+ 
+         Row.Builder r1Builder = BTreeRow.unsortedBuilder();
+         r1Builder.newRow(c1);
+         LivenessInfo originalLiveness = LivenessInfo.withExpirationTime(ts1, 
100, ldt);
+         r1Builder.addPrimaryKeyLivenessInfo(originalLiveness);
+ 
+         Row.Builder r2Builder = BTreeRow.unsortedBuilder();
+         r2Builder.newRow(c1);
+         LivenessInfo loweredTTL = LivenessInfo.withExpirationTime(ts1, 50, 
ldt);
+         r2Builder.addPrimaryKeyLivenessInfo(loweredTTL);
+ 
+         Cell<?> r2v = expiringWithExpirationTime(v, ts1, 75, ldt, BB1);
+         Cell<?> r2m2 = expiringWithExpirationTime(m, ts1, 50, ldt, BB1, 
CellPath.create(BB2));
+         Cell<?> r2m3 = expiringWithExpirationTime(m, ts1, 75, ldt, BB2, 
CellPath.create(BB3));
+         Cell<?> r2m4 = expiringWithExpirationTime(m, ts1, 100, ldt, BB3, 
CellPath.create(BB4));
+         List<Cell<?>> expectedCells = Lists.newArrayList(r2v, r2m2, r2m3, 
r2m4);
+ 
+         expectedCells.forEach(r1Builder::addCell);
+         expectedCells.forEach(r2Builder::addCell);
+ 
+         Row r1 = r1Builder.build();
+         Row r2 = r2Builder.build();
+ 
+         Row r1r2 = Rows.merge(r1, r2);
+         Row r2r1 = Rows.merge(r2, r1);
+ 
+         DiffListener mergedListener = new DiffListener();
+         Rows.diff(mergedListener, r1r2, r2r1);
+ 
+         mergedListener.liveness.forEach(pair -> 
Assert.assertEquals(pair.merged, pair.original));
+         mergedListener.cells.forEach(pair -> assertCellsEqual(pair.merged, 
pair.original));
+     }
+ 
+ 
      // Creates a dummy cell for a (regular) column for the provided name and 
without a cellPath.
      private static Cell<?> liveCell(ColumnMetadata name)
      {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to