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]
