Cell reconciliation should not depend on nowInSec

patch by Benedict; reviewed by Aleksey for CASSANDRA-14592


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e225c88a
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e225c88a
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e225c88a

Branch: refs/heads/trunk
Commit: e225c88a65f2e8091f8ea6212c291416674882a1
Parents: 6a473c4
Author: Benedict Elliott Smith <[email protected]>
Authored: Thu Jul 26 19:11:17 2018 +0100
Committer: Benedict Elliott Smith <[email protected]>
Committed: Thu Aug 23 14:14:07 2018 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 NEWS.txt                                        |   3 +
 .../apache/cassandra/cql3/UpdateParameters.java |   6 +-
 src/java/org/apache/cassandra/db/Conflicts.java |  88 ----------
 .../cassandra/db/PartitionRangeReadCommand.java |   2 +-
 .../org/apache/cassandra/db/SimpleBuilders.java |   2 +-
 .../db/SinglePartitionReadCommand.java          |   4 +-
 .../db/compaction/CompactionIterator.java       |  17 +-
 .../cassandra/db/compaction/Scrubber.java       |   2 +-
 .../db/partitions/AtomicBTreePartition.java     |   5 +-
 .../db/partitions/PartitionUpdate.java          |  12 +-
 .../UnfilteredPartitionIterators.java           |   8 +-
 .../org/apache/cassandra/db/rows/BTreeRow.java  |  27 +--
 .../org/apache/cassandra/db/rows/Cells.java     | 168 +++++++++++--------
 src/java/org/apache/cassandra/db/rows/Row.java  |  22 +--
 src/java/org/apache/cassandra/db/rows/Rows.java |  23 +--
 .../db/rows/UnfilteredRowIterators.java         |  23 ++-
 .../apache/cassandra/db/view/TableViews.java    |  15 +-
 .../cassandra/db/virtual/SimpleDataSet.java     |   2 +-
 .../cassandra/service/reads/DataResolver.java   |   2 +-
 test/unit/org/apache/cassandra/db/CellTest.java |   9 +-
 .../apache/cassandra/db/CounterCellTest.java    |  20 +--
 .../org/apache/cassandra/db/NativeCellTest.java |   2 +-
 .../apache/cassandra/db/ReadCommandTest.java    |   2 +-
 test/unit/org/apache/cassandra/db/RowTest.java  |   8 +-
 .../partition/PartitionImplementationTest.java  |   4 +-
 .../org/apache/cassandra/db/rows/RowsTest.java  |  26 +--
 .../rows/ThrottledUnfilteredIteratorTest.java   |   2 +-
 .../rows/UnfilteredRowIteratorsMergeTest.java   |   7 +-
 .../service/reads/DataResolverTest.java         |   8 +-
 .../cassandra/triggers/TriggerExecutorTest.java |   2 +-
 31 files changed, 210 insertions(+), 312 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index b34979a..75f41e8 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -18,6 +18,7 @@
  * Fix toDate function for timestamp arguments (CASSANDRA-14502)
  * Revert running dtests by default in circleci (CASSANDRA-14614)
  * Stream entire SSTables when possible (CASSANDRA-14556)
+ * Cell reconciliation should not depend on nowInSec (CASSANDRA-14592)
  * Add experimental support for Java 11 (CASSANDRA-9608)
  * Make PeriodicCommitLogService.blockWhenSyncLagsNanos configurable 
(CASSANDRA-14580)
  * Improve logging in MessageInHandler's constructor (CASSANDRA-14576)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/NEWS.txt
----------------------------------------------------------------------
diff --git a/NEWS.txt b/NEWS.txt
index 9d0da9b..aa8281c 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -97,6 +97,9 @@ New features
 
 Upgrading
 ---------
+    - Timestamp ties between values resolve differently: if either value has a 
TTL,
+      this value always wins. This is to provide consistent reconciliation 
before
+      and after the value expires into a tombstone.
     - Cassandra 4.0 removed support for COMPACT STORAGE tables. All Compact 
Tables
       have to be migrated using `ALTER ... DROP COMPACT STORAGE` statement in 
3.0/3.11.
       Cassandra starting 4.0 will not start if flags indicate that the table 
is non-CQL.

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/cql3/UpdateParameters.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/UpdateParameters.java 
b/src/java/org/apache/cassandra/cql3/UpdateParameters.java
index ba11a89..9d6f2e9 100644
--- a/src/java/org/apache/cassandra/cql3/UpdateParameters.java
+++ b/src/java/org/apache/cassandra/cql3/UpdateParameters.java
@@ -95,13 +95,13 @@ public class UpdateParameters
         if (clustering == Clustering.STATIC_CLUSTERING)
         {
             if (staticBuilder == null)
-                staticBuilder = BTreeRow.unsortedBuilder(nowInSec);
+                staticBuilder = BTreeRow.unsortedBuilder();
             builder = staticBuilder;
         }
         else
         {
             if (regularBuilder == null)
-                regularBuilder = BTreeRow.unsortedBuilder(nowInSec);
+                regularBuilder = BTreeRow.unsortedBuilder();
             builder = regularBuilder;
         }
 
@@ -230,7 +230,7 @@ public class UpdateParameters
         if (prefetchedRow == null)
             return pendingMutations;
 
-        return Rows.merge(prefetchedRow, pendingMutations, nowInSec)
+        return Rows.merge(prefetchedRow, pendingMutations)
                    .purge(DeletionPurger.PURGE_ALL, nowInSec, 
metadata.enforceStrictLiveness());
     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/Conflicts.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Conflicts.java 
b/src/java/org/apache/cassandra/db/Conflicts.java
deleted file mode 100644
index 9e8bd9a..0000000
--- a/src/java/org/apache/cassandra/db/Conflicts.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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.db;
-
-import java.nio.ByteBuffer;
-
-import org.apache.cassandra.db.context.CounterContext;
-
-public abstract class Conflicts
-{
-    private Conflicts() {}
-
-    public enum Resolution { LEFT_WINS, MERGE, RIGHT_WINS };
-
-    public static Resolution resolveRegular(long leftTimestamp,
-                                            boolean leftLive,
-                                            int leftLocalDeletionTime,
-                                            ByteBuffer leftValue,
-                                            long rightTimestamp,
-                                            boolean rightLive,
-                                            int rightLocalDeletionTime,
-                                            ByteBuffer rightValue)
-    {
-        if (leftTimestamp != rightTimestamp)
-            return leftTimestamp < rightTimestamp ? Resolution.RIGHT_WINS : 
Resolution.LEFT_WINS;
-
-        if (leftLive != rightLive)
-            return leftLive ? Resolution.RIGHT_WINS : Resolution.LEFT_WINS;
-
-        int c = leftValue.compareTo(rightValue);
-        if (c < 0)
-            return Resolution.RIGHT_WINS;
-        else if (c > 0)
-            return Resolution.LEFT_WINS;
-
-        // Prefer the longest ttl if relevant
-        return leftLocalDeletionTime < rightLocalDeletionTime ? 
Resolution.RIGHT_WINS : Resolution.LEFT_WINS;
-    }
-
-    public static Resolution resolveCounter(long leftTimestamp,
-                                            boolean leftLive,
-                                            ByteBuffer leftValue,
-                                            long rightTimestamp,
-                                            boolean rightLive,
-                                            ByteBuffer rightValue)
-    {
-        // No matter what the counter cell's timestamp is, a tombstone always 
takes precedence. See CASSANDRA-7346.
-        if (!leftLive)
-            // left is a tombstone: it has precedence over right if either 
right is not a tombstone, or left has a greater timestamp
-            return rightLive || leftTimestamp > rightTimestamp ? 
Resolution.LEFT_WINS : Resolution.RIGHT_WINS;
-
-        // If right is a tombstone, since left isn't one, it has precedence
-        if (!rightLive)
-            return Resolution.RIGHT_WINS;
-
-        // Handle empty values. Counters can't truly have empty values, but we 
can have a counter cell that temporarily
-        // has one on read if the column for the cell is not queried by the 
user due to the optimization of #10657. We
-        // thus need to handle this (see #11726 too).
-        if (!leftValue.hasRemaining())
-            return rightValue.hasRemaining() || leftTimestamp > rightTimestamp 
? Resolution.LEFT_WINS : Resolution.RIGHT_WINS;
-
-        if (!rightValue.hasRemaining())
-            return Resolution.RIGHT_WINS;
-
-        return Resolution.MERGE;
-    }
-
-    public static ByteBuffer mergeCounterValues(ByteBuffer left, ByteBuffer 
right)
-    {
-        return CounterContext.instance().merge(left, right);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java 
b/src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java
index c312acc..2bfb434 100644
--- a/src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java
+++ b/src/java/org/apache/cassandra/db/PartitionRangeReadCommand.java
@@ -259,7 +259,7 @@ public class PartitionRangeReadCommand extends ReadCommand 
implements PartitionR
             }
             // iterators can be empty for offline tools
             return iterators.isEmpty() ? 
EmptyIterators.unfilteredPartition(metadata())
-                                       : 
checkCacheFilter(UnfilteredPartitionIterators.mergeLazily(iterators, 
nowInSec()), cfs);
+                                       : 
checkCacheFilter(UnfilteredPartitionIterators.mergeLazily(iterators), cfs);
         }
         catch (RuntimeException | Error e)
         {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/SimpleBuilders.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/SimpleBuilders.java 
b/src/java/org/apache/cassandra/db/SimpleBuilders.java
index 3520d97..0fb40a7 100644
--- a/src/java/org/apache/cassandra/db/SimpleBuilders.java
+++ b/src/java/org/apache/cassandra/db/SimpleBuilders.java
@@ -323,7 +323,7 @@ public abstract class SimpleBuilders
         public RowBuilder(TableMetadata metadata, Object... clusteringColumns)
         {
             this.metadata = metadata;
-            this.builder = 
BTreeRow.unsortedBuilder(FBUtilities.nowInSeconds());
+            this.builder = BTreeRow.unsortedBuilder();
 
             this.builder.newRow(makeClustering(metadata, clusteringColumns));
         }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java 
b/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java
index 1fdb11f..ba87996 100644
--- a/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java
+++ b/src/java/org/apache/cassandra/db/SinglePartitionReadCommand.java
@@ -718,7 +718,7 @@ public class SinglePartitionReadCommand extends ReadCommand 
implements SinglePar
                                                        
SSTableReadMetricsCollector metricsCollector)
     {
         @SuppressWarnings("resource") //  Closed through the closing of the 
result of the caller method.
-        UnfilteredRowIterator merged = UnfilteredRowIterators.merge(iterators, 
nowInSec());
+        UnfilteredRowIterator merged = UnfilteredRowIterators.merge(iterators);
 
         if (!merged.isEmpty())
         {
@@ -882,7 +882,7 @@ public class SinglePartitionReadCommand extends ReadCommand 
implements SinglePar
         if (result == null)
             return ImmutableBTreePartition.create(iter, maxRows);
 
-        try (UnfilteredRowIterator merged = 
UnfilteredRowIterators.merge(Arrays.asList(iter, 
result.unfilteredIterator(columnFilter(), Slices.ALL, filter.isReversed())), 
nowInSec()))
+        try (UnfilteredRowIterator merged = 
UnfilteredRowIterators.merge(Arrays.asList(iter, 
result.unfilteredIterator(columnFilter(), Slices.ALL, filter.isReversed()))))
         {
             return ImmutableBTreePartition.create(merged, maxRows);
         }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/compaction/CompactionIterator.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/compaction/CompactionIterator.java 
b/src/java/org/apache/cassandra/db/compaction/CompactionIterator.java
index c9d7e52..f8e32a8 100644
--- a/src/java/org/apache/cassandra/db/compaction/CompactionIterator.java
+++ b/src/java/org/apache/cassandra/db/compaction/CompactionIterator.java
@@ -102,8 +102,8 @@ public class CompactionIterator extends 
CompactionInfo.Holder implements Unfilte
 
         UnfilteredPartitionIterator merged = scanners.isEmpty()
                                            ? 
EmptyIterators.unfilteredPartition(controller.cfs.metadata())
-                                           : 
UnfilteredPartitionIterators.merge(scanners, nowInSec, listener());
-        merged = Transformation.apply(merged, new GarbageSkipper(controller, 
nowInSec));
+                                           : 
UnfilteredPartitionIterators.merge(scanners, listener());
+        merged = Transformation.apply(merged, new GarbageSkipper(controller));
         merged = Transformation.apply(merged, new Purger(controller, 
nowInSec));
         compacted = Transformation.apply(merged, new 
AbortableUnfilteredPartitionTransformation(this));
     }
@@ -322,7 +322,6 @@ public class CompactionIterator extends 
CompactionInfo.Holder implements Unfilte
         final DeletionTime partitionLevelDeletion;
         final Row staticRow;
         final ColumnFilter cf;
-        final int nowInSec;
         final TableMetadata metadata;
         final boolean cellLevelGC;
 
@@ -340,15 +339,13 @@ public class CompactionIterator extends 
CompactionInfo.Holder implements Unfilte
          *
          * @param dataSource The input row. The result is a filtered version 
of this.
          * @param tombSource Tombstone source, i.e. iterator used to identify 
deleted data in the input row.
-         * @param nowInSec Current time, used in choosing the winner when cell 
expiration is involved.
          * @param cellLevelGC If false, the iterator will only look at 
row-level deletion times and tombstones.
          *                    If true, deleted or overwritten cells within a 
surviving row will also be removed.
          */
-        protected GarbageSkippingUnfilteredRowIterator(UnfilteredRowIterator 
dataSource, UnfilteredRowIterator tombSource, int nowInSec, boolean cellLevelGC)
+        protected GarbageSkippingUnfilteredRowIterator(UnfilteredRowIterator 
dataSource, UnfilteredRowIterator tombSource, boolean cellLevelGC)
         {
             super(dataSource);
             this.tombSource = tombSource;
-            this.nowInSec = nowInSec;
             this.cellLevelGC = cellLevelGC;
             metadata = dataSource.metadata();
             cf = ColumnFilter.all(metadata);
@@ -453,7 +450,7 @@ public class CompactionIterator extends 
CompactionInfo.Holder implements Unfilte
         {
             if (cellLevelGC)
             {
-                return Rows.removeShadowedCells(dataRow, tombRow, 
activeDeletionTime, nowInSec);
+                return Rows.removeShadowedCells(dataRow, tombRow, 
activeDeletionTime);
             }
             else
             {
@@ -512,14 +509,12 @@ public class CompactionIterator extends 
CompactionInfo.Holder implements Unfilte
      */
     private static class GarbageSkipper extends 
Transformation<UnfilteredRowIterator>
     {
-        final int nowInSec;
         final CompactionController controller;
         final boolean cellLevelGC;
 
-        private GarbageSkipper(CompactionController controller, int nowInSec)
+        private GarbageSkipper(CompactionController controller)
         {
             this.controller = controller;
-            this.nowInSec = nowInSec;
             cellLevelGC = controller.tombstoneOption == TombstoneOption.CELL;
         }
 
@@ -540,7 +535,7 @@ public class CompactionIterator extends 
CompactionInfo.Holder implements Unfilte
             if (iters.isEmpty())
                 return partition;
 
-            return new GarbageSkippingUnfilteredRowIterator(partition, 
UnfilteredRowIterators.merge(iters, nowInSec), nowInSec, cellLevelGC);
+            return new GarbageSkippingUnfilteredRowIterator(partition, 
UnfilteredRowIterators.merge(iters), cellLevelGC);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/compaction/Scrubber.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/compaction/Scrubber.java 
b/src/java/org/apache/cassandra/db/compaction/Scrubber.java
index 8a7c53b..f97b693 100644
--- a/src/java/org/apache/cassandra/db/compaction/Scrubber.java
+++ b/src/java/org/apache/cassandra/db/compaction/Scrubber.java
@@ -548,7 +548,7 @@ public class Scrubber implements Closeable
                     }
 
                     // Duplicate row, merge it.
-                    next = Rows.merge((Row) next, (Row) peek, 
FBUtilities.nowInSeconds());
+                    next = Rows.merge((Row) next, (Row) peek);
                 }
             }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/partitions/AtomicBTreePartition.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/partitions/AtomicBTreePartition.java 
b/src/java/org/apache/cassandra/db/partitions/AtomicBTreePartition.java
index 6adebfd..8c62642 100644
--- a/src/java/org/apache/cassandra/db/partitions/AtomicBTreePartition.java
+++ b/src/java/org/apache/cassandra/db/partitions/AtomicBTreePartition.java
@@ -31,7 +31,6 @@ import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.filter.ColumnFilter;
 import org.apache.cassandra.db.rows.*;
 import org.apache.cassandra.index.transactions.UpdateTransaction;
-import org.apache.cassandra.utils.FBUtilities;
 import org.apache.cassandra.utils.ObjectSizes;
 import org.apache.cassandra.utils.SearchIterator;
 import org.apache.cassandra.utils.btree.BTree;
@@ -306,7 +305,6 @@ public final class AtomicBTreePartition extends 
AtomicBTreePartitionBase
         final MemtableAllocator allocator;
         final OpOrder.Group writeOp;
         final UpdateTransaction indexer;
-        final int nowInSec;
         Holder ref;
         Row.Builder regularBuilder;
         long dataSize;
@@ -320,7 +318,6 @@ public final class AtomicBTreePartition extends 
AtomicBTreePartitionBase
             this.allocator = allocator;
             this.writeOp = writeOp;
             this.indexer = indexer;
-            this.nowInSec = FBUtilities.nowInSeconds();
         }
 
         private Row.Builder builder(Clustering clustering)
@@ -351,7 +348,7 @@ public final class AtomicBTreePartition extends 
AtomicBTreePartitionBase
         public Row apply(Row existing, Row update)
         {
             Row.Builder builder = builder(existing.clustering());
-            colUpdateTimeDelta = Math.min(colUpdateTimeDelta, 
Rows.merge(existing, update, builder, nowInSec));
+            colUpdateTimeDelta = Math.min(colUpdateTimeDelta, 
Rows.merge(existing, update, builder));
 
             Row reconciled = builder.build();
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/partitions/PartitionUpdate.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/partitions/PartitionUpdate.java 
b/src/java/org/apache/cassandra/db/partitions/PartitionUpdate.java
index 99220ca..31f68f4 100644
--- a/src/java/org/apache/cassandra/db/partitions/PartitionUpdate.java
+++ b/src/java/org/apache/cassandra/db/partitions/PartitionUpdate.java
@@ -289,9 +289,8 @@ public class PartitionUpdate extends AbstractBTreePartition
         if (size == 1)
             return Iterables.getOnlyElement(updates);
 
-        int nowInSecs = FBUtilities.nowInSeconds();
         List<UnfilteredRowIterator> asIterators = Lists.transform(updates, 
AbstractBTreePartition::unfilteredIterator);
-        return fromIterator(UnfilteredRowIterators.merge(asIterators, 
nowInSecs), ColumnFilter.all(updates.get(0).metadata()));
+        return fromIterator(UnfilteredRowIterators.merge(asIterators), 
ColumnFilter.all(updates.get(0).metadata()));
     }
 
     // We override this, because the version in the super-class calls 
holder(), which build the update preventing
@@ -716,7 +715,6 @@ public class PartitionUpdate extends AbstractBTreePartition
         private final boolean canHaveShadowedData;
         private Object[] tree = BTree.empty();
         private final BTree.Builder<Row> rowBuilder;
-        private final int createdAtInSec = FBUtilities.nowInSeconds();
         private Row staticRow = Rows.EMPTY_STATIC_ROW;
         private final RegularAndStaticColumns columns;
         private boolean isBuilt = false;
@@ -800,7 +798,7 @@ public class PartitionUpdate extends AbstractBTreePartition
                 assert columns().statics.containsAll(row.columns()) : 
columns().statics + " is not superset of " + row.columns();
                 staticRow = staticRow.isEmpty()
                             ? row
-                            : Rows.merge(staticRow, row, createdAtInSec);
+                            : Rows.merge(staticRow, row);
             }
             else
             {
@@ -837,7 +835,7 @@ public class PartitionUpdate extends AbstractBTreePartition
             assert !isBuilt : "A PartitionUpdate.Builder should only get built 
once";
             Object[] add = rowBuilder.build();
             Object[] merged = BTree.<Row>merge(tree, add, metadata.comparator,
-                                               UpdateFunction.Simple.of((a, b) 
-> Rows.merge(a, b, createdAtInSec)));
+                                               
UpdateFunction.Simple.of(Rows::merge));
 
             EncodingStats newStats = 
EncodingStats.Collector.collect(staticRow, BTree.iterator(merged), 
deletionInfo);
 
@@ -866,8 +864,7 @@ public class PartitionUpdate extends AbstractBTreePartition
         private BTree.Builder<Row> rowBuilder(int initialCapacity)
         {
             return BTree.<Row>builder(metadata.comparator, initialCapacity)
-                   .setQuickResolver((a, b) ->
-                                     Rows.merge(a, b, createdAtInSec));
+                   .setQuickResolver(Rows::merge);
         }
         /**
          * Modify this update to set every timestamp for live data to {@code 
newTimestamp} and
@@ -899,7 +896,6 @@ public class PartitionUpdate extends AbstractBTreePartition
                    ", key=" + key +
                    ", deletionInfo=" + deletionInfo +
                    ", canHaveShadowedData=" + canHaveShadowedData +
-                   ", createdAtInSec=" + createdAtInSec +
                    ", staticRow=" + staticRow +
                    ", columns=" + columns +
                    ", isBuilt=" + isBuilt +

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/partitions/UnfilteredPartitionIterators.java
----------------------------------------------------------------------
diff --git 
a/src/java/org/apache/cassandra/db/partitions/UnfilteredPartitionIterators.java 
b/src/java/org/apache/cassandra/db/partitions/UnfilteredPartitionIterators.java
index 7b1259c..24c4d4a 100644
--- 
a/src/java/org/apache/cassandra/db/partitions/UnfilteredPartitionIterators.java
+++ 
b/src/java/org/apache/cassandra/db/partitions/UnfilteredPartitionIterators.java
@@ -112,7 +112,7 @@ public abstract class UnfilteredPartitionIterators
     }
 
     @SuppressWarnings("resource")
-    public static UnfilteredPartitionIterator merge(final List<? extends 
UnfilteredPartitionIterator> iterators, final int nowInSec, final MergeListener 
listener)
+    public static UnfilteredPartitionIterator merge(final List<? extends 
UnfilteredPartitionIterator> iterators, final MergeListener listener)
     {
         assert listener != null;
         assert !iterators.isEmpty();
@@ -155,7 +155,7 @@ public abstract class UnfilteredPartitionIterators
                     }
                 }
 
-                return UnfilteredRowIterators.merge(toMerge, nowInSec, 
rowListener);
+                return UnfilteredRowIterators.merge(toMerge, rowListener);
             }
 
             protected void onKeyChange()
@@ -193,7 +193,7 @@ public abstract class UnfilteredPartitionIterators
     }
 
     @SuppressWarnings("resource")
-    public static UnfilteredPartitionIterator mergeLazily(final List<? extends 
UnfilteredPartitionIterator> iterators, final int nowInSec)
+    public static UnfilteredPartitionIterator mergeLazily(final List<? extends 
UnfilteredPartitionIterator> iterators)
     {
         assert !iterators.isEmpty();
 
@@ -217,7 +217,7 @@ public abstract class UnfilteredPartitionIterators
                 {
                     protected UnfilteredRowIterator initializeIterator()
                     {
-                        return UnfilteredRowIterators.merge(toMerge, nowInSec);
+                        return UnfilteredRowIterators.merge(toMerge);
                     }
                 };
             }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/rows/BTreeRow.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/BTreeRow.java 
b/src/java/org/apache/cassandra/db/rows/BTreeRow.java
index deeeeca..fff7750 100644
--- a/src/java/org/apache/cassandra/db/rows/BTreeRow.java
+++ b/src/java/org/apache/cassandra/db/rows/BTreeRow.java
@@ -451,9 +451,9 @@ public class BTreeRow extends AbstractRow
         return new Builder(true);
     }
 
-    public static Row.Builder unsortedBuilder(int nowInSec)
+    public static Row.Builder unsortedBuilder()
     {
-        return new Builder(false, nowInSec);
+        return new Builder(false);
     }
 
     // This is only used by PartitionUpdate.CounterMark but other uses should 
be avoided as much as possible as it breaks our general
@@ -605,11 +605,7 @@ public class BTreeRow extends AbstractRow
         // converts a run of Cell with equal column into a ColumnData
         private static class CellResolver implements BTree.Builder.Resolver
         {
-            final int nowInSec;
-            private CellResolver(int nowInSec)
-            {
-                this.nowInSec = nowInSec;
-            }
+            static final CellResolver instance = new CellResolver();
 
             public ColumnData resolve(Object[] cells, int lb, int ub)
             {
@@ -617,9 +613,8 @@ public class BTreeRow extends AbstractRow
                 ColumnMetadata column = cell.column;
                 if (cell.column.isSimple())
                 {
-                    assert lb + 1 == ub || nowInSec != Integer.MIN_VALUE;
                     while (++lb < ub)
-                        cell = Cells.reconcile(cell, (Cell) cells[lb], 
nowInSec);
+                        cell = Cells.reconcile(cell, (Cell) cells[lb]);
                     return cell;
                 }
 
@@ -652,7 +647,7 @@ public class BTreeRow extends AbstractRow
                     {
                         if (previous != null && 
column.cellComparator().compare(previous, c) == 0)
                         {
-                            c = Cells.reconcile(previous, c, nowInSec);
+                            c = Cells.reconcile(previous, c);
                             buildFrom.set(buildFrom.size() - 1, c);
                         }
                         else
@@ -666,28 +661,21 @@ public class BTreeRow extends AbstractRow
                 Object[] btree = BTree.build(buildFrom, UpdateFunction.noOp());
                 return new ComplexColumnData(column, btree, deletion);
             }
-
         }
+
         protected Clustering clustering;
         protected LivenessInfo primaryKeyLivenessInfo = LivenessInfo.EMPTY;
         protected Deletion deletion = Deletion.LIVE;
 
         private final boolean isSorted;
         private BTree.Builder<Cell> cells_;
-        private final CellResolver resolver;
         private boolean hasComplex = false;
 
         // For complex column at index i of 'columns', we store at 
complexDeletions[i] its complex deletion.
 
         protected Builder(boolean isSorted)
         {
-            this(isSorted, Integer.MIN_VALUE);
-        }
-
-        protected Builder(boolean isSorted, int nowInSecs)
-        {
             cells_ = null;
-            resolver = new CellResolver(nowInSecs);
             this.isSorted = isSorted;
         }
 
@@ -707,7 +695,6 @@ public class BTreeRow extends AbstractRow
             primaryKeyLivenessInfo = builder.primaryKeyLivenessInfo;
             deletion = builder.deletion;
             cells_ = builder.cells_ == null ? null : builder.cells_.copy();
-            resolver = builder.resolver;
             isSorted = builder.isSorted;
             hasComplex = builder.hasComplex;
         }
@@ -783,7 +770,7 @@ public class BTreeRow extends AbstractRow
             // we can avoid resolving if we're sorted and have no complex 
values
             // (because we'll only have unique simple cells, which are already 
in their final condition)
             if (!isSorted | hasComplex)
-                getCells().resolve(resolver);
+                getCells().resolve(CellResolver.instance);
             Object[] btree = getCells().build();
 
             if (deletion.isShadowedBy(primaryKeyLivenessInfo))

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/rows/Cells.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/Cells.java 
b/src/java/org/apache/cassandra/db/rows/Cells.java
index 7f2772c..45d69e8 100644
--- a/src/java/org/apache/cassandra/db/rows/Cells.java
+++ b/src/java/org/apache/cassandra/db/rows/Cells.java
@@ -21,8 +21,8 @@ import java.nio.ByteBuffer;
 import java.util.Comparator;
 import java.util.Iterator;
 
+import org.apache.cassandra.db.context.CounterContext;
 import org.apache.cassandra.schema.ColumnMetadata;
-import org.apache.cassandra.db.Conflicts;
 import org.apache.cassandra.db.DeletionTime;
 import org.apache.cassandra.db.partitions.PartitionStatisticsCollector;
 
@@ -66,9 +66,6 @@ public abstract class Cells
      * @param deletion the deletion time that applies to the cells being 
considered.
      * This deletion time may delete both {@code existing} or {@code update}.
      * @param builder the row builder to which the result of the 
reconciliation is written.
-     * @param nowInSec the current time in seconds (which plays a role during 
reconciliation
-     * because deleted cells always have precedence on timestamp equality and 
deciding if a
-     * cell is a live or not depends on the current time due to expiring 
cells).
      *
      * @return the timestamp delta between existing and update, or {@code 
Long.MAX_VALUE} if one
      * of them is {@code null} or deleted by {@code deletion}).
@@ -76,8 +73,7 @@ public abstract class Cells
     public static long reconcile(Cell existing,
                                  Cell update,
                                  DeletionTime deletion,
-                                 Row.Builder builder,
-                                 int nowInSec)
+                                 Row.Builder builder)
     {
         existing = existing == null || deletion.deletes(existing) ? null : 
existing;
         update = update == null || deletion.deletes(update) ? null : update;
@@ -94,7 +90,7 @@ public abstract class Cells
             return Long.MAX_VALUE;
         }
 
-        Cell reconciled = reconcile(existing, update, nowInSec);
+        Cell reconciled = reconcile(existing, update);
         builder.addCell(reconciled);
 
         return Math.abs(existing.timestamp() - update.timestamp());
@@ -111,59 +107,107 @@ public abstract class Cells
      *
      * @param c1 the first cell participating in the reconciliation.
      * @param c2 the second cell participating in the reconciliation.
-     * @param nowInSec the current time in seconds (which plays a role during 
reconciliation
-     * because deleted cells always have precedence on timestamp equality and 
deciding if a
-     * cell is a live or not depends on the current time due to expiring 
cells).
      *
      * @return a cell corresponding to the reconciliation of {@code c1} and 
{@code c2}.
      * For non-counter cells, this will always be either {@code c1} or {@code 
c2}, but for
      * counter cells this can be a newly allocated cell.
      */
-    public static Cell reconcile(Cell c1, Cell c2, int nowInSec)
+    public static Cell reconcile(Cell c1, Cell c2)
     {
-        if (c1 == null)
-            return c2 == null ? null : c2;
-        if (c2 == null)
-            return c1;
+        if (c1 == null || c2 == null)
+            return c2 == null ? c1 : c2;
 
         if (c1.isCounterCell() || c2.isCounterCell())
+            return resolveCounter(c1, c2);
+
+        return resolveRegular(c1, c2);
+    }
+
+    private static Cell resolveRegular(Cell left, Cell right)
+    {
+        long leftTimestamp = left.timestamp();
+        long rightTimestamp = right.timestamp();
+        if (leftTimestamp != rightTimestamp)
+            return leftTimestamp > rightTimestamp ? left : right;
+
+        int leftLocalDeletionTime = left.localDeletionTime();
+        int rightLocalDeletionTime = right.localDeletionTime();
+
+        boolean leftIsExpiringOrTombstone = leftLocalDeletionTime != 
Cell.NO_DELETION_TIME;
+        boolean rightIsExpiringOrTombstone = rightLocalDeletionTime != 
Cell.NO_DELETION_TIME;
+
+        if (leftIsExpiringOrTombstone | rightIsExpiringOrTombstone)
         {
-            Conflicts.Resolution res = Conflicts.resolveCounter(c1.timestamp(),
-                                                                
c1.isLive(nowInSec),
-                                                                c1.value(),
-                                                                c2.timestamp(),
-                                                                
c2.isLive(nowInSec),
-                                                                c2.value());
+            // Tombstones always win reconciliation with live cells of the 
same timstamp
+            // CASSANDRA-14592: for consistency of reconciliation, regardless 
of system clock at time of reconciliation
+            // this requires us to treat expiring cells (which will become 
tombstones at some future date) the same wrt regular cells
+            if (leftIsExpiringOrTombstone != rightIsExpiringOrTombstone)
+                return leftIsExpiringOrTombstone ? left : right;
 
-            switch (res)
-            {
-                case LEFT_WINS: return c1;
-                case RIGHT_WINS: return c2;
-                default:
-                    ByteBuffer merged = 
Conflicts.mergeCounterValues(c1.value(), c2.value());
-                    long timestamp = Math.max(c1.timestamp(), c2.timestamp());
+            // for most historical consistency, we still prefer tombstones 
over expiring cells.
+            // While this leads to the an inconsistency over which is chosen
+            // (i.e. before expiry, the pure tombstone; after expiry, 
whichever is more recent)
+            // this inconsistency has no user-visible distinction, as at this 
point they are both logically tombstones
+            // (the only possible difference is the time at which the cells 
become purgeable)
+            boolean leftIsTombstone = !left.isExpiring(); // !isExpiring() == 
isTombstone(), but does not need to consider localDeletionTime()
+            boolean rightIsTombstone = !right.isExpiring();
+            if (leftIsTombstone != rightIsTombstone)
+                return leftIsTombstone ? left : right;
 
-                    // We save allocating a new cell object if it turns out 
that one cell was
-                    // a complete superset of the other
-                    if (merged == c1.value() && timestamp == c1.timestamp())
-                        return c1;
-                    else if (merged == c2.value() && timestamp == 
c2.timestamp())
-                        return c2;
-                    else // merge clocks and timestamps.
-                        return new BufferCell(c1.column(), timestamp, 
Cell.NO_TTL, Cell.NO_DELETION_TIME, merged, c1.path());
-            }
+            // ==> (leftIsExpiring && rightIsExpiring) or (leftIsTombstone && 
rightIsTombstone)
+            // if both are expiring, we do not want to consult the value bytes 
if we can avoid it, as like with C-14592
+            // the value bytes implicitly depend on the system time at 
reconciliation, as a
+            // would otherwise always win (unless it had an empty value), 
until it expired and was translated to a tombstone
+            if (leftLocalDeletionTime != rightLocalDeletionTime)
+                return leftLocalDeletionTime > rightLocalDeletionTime ? left : 
right;
+        }
+
+        ByteBuffer leftValue = left.value();
+        ByteBuffer rightValue = right.value();
+        return leftValue.compareTo(rightValue) >= 0 ? left : right;
+    }
+
+    private static Cell resolveCounter(Cell left, Cell right)
+    {
+        long leftTimestamp = left.timestamp();
+        long rightTimestamp = right.timestamp();
+
+        boolean leftIsTombstone = left.isTombstone();
+        boolean rightIsTombstone = right.isTombstone();
+
+        if (leftIsTombstone | rightIsTombstone)
+        {
+            // No matter what the counter cell's timestamp is, a tombstone 
always takes precedence. See CASSANDRA-7346.
+            assert leftIsTombstone != rightIsTombstone;
+            return leftIsTombstone ? left : right;
         }
 
-        Conflicts.Resolution res = Conflicts.resolveRegular(c1.timestamp(),
-                                                            
c1.isLive(nowInSec),
-                                                            
c1.localDeletionTime(),
-                                                            c1.value(),
-                                                            c2.timestamp(),
-                                                            
c2.isLive(nowInSec),
-                                                            
c2.localDeletionTime(),
-                                                            c2.value());
-        assert res != Conflicts.Resolution.MERGE;
-        return res == Conflicts.Resolution.LEFT_WINS ? c1 : c2;
+        ByteBuffer leftValue = left.value();
+        ByteBuffer rightValue = right.value();
+
+        // Handle empty values. Counters can't truly have empty values, but we 
can have a counter cell that temporarily
+        // has one on read if the column for the cell is not queried by the 
user due to the optimization of #10657. We
+        // thus need to handle this (see #11726 too).
+        boolean leftIsEmpty = !leftValue.hasRemaining();
+        boolean rightIsEmpty = !rightValue.hasRemaining();
+        if (leftIsEmpty || rightIsEmpty)
+        {
+            if (leftIsEmpty != rightIsEmpty)
+                return leftIsEmpty ? left : right;
+            return leftTimestamp > rightTimestamp ? left : right;
+        }
+
+        ByteBuffer merged = CounterContext.instance().merge(leftValue, 
rightValue);
+        long timestamp = Math.max(leftTimestamp, rightTimestamp);
+
+        // We save allocating a new cell object if it turns out that one cell 
was
+        // a complete superset of the other
+        if (merged == leftValue && timestamp == leftTimestamp)
+            return left;
+        else if (merged == rightValue && timestamp == rightTimestamp)
+            return right;
+        else // merge clocks and timestamps.
+            return new BufferCell(left.column(), timestamp, Cell.NO_TTL, 
Cell.NO_DELETION_TIME, merged, left.path());
     }
 
     /**
@@ -187,9 +231,6 @@ public abstract class Cells
      * @param deletion the deletion time that applies to the cells being 
considered.
      * This deletion time may delete cells in both {@code existing} and {@code 
update}.
      * @param builder the row build to which the result of the reconciliation 
is written.
-     * @param nowInSec the current time in seconds (which plays a role during 
reconciliation
-     * because deleted cells always have precedence on timestamp equality and 
deciding if a
-     * cell is a live or not depends on the current time due to expiring 
cells).
      *
      * @return the smallest timestamp delta between corresponding cells from 
existing and update. A
      * timestamp delta being computed as the difference between a cell from 
{@code update} and the
@@ -201,8 +242,7 @@ public abstract class Cells
                                         Iterator<Cell> existing,
                                         Iterator<Cell> update,
                                         DeletionTime deletion,
-                                        Row.Builder builder,
-                                        int nowInSec)
+                                        Row.Builder builder)
     {
         Comparator<CellPath> comparator = column.cellPathComparator();
         Cell nextExisting = getNext(existing);
@@ -215,17 +255,17 @@ public abstract class Cells
                      : comparator.compare(nextExisting.path(), 
nextUpdate.path()));
             if (cmp < 0)
             {
-                reconcile(nextExisting, null, deletion, builder, nowInSec);
+                reconcile(nextExisting, null, deletion, builder);
                 nextExisting = getNext(existing);
             }
             else if (cmp > 0)
             {
-                reconcile(null, nextUpdate, deletion, builder, nowInSec);
+                reconcile(null, nextUpdate, deletion, builder);
                 nextUpdate = getNext(update);
             }
             else
             {
-                timeDelta = Math.min(timeDelta, reconcile(nextExisting, 
nextUpdate, deletion, builder, nowInSec));
+                timeDelta = Math.min(timeDelta, reconcile(nextExisting, 
nextUpdate, deletion, builder));
                 nextExisting = getNext(existing);
                 nextUpdate = getNext(update);
             }
@@ -246,20 +286,16 @@ public abstract class Cells
      * @param deletion the deletion time that applies to the cells being 
considered.
      * This deletion time may delete both {@code existing} or {@code update}.
      * @param builder the row builder to which the result of the filtering is 
written.
-     * @param nowInSec the current time in seconds (which plays a role during 
reconciliation
-     * because deleted cells always have precedence on timestamp equality and 
deciding if a
-     * cell is a live or not depends on the current time due to expiring 
cells).
      */
     public static void addNonShadowed(Cell existing,
                                       Cell update,
                                       DeletionTime deletion,
-                                      Row.Builder builder,
-                                      int nowInSec)
+                                      Row.Builder builder)
     {
         if (deletion.deletes(existing))
             return;
 
-        Cell reconciled = reconcile(existing, update, nowInSec);
+        Cell reconciled = reconcile(existing, update);
         if (reconciled != update)
             builder.addCell(existing);
     }
@@ -278,16 +314,12 @@ public abstract class Cells
      * @param deletion the deletion time that applies to the cells being 
considered.
      * This deletion time may delete both {@code existing} or {@code update}.
      * @param builder the row builder to which the result of the filtering is 
written.
-     * @param nowInSec the current time in seconds (which plays a role during 
reconciliation
-     * because deleted cells always have precedence on timestamp equality and 
deciding if a
-     * cell is a live or not depends on the current time due to expiring 
cells).
      */
     public static void addNonShadowedComplex(ColumnMetadata column,
                                              Iterator<Cell> existing,
                                              Iterator<Cell> update,
                                              DeletionTime deletion,
-                                             Row.Builder builder,
-                                             int nowInSec)
+                                             Row.Builder builder)
     {
         Comparator<CellPath> comparator = column.cellPathComparator();
         Cell nextExisting = getNext(existing);
@@ -297,12 +329,12 @@ public abstract class Cells
             int cmp = nextUpdate == null ? -1 : 
comparator.compare(nextExisting.path(), nextUpdate.path());
             if (cmp < 0)
             {
-                addNonShadowed(nextExisting, null, deletion, builder, 
nowInSec);
+                addNonShadowed(nextExisting, null, deletion, builder);
                 nextExisting = getNext(existing);
             }
             else if (cmp == 0)
             {
-                addNonShadowed(nextExisting, nextUpdate, deletion, builder, 
nowInSec);
+                addNonShadowed(nextExisting, nextUpdate, deletion, builder);
                 nextExisting = getNext(existing);
                 nextUpdate = getNext(update);
             }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/rows/Row.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/Row.java 
b/src/java/org/apache/cassandra/db/rows/Row.java
index f35272a..74c0040 100644
--- a/src/java/org/apache/cassandra/db/rows/Row.java
+++ b/src/java/org/apache/cassandra/db/rows/Row.java
@@ -621,11 +621,11 @@ public interface Row extends Unfiltered, 
Collection<ColumnData>
         private final List<ColumnData> dataBuffer = new ArrayList<>();
         private final ColumnDataReducer columnDataReducer;
 
-        public Merger(int size, int nowInSec, boolean hasComplex)
+        public Merger(int size, boolean hasComplex)
         {
             this.rows = new Row[size];
             this.columnDataIterators = new ArrayList<>(size);
-            this.columnDataReducer = new ColumnDataReducer(size, nowInSec, 
hasComplex);
+            this.columnDataReducer = new ColumnDataReducer(size, hasComplex);
         }
 
         public void clear()
@@ -711,8 +711,6 @@ public interface Row extends Unfiltered, 
Collection<ColumnData>
 
         private static class ColumnDataReducer extends 
MergeIterator.Reducer<ColumnData, ColumnData>
         {
-            private final int nowInSec;
-
             private ColumnMetadata column;
             private final List<ColumnData> versions;
 
@@ -722,13 +720,12 @@ public interface Row extends Unfiltered, 
Collection<ColumnData>
             private final List<Iterator<Cell>> complexCells;
             private final CellReducer cellReducer;
 
-            public ColumnDataReducer(int size, int nowInSec, boolean 
hasComplex)
+            public ColumnDataReducer(int size, boolean hasComplex)
             {
-                this.nowInSec = nowInSec;
                 this.versions = new ArrayList<>(size);
                 this.complexBuilder = hasComplex ? ComplexColumnData.builder() 
: null;
                 this.complexCells = hasComplex ? new ArrayList<>(size) : null;
-                this.cellReducer = new CellReducer(nowInSec);
+                this.cellReducer = new CellReducer();
             }
 
             public void setActiveDeletion(DeletionTime activeDeletion)
@@ -767,7 +764,7 @@ public interface Row extends Unfiltered, 
Collection<ColumnData>
                     {
                         Cell cell = (Cell)data;
                         if (!activeDeletion.deletes(cell))
-                            merged = merged == null ? cell : 
Cells.reconcile(merged, cell, nowInSec);
+                            merged = merged == null ? cell : 
Cells.reconcile(merged, cell);
                     }
                     return merged;
                 }
@@ -814,16 +811,9 @@ public interface Row extends Unfiltered, 
Collection<ColumnData>
 
         private static class CellReducer extends MergeIterator.Reducer<Cell, 
Cell>
         {
-            private final int nowInSec;
-
             private DeletionTime activeDeletion;
             private Cell merged;
 
-            public CellReducer(int nowInSec)
-            {
-                this.nowInSec = nowInSec;
-            }
-
             public void setActiveDeletion(DeletionTime activeDeletion)
             {
                 this.activeDeletion = activeDeletion;
@@ -833,7 +823,7 @@ public interface Row extends Unfiltered, 
Collection<ColumnData>
             public void reduce(int idx, Cell cell)
             {
                 if (!activeDeletion.deletes(cell))
-                    merged = merged == null ? cell : Cells.reconcile(merged, 
cell, nowInSec);
+                    merged = merged == null ? cell : Cells.reconcile(merged, 
cell);
             }
 
             protected Cell getReduced()

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/rows/Rows.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/Rows.java 
b/src/java/org/apache/cassandra/db/rows/Rows.java
index 8c18c82..c0c84b6 100644
--- a/src/java/org/apache/cassandra/db/rows/Rows.java
+++ b/src/java/org/apache/cassandra/db/rows/Rows.java
@@ -239,10 +239,10 @@ public abstract class Rows
             iter.next();
     }
 
-    public static Row merge(Row row1, Row row2, int nowInSec)
+    public static Row merge(Row row1, Row row2)
     {
         Row.Builder builder = BTreeRow.sortedBuilder();
-        merge(row1, row2, builder, nowInSec);
+        merge(row1, row2, builder);
         return builder.build();
     }
 
@@ -256,9 +256,6 @@ public abstract class Rows
      * @param existing
      * @param update
      * @param builder the row build to which the result of the reconciliation 
is written.
-     * @param nowInSec the current time in seconds (which plays a role during 
reconciliation
-     * because deleted cells always have precedence on timestamp equality and 
deciding if a
-     * cell is a live or not depends on the current time due to expiring 
cells).
      *
      * @return the smallest timestamp delta between corresponding rows from 
existing and update. A
      * timestamp delta being computed as the difference between the cells and 
DeletionTimes from {@code existing}
@@ -266,8 +263,7 @@ public abstract class Rows
      */
     public static long merge(Row existing,
                              Row update,
-                             Row.Builder builder,
-                             int nowInSec)
+                             Row.Builder builder)
     {
         Clustering clustering = existing.clustering();
         builder.newRow(clustering);
@@ -301,7 +297,7 @@ public abstract class Rows
             ColumnMetadata column = getColumnMetadata(cura, curb);
             if (column.isSimple())
             {
-                timeDelta = Math.min(timeDelta, Cells.reconcile((Cell) cura, 
(Cell) curb, deletion, builder, nowInSec));
+                timeDelta = Math.min(timeDelta, Cells.reconcile((Cell) cura, 
(Cell) curb, deletion, builder));
             }
             else
             {
@@ -318,7 +314,7 @@ public abstract class Rows
 
                 Iterator<Cell> existingCells = existingData == null ? null : 
existingData.iterator();
                 Iterator<Cell> updateCells = updateData == null ? null : 
updateData.iterator();
-                timeDelta = Math.min(timeDelta, Cells.reconcileComplex(column, 
existingCells, updateCells, maxDt, builder, nowInSec));
+                timeDelta = Math.min(timeDelta, Cells.reconcileComplex(column, 
existingCells, updateCells, maxDt, builder));
             }
 
             if (cura != null)
@@ -337,11 +333,8 @@ public abstract class Rows
      * @param existing source row
      * @param update shadowing row
      * @param rangeDeletion extra {@code DeletionTime} from covering tombstone
-     * @param nowInSec the current time in seconds (which plays a role during 
reconciliation
-     * because deleted cells always have precedence on timestamp equality and 
deciding if a
-     * cell is a live or not depends on the current time due to expiring 
cells).
      */
-    public static Row removeShadowedCells(Row existing, Row update, 
DeletionTime rangeDeletion, int nowInSec)
+    public static Row removeShadowedCells(Row existing, Row update, 
DeletionTime rangeDeletion)
     {
         Row.Builder builder = BTreeRow.sortedBuilder();
         Clustering clustering = existing.clustering();
@@ -371,7 +364,7 @@ public abstract class Rows
                 ColumnData curb = comparison == 0 ? nextb : null;
                 if (column.isSimple())
                 {
-                    Cells.addNonShadowed((Cell) cura, (Cell) curb, deletion, 
builder, nowInSec);
+                    Cells.addNonShadowed((Cell) cura, (Cell) curb, deletion, 
builder);
                 }
                 else
                 {
@@ -390,7 +383,7 @@ public abstract class Rows
 
                     Iterator<Cell> existingCells = existingData.iterator();
                     Iterator<Cell> updateCells = updateData == null ? null : 
updateData.iterator();
-                    Cells.addNonShadowedComplex(column, existingCells, 
updateCells, maxDt, builder, nowInSec);
+                    Cells.addNonShadowedComplex(column, existingCells, 
updateCells, maxDt, builder);
                 }
                 nexta = a.hasNext() ? a.next() : null;
                 if (curb != null)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/rows/UnfilteredRowIterators.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/rows/UnfilteredRowIterators.java 
b/src/java/org/apache/cassandra/db/rows/UnfilteredRowIterators.java
index b125c01..851e447 100644
--- a/src/java/org/apache/cassandra/db/rows/UnfilteredRowIterators.java
+++ b/src/java/org/apache/cassandra/db/rows/UnfilteredRowIterators.java
@@ -123,13 +123,13 @@ public abstract class UnfilteredRowIterators
     /**
      * Returns an iterator that is the result of merging other iterators.
      */
-    public static UnfilteredRowIterator merge(List<UnfilteredRowIterator> 
iterators, int nowInSec)
+    public static UnfilteredRowIterator merge(List<UnfilteredRowIterator> 
iterators)
     {
         assert !iterators.isEmpty();
         if (iterators.size() == 1)
             return iterators.get(0);
 
-        return UnfilteredRowMergeIterator.create(iterators, nowInSec, null);
+        return UnfilteredRowMergeIterator.create(iterators, null);
     }
 
     /**
@@ -138,9 +138,9 @@ public abstract class UnfilteredRowIterators
      *
      * Note that this method assumes that there is at least 2 iterators to 
merge.
      */
-    public static UnfilteredRowIterator merge(List<UnfilteredRowIterator> 
iterators, int nowInSec, MergeListener mergeListener)
+    public static UnfilteredRowIterator merge(List<UnfilteredRowIterator> 
iterators, MergeListener mergeListener)
     {
-        return UnfilteredRowMergeIterator.create(iterators, nowInSec, 
mergeListener);
+        return UnfilteredRowMergeIterator.create(iterators, mergeListener);
     }
 
     /**
@@ -394,7 +394,6 @@ public abstract class UnfilteredRowIterators
                                            List<UnfilteredRowIterator> 
iterators,
                                            RegularAndStaticColumns columns,
                                            DeletionTime partitionDeletion,
-                                           int nowInSec,
                                            boolean reversed,
                                            MergeListener listener)
         {
@@ -402,17 +401,17 @@ public abstract class UnfilteredRowIterators
                   iterators.get(0).partitionKey(),
                   partitionDeletion,
                   columns,
-                  mergeStaticRows(iterators, columns.statics, nowInSec, 
listener, partitionDeletion),
+                  mergeStaticRows(iterators, columns.statics, listener, 
partitionDeletion),
                   reversed,
                   mergeStats(iterators));
 
             this.mergeIterator = MergeIterator.get(iterators,
                                                    reversed ? 
metadata.comparator.reversed() : metadata.comparator,
-                                                   new 
MergeReducer(iterators.size(), reversed, nowInSec, listener));
+                                                   new 
MergeReducer(iterators.size(), reversed, listener));
             this.listener = listener;
         }
 
-        private static UnfilteredRowMergeIterator 
create(List<UnfilteredRowIterator> iterators, int nowInSec, MergeListener 
listener)
+        private static UnfilteredRowMergeIterator 
create(List<UnfilteredRowIterator> iterators, MergeListener listener)
         {
             try
             {
@@ -421,7 +420,6 @@ public abstract class UnfilteredRowIterators
                                                       iterators,
                                                       
collectColumns(iterators),
                                                       
collectPartitionLevelDeletion(iterators, listener),
-                                                      nowInSec,
                                                       
iterators.get(0).isReverseOrder(),
                                                       listener);
             }
@@ -477,7 +475,6 @@ public abstract class UnfilteredRowIterators
 
         private static Row mergeStaticRows(List<UnfilteredRowIterator> 
iterators,
                                            Columns columns,
-                                           int nowInSec,
                                            MergeListener listener,
                                            DeletionTime partitionDeletion)
         {
@@ -487,7 +484,7 @@ public abstract class UnfilteredRowIterators
             if (iterators.stream().allMatch(iter -> 
iter.staticRow().isEmpty()))
                 return Rows.EMPTY_STATIC_ROW;
 
-            Row.Merger merger = new Row.Merger(iterators.size(), nowInSec, 
columns.hasComplex());
+            Row.Merger merger = new Row.Merger(iterators.size(), 
columns.hasComplex());
             for (int i = 0; i < iterators.size(); i++)
                 merger.add(i, iterators.get(i).staticRow());
 
@@ -552,9 +549,9 @@ public abstract class UnfilteredRowIterators
             private final Row.Merger rowMerger;
             private final RangeTombstoneMarker.Merger markerMerger;
 
-            private MergeReducer(int size, boolean reversed, int nowInSec, 
MergeListener listener)
+            private MergeReducer(int size, boolean reversed, MergeListener 
listener)
             {
-                this.rowMerger = new Row.Merger(size, nowInSec, 
columns().regulars.hasComplex());
+                this.rowMerger = new Row.Merger(size, 
columns().regulars.hasComplex());
                 this.markerMerger = new RangeTombstoneMarker.Merger(size, 
partitionLevelDeletion(), reversed);
                 this.listener = listener;
             }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/view/TableViews.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/view/TableViews.java 
b/src/java/org/apache/cassandra/db/view/TableViews.java
index eedcfbd..d35457e 100644
--- a/src/java/org/apache/cassandra/db/view/TableViews.java
+++ b/src/java/org/apache/cassandra/db/view/TableViews.java
@@ -246,7 +246,7 @@ public class TableViews extends AbstractCollection<View>
                 updateRow = 
((Row)updatesIter.next()).withRowDeletion(updatesDeletion.currentDeletion());
             }
 
-            addToViewUpdateGenerators(existingRow, updateRow, generators, 
nowInSec);
+            addToViewUpdateGenerators(existingRow, updateRow, generators);
         }
 
         // We only care about more existing rows if the update deletion isn't 
live, i.e. if we had a partition deletion
@@ -261,7 +261,7 @@ public class TableViews extends AbstractCollection<View>
                     continue;
 
                 Row existingRow = (Row)existing;
-                addToViewUpdateGenerators(existingRow, 
emptyRow(existingRow.clustering(), updatesDeletion.currentDeletion()), 
generators, nowInSec);
+                addToViewUpdateGenerators(existingRow, 
emptyRow(existingRow.clustering(), updatesDeletion.currentDeletion()), 
generators);
             }
         }
 
@@ -291,8 +291,7 @@ public class TableViews extends AbstractCollection<View>
                         Row updateRow = (Row) update;
                         
addToViewUpdateGenerators(emptyRow(updateRow.clustering(), 
existingsDeletion.currentDeletion()),
                                                   updateRow,
-                                                  generators,
-                                                  nowInSec);
+                                                  generators);
 
                         // If the updates have been filtered, then we won't 
have any mutations; we need to make sure that we
                         // only return if the mutations are empty. Otherwise, 
we continue to search for an update which is
@@ -333,8 +332,7 @@ public class TableViews extends AbstractCollection<View>
                 Row updateRow = (Row) update;
                 addToViewUpdateGenerators(emptyRow(updateRow.clustering(), 
existingsDeletion.currentDeletion()),
                                           updateRow,
-                                          generators,
-                                          nowInSec);
+                                          generators);
             }
 
             return 
Iterators.singletonIterator(buildMutations(baseTableMetadata.get(), 
generators));
@@ -465,9 +463,8 @@ public class TableViews extends AbstractCollection<View>
      * @param existingBaseRow the base table row as it is before an update.
      * @param updateBaseRow the newly updates made to {@code existingBaseRow}.
      * @param generators the view update generators to add the new changes to.
-     * @param nowInSec the current time in seconds. Used to decide if data is 
live or not.
      */
-    private static void addToViewUpdateGenerators(Row existingBaseRow, Row 
updateBaseRow, Collection<ViewUpdateGenerator> generators, int nowInSec)
+    private static void addToViewUpdateGenerators(Row existingBaseRow, Row 
updateBaseRow, Collection<ViewUpdateGenerator> generators)
     {
         // Having existing empty is useful, it just means we'll insert a brand 
new entry for updateBaseRow,
         // but if we have no update at all, we shouldn't get there.
@@ -475,7 +472,7 @@ public class TableViews extends AbstractCollection<View>
 
         // We allow existingBaseRow to be null, which we treat the same as 
being empty as an small optimization
         // to avoid allocating empty row objects when we know there was 
nothing existing.
-        Row mergedBaseRow = existingBaseRow == null ? updateBaseRow : 
Rows.merge(existingBaseRow, updateBaseRow, nowInSec);
+        Row mergedBaseRow = existingBaseRow == null ? updateBaseRow : 
Rows.merge(existingBaseRow, updateBaseRow);
         for (ViewUpdateGenerator generator : generators)
             generator.addBaseTableUpdate(existingBaseRow, mergedBaseRow);
     }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/db/virtual/SimpleDataSet.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/virtual/SimpleDataSet.java 
b/src/java/org/apache/cassandra/db/virtual/SimpleDataSet.java
index 2af3b6a..bf40140 100644
--- a/src/java/org/apache/cassandra/db/virtual/SimpleDataSet.java
+++ b/src/java/org/apache/cassandra/db/virtual/SimpleDataSet.java
@@ -169,7 +169,7 @@ public class SimpleDataSet extends 
AbstractVirtualTable.AbstractDataSet
 
         private org.apache.cassandra.db.rows.Row 
toTableRow(RegularAndStaticColumns columns, long now)
         {
-            org.apache.cassandra.db.rows.Row.Builder builder = 
BTreeRow.unsortedBuilder((int) TimeUnit.MILLISECONDS.toSeconds(now));
+            org.apache.cassandra.db.rows.Row.Builder builder = 
BTreeRow.unsortedBuilder();
             builder.newRow(clustering);
 
             columns.forEach(c ->

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/src/java/org/apache/cassandra/service/reads/DataResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/reads/DataResolver.java 
b/src/java/org/apache/cassandra/service/reads/DataResolver.java
index 76e9633..c0bff7a 100644
--- a/src/java/org/apache/cassandra/service/reads/DataResolver.java
+++ b/src/java/org/apache/cassandra/service/reads/DataResolver.java
@@ -112,7 +112,7 @@ public class DataResolver extends ResponseResolver
             for (int i = 0; i < results.size(); i++)
                 results.set(i, ShortReadProtection.extend(sources[i], 
results.get(i), command, mergedResultCounter, queryStartNanoTime, 
enforceStrictLiveness));
 
-        return UnfilteredPartitionIterators.merge(results, command.nowInSec(), 
wrapMergeListener(readRepair.getMergeListener(sources), sources));
+        return UnfilteredPartitionIterators.merge(results, 
wrapMergeListener(readRepair.getMergeListener(sources), sources));
     }
 
     private String makeResponsesDebugString(DecoratedKey partitionKey)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/test/unit/org/apache/cassandra/db/CellTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/CellTest.java 
b/test/unit/org/apache/cassandra/db/CellTest.java
index c94282f..ae22816 100644
--- a/test/unit/org/apache/cassandra/db/CellTest.java
+++ b/test/unit/org/apache/cassandra/db/CellTest.java
@@ -367,7 +367,7 @@ public class CellTest
         List<Cell> cells2 = Lists.newArrayList(r2m2, r2m3, r2m4);
 
         RowBuilder builder = new RowBuilder();
-        Cells.reconcileComplex(m, cells1.iterator(), cells2.iterator(), 
DeletionTime.LIVE, builder, now2 + 1);
+        Cells.reconcileComplex(m, cells1.iterator(), cells2.iterator(), 
DeletionTime.LIVE, builder);
         Assert.assertEquals(Lists.newArrayList(r1m1, r2m2, r2m3, r2m4), 
builder.cells);
     }
 
@@ -384,10 +384,9 @@ public class CellTest
         Cell c1 = expiring(cfm, n1, v1, t1, et1);
         Cell c2 = expiring(cfm, n2, v2, t2, et2);
 
-        int now = FBUtilities.nowInSeconds();
-        if (Cells.reconcile(c1, c2, now) == c1)
-            return Cells.reconcile(c2, c1, now) == c1 ? -1 : 0;
-        return Cells.reconcile(c2, c1, now) == c2 ? 1 : 0;
+        if (Cells.reconcile(c1, c2) == c1)
+            return Cells.reconcile(c2, c1) == c1 ? -1 : 0;
+        return Cells.reconcile(c2, c1) == c2 ? 1 : 0;
     }
 
     private Cell regular(TableMetadata cfm, String columnName, String value, 
long timestamp)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/test/unit/org/apache/cassandra/db/CounterCellTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/CounterCellTest.java 
b/test/unit/org/apache/cassandra/db/CounterCellTest.java
index 0ee59e1..36f8c92 100644
--- a/test/unit/org/apache/cassandra/db/CounterCellTest.java
+++ b/test/unit/org/apache/cassandra/db/CounterCellTest.java
@@ -136,43 +136,43 @@ public class CounterCellTest
         // both deleted, diff deletion time, same ts
         left = createDeleted(cfs, col, 2, 5);
         right = createDeleted(cfs, col, 2, 10);
-        assert Cells.reconcile(left, right, 10) == right;
+        assert Cells.reconcile(left, right) == right;
 
         // diff ts
         right = createLegacyCounterCell(cfs, col, 1, 10);
-        assert Cells.reconcile(left, right, 10) == left;
+        assert Cells.reconcile(left, right) == left;
 
         // < tombstone
         left = createDeleted(cfs, col, 6, 6);
         right = createLegacyCounterCell(cfs, col, 1, 5);
-        assert Cells.reconcile(left, right, 10) == left;
+        assert Cells.reconcile(left, right) == left;
 
         // > tombstone
         left = createDeleted(cfs, col, 1, 1);
         right = createLegacyCounterCell(cfs, col, 1, 5);
-        assert Cells.reconcile(left, right, 10) == left;
+        assert Cells.reconcile(left, right) == left;
 
         // == tombstone
         left = createDeleted(cfs, col, 8, 8);
         right = createLegacyCounterCell(cfs, col, 1, 8);
-        assert Cells.reconcile(left, right, 10) == left;
+        assert Cells.reconcile(left, right) == left;
 
         // live + live
         left = createLegacyCounterCell(cfs, col, 1, 2);
         right = createLegacyCounterCell(cfs, col, 3, 5);
-        Cell reconciled = Cells.reconcile(left, right, 10);
+        Cell reconciled = Cells.reconcile(left, right);
         assertEquals(CounterContext.instance().total(reconciled.value()), 4);
         assertEquals(reconciled.timestamp(), 5L);
 
         // Add, don't change TS
         Cell addTen = createLegacyCounterCell(cfs, col, 10, 4);
-        reconciled = Cells.reconcile(reconciled, addTen, 10);
+        reconciled = Cells.reconcile(reconciled, addTen);
         assertEquals(CounterContext.instance().total(reconciled.value()), 14);
         assertEquals(reconciled.timestamp(), 5L);
 
         // Add w/new TS
         Cell addThree = createLegacyCounterCell(cfs, col, 3, 7);
-        reconciled = Cells.reconcile(reconciled, addThree, 10);
+        reconciled = Cells.reconcile(reconciled, addThree);
         assertEquals(CounterContext.instance().total(reconciled.value()), 17);
         assertEquals(reconciled.timestamp(), 7L);
 
@@ -180,7 +180,7 @@ public class CounterCellTest
         assert reconciled.localDeletionTime() == Integer.MAX_VALUE;
 
         Cell deleted = createDeleted(cfs, col, 8, 8);
-        reconciled = Cells.reconcile(reconciled, deleted, 10);
+        reconciled = Cells.reconcile(reconciled, deleted);
         assert reconciled.localDeletionTime() == 8;
     }
 
@@ -292,7 +292,7 @@ public class CounterCellTest
         ColumnMetadata emptyColDef = 
cfs.metadata().getColumn(ByteBufferUtil.bytes("val2"));
         BufferCell emptyCell = BufferCell.live(emptyColDef, 0, 
ByteBuffer.allocate(0));
 
-        Row.Builder builder = BTreeRow.unsortedBuilder(0);
+        Row.Builder builder = BTreeRow.unsortedBuilder();
         
builder.newRow(Clustering.make(AsciiSerializer.instance.serialize("test")));
         builder.addCell(emptyCell);
         Row row = builder.build();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/test/unit/org/apache/cassandra/db/NativeCellTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/NativeCellTest.java 
b/test/unit/org/apache/cassandra/db/NativeCellTest.java
index cd7074f..a63fb32 100644
--- a/test/unit/org/apache/cassandra/db/NativeCellTest.java
+++ b/test/unit/org/apache/cassandra/db/NativeCellTest.java
@@ -61,7 +61,7 @@ public class NativeCellTest
     {
         for (int run = 0 ; run < 1000 ; run++)
         {
-            Row.Builder builder = BTreeRow.unsortedBuilder(1);
+            Row.Builder builder = BTreeRow.unsortedBuilder();
             builder.newRow(rndclustering());
             int count = 1 + rand.nextInt(10);
             for (int i = 0 ; i < count ; i++)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/test/unit/org/apache/cassandra/db/ReadCommandTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/ReadCommandTest.java 
b/test/unit/org/apache/cassandra/db/ReadCommandTest.java
index 6a82a5a..5020b95 100644
--- a/test/unit/org/apache/cassandra/db/ReadCommandTest.java
+++ b/test/unit/org/apache/cassandra/db/ReadCommandTest.java
@@ -320,7 +320,7 @@ public class ReadCommandTest
                 }
             };
 
-        try (PartitionIterator partitionIterator = 
UnfilteredPartitionIterators.filter(UnfilteredPartitionIterators.merge(iterators,
 nowInSeconds, listener), nowInSeconds))
+        try (PartitionIterator partitionIterator = 
UnfilteredPartitionIterators.filter(UnfilteredPartitionIterators.merge(iterators,
 listener), nowInSeconds))
         {
 
             int i = 0;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/test/unit/org/apache/cassandra/db/RowTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/RowTest.java 
b/test/unit/org/apache/cassandra/db/RowTest.java
index ca2765d..fe54299 100644
--- a/test/unit/org/apache/cassandra/db/RowTest.java
+++ b/test/unit/org/apache/cassandra/db/RowTest.java
@@ -83,7 +83,7 @@ public class RowTest
     }
 
     @Test
-    public void testMergeRangeTombstones() throws InterruptedException
+    public void testMergeRangeTombstones()
     {
         PartitionUpdate.Builder update1 = new 
PartitionUpdate.Builder(metadata, dk, metadata.regularAndStaticColumns(), 1);
         writeRangeTombstone(update1, "1", "11", 123, 123);
@@ -99,7 +99,7 @@ public class RowTest
         writeRangeTombstone(update2, "4", "41", 123, 1230);
         writeRangeTombstone(update2, "5", "51", 123, 1230);
 
-        try (UnfilteredRowIterator merged = 
UnfilteredRowIterators.merge(ImmutableList.of(update1.build().unfilteredIterator(),
 update2.build().unfilteredIterator()), nowInSeconds))
+        try (UnfilteredRowIterator merged = 
UnfilteredRowIterators.merge(ImmutableList.of(update1.build().unfilteredIterator(),
 update2.build().unfilteredIterator())))
         {
             Object[][] expected = new Object[][]{ { "1", "11", 123l, 123 },
                                                   { "111", "112", 1230l, 123 },
@@ -132,7 +132,7 @@ public class RowTest
         ColumnMetadata defA = metadata.getColumn(new ColumnIdentifier("a", 
true));
         ColumnMetadata defB = metadata.getColumn(new ColumnIdentifier("b", 
true));
 
-        Row.Builder builder = BTreeRow.unsortedBuilder(nowInSeconds);
+        Row.Builder builder = BTreeRow.unsortedBuilder();
         builder.newRow(metadata.comparator.make("c1"));
         writeSimpleCellValue(builder, defA, "a1", 0);
         writeSimpleCellValue(builder, defA, "a2", 1);
@@ -176,7 +176,7 @@ public class RowTest
         ColumnMetadata defA = metadata.getColumn(new ColumnIdentifier("a", 
true));
         ColumnMetadata defB = metadata.getColumn(new ColumnIdentifier("b", 
true));
 
-        Row.Builder builder = BTreeRow.unsortedBuilder(nowInSeconds);
+        Row.Builder builder = BTreeRow.unsortedBuilder();
         builder.newRow(metadata.comparator.make("c1"));
         writeSimpleCellValue(builder, defA, "a1", 0);
         writeSimpleCellValue(builder, defA, "a2", 1);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/test/unit/org/apache/cassandra/db/partition/PartitionImplementationTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/db/partition/PartitionImplementationTest.java 
b/test/unit/org/apache/cassandra/db/partition/PartitionImplementationTest.java
index 62dc260..5162548 100644
--- 
a/test/unit/org/apache/cassandra/db/partition/PartitionImplementationTest.java
+++ 
b/test/unit/org/apache/cassandra/db/partition/PartitionImplementationTest.java
@@ -101,7 +101,7 @@ public class PartitionImplementationTest
     Row makeRow(Clustering clustering, String colValue)
     {
         ColumnMetadata defCol = metadata.getColumn(new ColumnIdentifier("col", 
true));
-        Row.Builder row = BTreeRow.unsortedBuilder(TIMESTAMP);
+        Row.Builder row = BTreeRow.unsortedBuilder();
         row.newRow(clustering);
         row.addCell(BufferCell.live(defCol, TIMESTAMP, 
ByteBufferUtil.bytes(colValue)));
         return row.build();
@@ -110,7 +110,7 @@ public class PartitionImplementationTest
     Row makeStaticRow()
     {
         ColumnMetadata defCol = metadata.getColumn(new 
ColumnIdentifier("static_col", true));
-        Row.Builder row = BTreeRow.unsortedBuilder(TIMESTAMP);
+        Row.Builder row = BTreeRow.unsortedBuilder();
         row.newRow(Clustering.STATIC_CLUSTERING);
         row.addCell(BufferCell.live(defCol, TIMESTAMP, 
ByteBufferUtil.bytes("static value")));
         return row.build();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/test/unit/org/apache/cassandra/db/rows/RowsTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/rows/RowsTest.java 
b/test/unit/org/apache/cassandra/db/rows/RowsTest.java
index 73822a7..00a9af4 100644
--- a/test/unit/org/apache/cassandra/db/rows/RowsTest.java
+++ b/test/unit/org/apache/cassandra/db/rows/RowsTest.java
@@ -211,7 +211,7 @@ public class RowsTest
     private static Row.Builder createBuilder(Clustering c, int now, ByteBuffer 
vVal, ByteBuffer mKey, ByteBuffer mVal)
     {
         long ts = secondToTs(now);
-        Row.Builder builder = BTreeRow.unsortedBuilder(now);
+        Row.Builder builder = BTreeRow.unsortedBuilder();
         builder.newRow(c);
         builder.addPrimaryKeyLivenessInfo(LivenessInfo.create(ts, now));
         if (vVal != null)
@@ -232,7 +232,7 @@ public class RowsTest
     {
         int now = FBUtilities.nowInSeconds();
         long ts = secondToTs(now);
-        Row.Builder originalBuilder = BTreeRow.unsortedBuilder(now);
+        Row.Builder originalBuilder = BTreeRow.unsortedBuilder();
         originalBuilder.newRow(c1);
         LivenessInfo liveness = LivenessInfo.create(ts, now);
         originalBuilder.addPrimaryKeyLivenessInfo(liveness);
@@ -261,7 +261,7 @@ public class RowsTest
     {
         int now = FBUtilities.nowInSeconds();
         long ts = secondToTs(now);
-        Row.Builder builder = BTreeRow.unsortedBuilder(now);
+        Row.Builder builder = BTreeRow.unsortedBuilder();
         builder.newRow(c1);
         LivenessInfo liveness = LivenessInfo.create(ts, now);
         builder.addPrimaryKeyLivenessInfo(liveness);
@@ -299,7 +299,7 @@ public class RowsTest
     {
         int now1 = FBUtilities.nowInSeconds();
         long ts1 = secondToTs(now1);
-        Row.Builder r1Builder = BTreeRow.unsortedBuilder(now1);
+        Row.Builder r1Builder = BTreeRow.unsortedBuilder();
         r1Builder.newRow(c1);
         LivenessInfo r1Liveness = LivenessInfo.create(ts1, now1);
         r1Builder.addPrimaryKeyLivenessInfo(r1Liveness);
@@ -315,7 +315,7 @@ public class RowsTest
 
         int now2 = now1 + 1;
         long ts2 = secondToTs(now2);
-        Row.Builder r2Builder = BTreeRow.unsortedBuilder(now2);
+        Row.Builder r2Builder = BTreeRow.unsortedBuilder();
         r2Builder.newRow(c1);
         LivenessInfo r2Liveness = LivenessInfo.create(ts2, now2);
         r2Builder.addPrimaryKeyLivenessInfo(r2Liveness);
@@ -331,7 +331,7 @@ public class RowsTest
 
         Row r1 = r1Builder.build();
         Row r2 = r2Builder.build();
-        Row merged = Rows.merge(r1, r2, now2 + 1);
+        Row merged = Rows.merge(r1, r2);
 
         Assert.assertEquals(r1ComplexDeletion, 
merged.getComplexColumnData(m).complexDeletion());
 
@@ -375,7 +375,7 @@ public class RowsTest
     {
         int now1 = FBUtilities.nowInSeconds();
         long ts1 = secondToTs(now1);
-        Row.Builder r1Builder = BTreeRow.unsortedBuilder(now1);
+        Row.Builder r1Builder = BTreeRow.unsortedBuilder();
         r1Builder.newRow(c1);
         LivenessInfo r1Liveness = LivenessInfo.create(ts1, now1);
         r1Builder.addPrimaryKeyLivenessInfo(r1Liveness);
@@ -383,7 +383,7 @@ public class RowsTest
         // mergedData == null
         int now2 = now1 + 1;
         long ts2 = secondToTs(now2);
-        Row.Builder r2Builder = BTreeRow.unsortedBuilder(now2);
+        Row.Builder r2Builder = BTreeRow.unsortedBuilder();
         r2Builder.newRow(c1);
         LivenessInfo r2Liveness = LivenessInfo.create(ts2, now2);
         r2Builder.addPrimaryKeyLivenessInfo(r2Liveness);
@@ -429,7 +429,7 @@ public class RowsTest
     {
         int now1 = FBUtilities.nowInSeconds();
         long ts1 = secondToTs(now1);
-        Row.Builder r1Builder = BTreeRow.unsortedBuilder(now1);
+        Row.Builder r1Builder = BTreeRow.unsortedBuilder();
         r1Builder.newRow(c1);
         LivenessInfo r1Liveness = LivenessInfo.create(ts1, now1);
         r1Builder.addPrimaryKeyLivenessInfo(r1Liveness);
@@ -437,7 +437,7 @@ public class RowsTest
         // mergedData == null
         int now2 = now1 + 1;
         long ts2 = secondToTs(now2);
-        Row.Builder r2Builder = BTreeRow.unsortedBuilder(now2);
+        Row.Builder r2Builder = BTreeRow.unsortedBuilder();
         r2Builder.newRow(c1);
         LivenessInfo r2Liveness = LivenessInfo.create(ts2, now2);
         r2Builder.addPrimaryKeyLivenessInfo(r2Liveness);
@@ -494,7 +494,7 @@ public class RowsTest
         updateBuilder.addCell(expectedMCell);
 
         RowBuilder builder = new RowBuilder();
-        long td = Rows.merge(existingBuilder.build(), updateBuilder.build(), 
builder, now2 + 1);
+        long td = Rows.merge(existingBuilder.build(), updateBuilder.build(), 
builder);
 
         Assert.assertEquals(c1, builder.clustering);
         Assert.assertEquals(LivenessInfo.create(ts2, now2), 
builder.livenessInfo);
@@ -518,7 +518,7 @@ public class RowsTest
         updateBuilder.addRowDeletion(expectedDeletion);
 
         RowBuilder builder = new RowBuilder();
-        Rows.merge(existingBuilder.build(), updateBuilder.build(), builder, 
now3 + 1);
+        Rows.merge(existingBuilder.build(), updateBuilder.build(), builder);
 
         Assert.assertEquals(expectedDeletion, builder.deletionTime);
         Assert.assertEquals(Collections.emptyList(), builder.complexDeletions);
@@ -542,7 +542,7 @@ public class RowsTest
         updateBuilder.addRowDeletion(expectedDeletion);
 
         RowBuilder builder = new RowBuilder();
-        Rows.merge(existingBuilder.build(), updateBuilder.build(), builder, 
now3 + 1);
+        Rows.merge(existingBuilder.build(), updateBuilder.build(), builder);
 
         Assert.assertEquals(expectedDeletion, builder.deletionTime);
         Assert.assertEquals(LivenessInfo.EMPTY, builder.livenessInfo);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/test/unit/org/apache/cassandra/db/rows/ThrottledUnfilteredIteratorTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/db/rows/ThrottledUnfilteredIteratorTest.java 
b/test/unit/org/apache/cassandra/db/rows/ThrottledUnfilteredIteratorTest.java
index a530521..cc886f1 100644
--- 
a/test/unit/org/apache/cassandra/db/rows/ThrottledUnfilteredIteratorTest.java
+++ 
b/test/unit/org/apache/cassandra/db/rows/ThrottledUnfilteredIteratorTest.java
@@ -682,7 +682,7 @@ public class ThrottledUnfilteredIteratorTest extends 
CQLTester
             }
 
             // Verify throttled data after merge
-            Partition partition = 
ImmutableBTreePartition.create(UnfilteredRowIterators.merge(unfilteredRowIterators,
 FBUtilities.nowInSeconds()));
+            Partition partition = 
ImmutableBTreePartition.create(UnfilteredRowIterators.merge(unfilteredRowIterators));
 
             int nowInSec = FBUtilities.nowInSeconds();
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/test/unit/org/apache/cassandra/db/rows/UnfilteredRowIteratorsMergeTest.java
----------------------------------------------------------------------
diff --git 
a/test/unit/org/apache/cassandra/db/rows/UnfilteredRowIteratorsMergeTest.java 
b/test/unit/org/apache/cassandra/db/rows/UnfilteredRowIteratorsMergeTest.java
index d6a968e..7f1b735 100644
--- 
a/test/unit/org/apache/cassandra/db/rows/UnfilteredRowIteratorsMergeTest.java
+++ 
b/test/unit/org/apache/cassandra/db/rows/UnfilteredRowIteratorsMergeTest.java
@@ -151,20 +151,19 @@ public class UnfilteredRowIteratorsMergeTest
 
     public UnfilteredRowIterator mergeIterators(List<UnfilteredRowIterator> 
us, boolean iterations)
     {
-        int now = FBUtilities.nowInSeconds();
         if (iterations)
         {
             UnfilteredRowIterator mi = us.get(0);
             int i;
             for (i = 1; i + 2 <= ITERATORS; i += 2)
-                mi = UnfilteredRowIterators.merge(ImmutableList.of(mi, 
us.get(i), us.get(i+1)), now);
+                mi = UnfilteredRowIterators.merge(ImmutableList.of(mi, 
us.get(i), us.get(i+1)));
             if (i + 1 <= ITERATORS)
-                mi = UnfilteredRowIterators.merge(ImmutableList.of(mi, 
us.get(i)), now);
+                mi = UnfilteredRowIterators.merge(ImmutableList.of(mi, 
us.get(i)));
             return mi;
         }
         else
         {
-            return UnfilteredRowIterators.merge(us, now);
+            return UnfilteredRowIterators.merge(us);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e225c88a/test/unit/org/apache/cassandra/service/reads/DataResolverTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/service/reads/DataResolverTest.java 
b/test/unit/org/apache/cassandra/service/reads/DataResolverTest.java
index 1a5aa7a..ac8ed0b 100644
--- a/test/unit/org/apache/cassandra/service/reads/DataResolverTest.java
+++ b/test/unit/org/apache/cassandra/service/reads/DataResolverTest.java
@@ -714,7 +714,7 @@ public class DataResolverTest
 
         long[] ts = {100, 200};
 
-        Row.Builder builder = BTreeRow.unsortedBuilder(nowInSec);
+        Row.Builder builder = BTreeRow.unsortedBuilder();
         builder.newRow(Clustering.EMPTY);
         builder.addComplexDeletion(m, new DeletionTime(ts[0] - 1, nowInSec));
         builder.addCell(mapCell(0, 0, ts[0]));
@@ -766,7 +766,7 @@ public class DataResolverTest
 
         long[] ts = {100, 200};
 
-        Row.Builder builder = BTreeRow.unsortedBuilder(nowInSec);
+        Row.Builder builder = BTreeRow.unsortedBuilder();
         builder.newRow(Clustering.EMPTY);
         builder.addComplexDeletion(m, new DeletionTime(ts[0] - 1, nowInSec));
         builder.addCell(mapCell(0, 0, ts[0]));
@@ -810,7 +810,7 @@ public class DataResolverTest
         long[] ts = {100, 200};
 
         // map column
-        Row.Builder builder = BTreeRow.unsortedBuilder(nowInSec);
+        Row.Builder builder = BTreeRow.unsortedBuilder();
         builder.newRow(Clustering.EMPTY);
         DeletionTime expectedCmplxDelete = new DeletionTime(ts[0] - 1, 
nowInSec);
         builder.addComplexDeletion(m, expectedCmplxDelete);
@@ -859,7 +859,7 @@ public class DataResolverTest
         long[] ts = {100, 200};
 
         // cleared map column
-        Row.Builder builder = BTreeRow.unsortedBuilder(nowInSec);
+        Row.Builder builder = BTreeRow.unsortedBuilder();
         builder.newRow(Clustering.EMPTY);
         builder.addComplexDeletion(m, new DeletionTime(ts[0] - 1, nowInSec));
 


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

Reply via email to