You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ma...@apache.org on 2014/10/02 10:50:39 UTC
[2/3] git commit: Merge branch 'cassandra-2.0' into cassandra-2.1
Merge branch 'cassandra-2.0' into cassandra-2.1
Conflicts:
src/java/org/apache/cassandra/db/ColumnFamily.java
src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java
src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/97b1d9f6
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/97b1d9f6
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/97b1d9f6
Branch: refs/heads/trunk
Commit: 97b1d9f6322067864146d0bb92afa1271c9cc4ac
Parents: b701dd5 7110d98
Author: Marcus Eriksson <ma...@apache.org>
Authored: Thu Oct 2 10:39:31 2014 +0200
Committer: Marcus Eriksson <ma...@apache.org>
Committed: Thu Oct 2 10:40:40 2014 +0200
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../org/apache/cassandra/db/ColumnFamily.java | 32 ++--
.../db/compaction/LazilyCompactedRow.java | 36 +++--
.../cassandra/io/sstable/ColumnStats.java | 67 ++++++++
.../cassandra/io/sstable/SSTableWriter.java | 32 ++--
.../cql3/SSTableMetadataTrackingTest.java | 160 +++++++++++++++++++
.../apache/cassandra/db/RangeTombstoneTest.java | 94 +++++++++++
7 files changed, 385 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/97b1d9f6/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index d83b86f,c9b4e59..d3a0ba2
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,58 -1,6 +1,59 @@@
-2.0.11:
+2.1.1
+ * Make native server start block until properly bound (CASSANDRA-7885)
+ * (cqlsh) Fix IPv6 support (CASSANDRA-7988)
+ * Ignore fat clients when checking for endpoint collision (CASSANDRA-7939)
+ * Make sstablerepairedset take a list of files (CASSANDRA-7995)
+ * (cqlsh) Tab completeion for indexes on map keys (CASSANDRA-7972)
+ * (cqlsh) Fix UDT field selection in select clause (CASSANDRA-7891)
+ * Fix resource leak in event of corrupt sstable
+ * (cqlsh) Add command line option for cqlshrc file path (CASSANDRA-7131)
+ * Provide visibility into prepared statements churn (CASSANDRA-7921, CASSANDRA-7930)
+ * Invalidate prepared statements when their keyspace or table is
+ dropped (CASSANDRA-7566)
+ * cassandra-stress: fix support for NetworkTopologyStrategy (CASSANDRA-7945)
+ * Fix saving caches when a table is dropped (CASSANDRA-7784)
+ * Add better error checking of new stress profile (CASSANDRA-7716)
+ * Use ThreadLocalRandom and remove FBUtilities.threadLocalRandom (CASSANDRA-7934)
+ * Prevent operator mistakes due to simultaneous bootstrap (CASSANDRA-7069)
+ * cassandra-stress supports whitelist mode for node config (CASSANDRA-7658)
+ * GCInspector more closely tracks GC; cassandra-stress and nodetool report it (CASSANDRA-7916)
+ * nodetool won't output bogus ownership info without a keyspace (CASSANDRA-7173)
+ * Add human readable option to nodetool commands (CASSANDRA-5433)
+ * Don't try to set repairedAt on old sstables (CASSANDRA-7913)
+ * Add metrics for tracking PreparedStatement use (CASSANDRA-7719)
+ * (cqlsh) tab-completion for triggers (CASSANDRA-7824)
+ * (cqlsh) Support for query paging (CASSANDRA-7514)
+ * (cqlsh) Show progress of COPY operations (CASSANDRA-7789)
+ * Add syntax to remove multiple elements from a map (CASSANDRA-6599)
+ * Support non-equals conditions in lightweight transactions (CASSANDRA-6839)
+ * Add IF [NOT] EXISTS to create/drop triggers (CASSANDRA-7606)
+ * (cqlsh) Display the current logged-in user (CASSANDRA-7785)
+ * (cqlsh) Don't ignore CTRL-C during COPY FROM execution (CASSANDRA-7815)
+ * (cqlsh) Order UDTs according to cross-type dependencies in DESCRIBE
+ output (CASSANDRA-7659)
+ * (cqlsh) Fix handling of CAS statement results (CASSANDRA-7671)
+ * (cqlsh) COPY TO/FROM improvements (CASSANDRA-7405)
+ * Support list index operations with conditions (CASSANDRA-7499)
+ * Add max live/tombstoned cells to nodetool cfstats output (CASSANDRA-7731)
+ * Validate IPv6 wildcard addresses properly (CASSANDRA-7680)
+ * (cqlsh) Error when tracing query (CASSANDRA-7613)
+ * Avoid IOOBE when building SyntaxError message snippet (CASSANDRA-7569)
+ * SSTableExport uses correct validator to create string representation of partition
+ keys (CASSANDRA-7498)
+ * Avoid NPEs when receiving type changes for an unknown keyspace (CASSANDRA-7689)
+ * Add support for custom 2i validation (CASSANDRA-7575)
+ * Pig support for hadoop CqlInputFormat (CASSANDRA-6454)
+ * Add listen_interface and rpc_interface options (CASSANDRA-7417)
+ * Improve schema merge performance (CASSANDRA-7444)
+ * Adjust MT depth based on # of partition validating (CASSANDRA-5263)
+ * Optimise NativeCell comparisons (CASSANDRA-6755)
+ * Configurable client timeout for cqlsh (CASSANDRA-7516)
+ * Include snippet of CQL query near syntax error in messages (CASSANDRA-7111)
+ * Make repair -pr work with -local (CASSANDRA-7450)
+ * Fix error in sstableloader with -cph > 1 (CASSANDRA-8007)
+Merged from 2.0:
* Better validation of collection values (CASSANDRA-7833)
+ * Track min/max timestamps correctly (CASSANDRA-7969)
* Fix possible overflow while sorting CL segments for replay (CASSANDRA-7992)
* Increase nodetool Xmx (CASSANDRA-7956)
* Archive any commitlog segments present at startup (CASSANDRA-6904)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/97b1d9f6/src/java/org/apache/cassandra/db/ColumnFamily.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/ColumnFamily.java
index cd96785,7edf825..38b39fe
--- a/src/java/org/apache/cassandra/db/ColumnFamily.java
+++ b/src/java/org/apache/cassandra/db/ColumnFamily.java
@@@ -394,50 -397,62 +394,60 @@@ public abstract class ColumnFamily impl
return cf1.diff(cf2);
}
- public void resolve(ColumnFamily cf)
- {
- resolve(cf, HeapAllocator.instance);
- }
-
- public void resolve(ColumnFamily cf, Allocator allocator)
- {
- // Row _does_ allow null CF objects :( seems a necessary evil for efficiency
- if (cf == null)
- return;
- addAll(cf, allocator);
- }
-
public ColumnStats getColumnStats()
{
- long minTimestampSeen = deletionInfo().isLive() ? Long.MAX_VALUE : deletionInfo().minTimestamp();
- long maxTimestampSeen = deletionInfo().maxTimestamp();
+ // note that we default to MIN_VALUE/MAX_VALUE here to be able to override them later in this method
+ // we are checking row/range tombstones and actual cells - there should always be data that overrides
+ // these with actual values
+ ColumnStats.MinTracker<Long> minTimestampTracker = new ColumnStats.MinTracker<>(Long.MIN_VALUE);
+ ColumnStats.MaxTracker<Long> maxTimestampTracker = new ColumnStats.MaxTracker<>(Long.MAX_VALUE);
StreamingHistogram tombstones = new StreamingHistogram(SSTable.TOMBSTONE_HISTOGRAM_BIN_SIZE);
- int maxLocalDeletionTime = Integer.MIN_VALUE;
+ ColumnStats.MaxTracker<Integer> maxDeletionTimeTracker = new ColumnStats.MaxTracker<>(Integer.MAX_VALUE);
List<ByteBuffer> minColumnNamesSeen = Collections.emptyList();
List<ByteBuffer> maxColumnNamesSeen = Collections.emptyList();
+ boolean hasLegacyCounterShards = false;
if (deletionInfo().getTopLevelDeletion().localDeletionTime < Integer.MAX_VALUE)
+ {
tombstones.update(deletionInfo().getTopLevelDeletion().localDeletionTime);
+ maxDeletionTimeTracker.update(deletionInfo().getTopLevelDeletion().localDeletionTime);
+ minTimestampTracker.update(deletionInfo().getTopLevelDeletion().markedForDeleteAt);
+ maxTimestampTracker.update(deletionInfo().getTopLevelDeletion().markedForDeleteAt);
+ }
Iterator<RangeTombstone> it = deletionInfo().rangeIterator();
while (it.hasNext())
{
RangeTombstone rangeTombstone = it.next();
tombstones.update(rangeTombstone.getLocalDeletionTime());
- minTimestampSeen = Math.min(minTimestampSeen, rangeTombstone.timestamp());
- maxTimestampSeen = Math.max(maxTimestampSeen, rangeTombstone.timestamp());
- minTimestampTracker.update(rangeTombstone.minTimestamp());
- maxTimestampTracker.update(rangeTombstone.maxTimestamp());
++ minTimestampTracker.update(rangeTombstone.timestamp());
++ maxTimestampTracker.update(rangeTombstone.timestamp());
+ maxDeletionTimeTracker.update(rangeTombstone.getLocalDeletionTime());
minColumnNamesSeen = ColumnNameHelper.minComponents(minColumnNamesSeen, rangeTombstone.min, metadata.comparator);
maxColumnNamesSeen = ColumnNameHelper.maxComponents(maxColumnNamesSeen, rangeTombstone.max, metadata.comparator);
}
- for (Column column : this)
+ for (Cell cell : this)
{
- minTimestampSeen = Math.min(minTimestampSeen, cell.timestamp());
- maxTimestampSeen = Math.max(maxTimestampSeen, cell.timestamp());
- maxLocalDeletionTime = Math.max(maxLocalDeletionTime, cell.getLocalDeletionTime());
- minTimestampTracker.update(column.minTimestamp());
- maxTimestampTracker.update(column.maxTimestamp());
- maxDeletionTimeTracker.update(column.getLocalDeletionTime());
- int deletionTime = column.getLocalDeletionTime();
++ minTimestampTracker.update(cell.timestamp());
++ maxTimestampTracker.update(cell.timestamp());
++ maxDeletionTimeTracker.update(cell.getLocalDeletionTime());
++
+ int deletionTime = cell.getLocalDeletionTime();
if (deletionTime < Integer.MAX_VALUE)
tombstones.update(deletionTime);
- minColumnNamesSeen = ColumnNameHelper.minComponents(minColumnNamesSeen, column.name, metadata.comparator);
- maxColumnNamesSeen = ColumnNameHelper.maxComponents(maxColumnNamesSeen, column.name, metadata.comparator);
+ minColumnNamesSeen = ColumnNameHelper.minComponents(minColumnNamesSeen, cell.name(), metadata.comparator);
+ maxColumnNamesSeen = ColumnNameHelper.maxComponents(maxColumnNamesSeen, cell.name(), metadata.comparator);
+ if (cell instanceof CounterCell)
+ hasLegacyCounterShards = hasLegacyCounterShards || ((CounterCell) cell).hasLegacyShards();
}
- return new ColumnStats(getColumnCount(), minTimestampTracker.get(), maxTimestampTracker.get(), maxDeletionTimeTracker.get(), tombstones, minColumnNamesSeen, maxColumnNamesSeen);
+ return new ColumnStats(getColumnCount(),
- minTimestampSeen,
- maxTimestampSeen,
- maxLocalDeletionTime,
++ minTimestampTracker.get(),
++ maxTimestampTracker.get(),
++ maxDeletionTimeTracker.get(),
+ tombstones,
+ minColumnNamesSeen,
+ maxColumnNamesSeen,
+ hasLegacyCounterShards);
}
public boolean isMarkedForDelete()
http://git-wip-us.apache.org/repos/asf/cassandra/blob/97b1d9f6/src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java
index 0ae41ee,2757411..fa59dba
--- a/src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java
+++ b/src/java/org/apache/cassandra/db/compaction/LazilyCompactedRow.java
@@@ -118,14 -109,16 +118,14 @@@ public class LazilyCompactedRow extend
throw new RuntimeException(e);
}
// reach into the reducer (created during iteration) to get column count, size, max column timestamp
- // (however, if there are zero columns, iterator() will not be called by ColumnIndexer and reducer will be null)
- columnStats = new ColumnStats(reducer == null ? 0 : reducer.columns,
- reducer == null ? Long.MAX_VALUE : reducer.minTimestampTracker.get(),
- reducer == null ? emptyColumnFamily.maxTimestamp() : Math.max(emptyColumnFamily.maxTimestamp(), reducer.maxTimestampTracker.get()),
- reducer == null ? Integer.MIN_VALUE : reducer.maxDeletionTimeTracker.get(),
- reducer == null ? new StreamingHistogram(SSTable.TOMBSTONE_HISTOGRAM_BIN_SIZE) : reducer.tombstones,
- reducer == null ? Collections.<ByteBuffer>emptyList() : reducer.minColumnNameSeen,
- reducer == null ? Collections.<ByteBuffer>emptyList() : reducer.maxColumnNameSeen
- );
- reducer = null;
+ columnStats = new ColumnStats(reducer.columns,
- reducer.minTimestampSeen,
- Math.max(emptyColumnFamily.deletionInfo().maxTimestamp(), reducer.maxTimestampSeen),
- reducer.maxLocalDeletionTimeSeen,
++ reducer.minTimestampTracker.get(),
++ Math.max(emptyColumnFamily.deletionInfo().maxTimestamp(), reducer.maxTimestampTracker.get()),
++ reducer.maxDeletionTimeTracker.get(),
+ reducer.tombstones,
+ reducer.minColumnNameSeen,
+ reducer.maxColumnNameSeen,
+ reducer.hasLegacyCounterShards);
// in case no columns were ever written, we may still need to write an empty header with a top-level tombstone
indexBuilder.maybeWriteEmptyRowHeader();
@@@ -201,8 -213,14 +207,15 @@@
StreamingHistogram tombstones = new StreamingHistogram(SSTable.TOMBSTONE_HISTOGRAM_BIN_SIZE);
List<ByteBuffer> minColumnNameSeen = Collections.emptyList();
List<ByteBuffer> maxColumnNameSeen = Collections.emptyList();
+ boolean hasLegacyCounterShards = false;
+ public Reducer()
+ {
+ minTimestampTracker.update(maxRowTombstone.isLive() ? Long.MAX_VALUE : maxRowTombstone.markedForDeleteAt);
+ maxTimestampTracker.update(maxRowTombstone.markedForDeleteAt);
+ maxDeletionTimeTracker.update(maxRowTombstone.isLive() ? Integer.MIN_VALUE : maxRowTombstone.localDeletionTime);
+ }
+
/**
* Called once per version of a cell that we need to merge, after which getReduced() is called. In other words,
* this will be called one or more times with cells that share the same column name.
@@@ -246,10 -267,12 +259,11 @@@
else
{
tombstones.update(t.getLocalDeletionTime());
- minTimestampSeen = Math.min(minTimestampSeen, t.timestamp());
- maxTimestampSeen = Math.max(maxTimestampSeen, t.timestamp());
- minTimestampTracker.update(t.minTimestamp());
- maxTimestampTracker.update(t.maxTimestamp());
++ minTimestampTracker.update(t.timestamp());
++ maxTimestampTracker.update(t.timestamp());
+ maxDeletionTimeTracker.update(t.getLocalDeletionTime());
minColumnNameSeen = ColumnNameHelper.minComponents(minColumnNameSeen, t.min, controller.cfs.metadata.comparator);
maxColumnNameSeen = ColumnNameHelper.maxComponents(maxColumnNameSeen, t.max, controller.cfs.metadata.comparator);
-
return t;
}
}
@@@ -281,11 -297,13 +295,11 @@@
indexer.remove(reduced);
return null;
}
- int localDeletionTime = purged.deletionInfo().getTopLevelDeletion().localDeletionTime;
- if (localDeletionTime < Integer.MAX_VALUE)
- tombstones.update(localDeletionTime);
+
columns++;
- minTimestampSeen = Math.min(minTimestampSeen, reduced.timestamp());
- maxTimestampSeen = Math.max(maxTimestampSeen, reduced.timestamp());
- maxLocalDeletionTimeSeen = Math.max(maxLocalDeletionTimeSeen, reduced.getLocalDeletionTime());
- minTimestampTracker.update(reduced.minTimestamp());
- maxTimestampTracker.update(reduced.maxTimestamp());
++ minTimestampTracker.update(reduced.timestamp());
++ maxTimestampTracker.update(reduced.timestamp());
+ maxDeletionTimeTracker.update(reduced.getLocalDeletionTime());
minColumnNameSeen = ColumnNameHelper.minComponents(minColumnNameSeen, reduced.name(), controller.cfs.metadata.comparator);
maxColumnNameSeen = ColumnNameHelper.maxComponents(maxColumnNameSeen, reduced.name(), controller.cfs.metadata.comparator);
http://git-wip-us.apache.org/repos/asf/cassandra/blob/97b1d9f6/src/java/org/apache/cassandra/io/sstable/ColumnStats.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/io/sstable/ColumnStats.java
index d09f965,446c41c..873aa09
--- a/src/java/org/apache/cassandra/io/sstable/ColumnStats.java
+++ b/src/java/org/apache/cassandra/io/sstable/ColumnStats.java
@@@ -59,6 -51,71 +60,72 @@@ public class ColumnStat
this.tombstoneHistogram = tombstoneHistogram;
this.minColumnNames = minColumnNames;
this.maxColumnNames = maxColumnNames;
+ this.hasLegacyCounterShards = hasLegacyCounterShards;
}
+
+ public static class MinTracker<T extends Comparable<T>>
+ {
+ private final T defaultValue;
+ private boolean isSet = false;
+ private T value;
+
+ public MinTracker(T defaultValue)
+ {
+ this.defaultValue = defaultValue;
+ }
+
+ public void update(T value)
+ {
+ if (!isSet)
+ {
+ this.value = value;
+ isSet = true;
+ }
+ else
+ {
+ if (value.compareTo(this.value) < 0)
+ this.value = value;
+ }
+ }
+
+ public T get()
+ {
+ if (isSet)
+ return value;
+ return defaultValue;
+ }
+ }
+
+ public static class MaxTracker<T extends Comparable<T>>
+ {
+ private final T defaultValue;
+ private boolean isSet = false;
+ private T value;
+
+ public MaxTracker(T defaultValue)
+ {
+ this.defaultValue = defaultValue;
+ }
+
+ public void update(T value)
+ {
+ if (!isSet)
+ {
+ this.value = value;
+ isSet = true;
+ }
+ else
+ {
+ if (value.compareTo(this.value) > 0)
+ this.value = value;
+ }
+ }
+
+ public T get()
+ {
+ if (isSet)
+ return value;
+ return defaultValue;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/97b1d9f6/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
index bfb2445,4619ddc..9e861a1
--- a/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
+++ b/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java
@@@ -251,24 -219,37 +250,29 @@@ public class SSTableWriter extends SSTa
List<ByteBuffer> minColumnNames = Collections.emptyList();
List<ByteBuffer> maxColumnNames = Collections.emptyList();
StreamingHistogram tombstones = new StreamingHistogram(TOMBSTONE_HISTOGRAM_BIN_SIZE);
- ColumnFamily cf = ArrayBackedSortedColumns.factory.create(metadata);
-
- // skip row size for version < ja
- if (version.hasRowSizeAndColumnCount)
- FileUtils.skipBytesFully(in, 8);
+ boolean hasLegacyCounterShards = false;
+ ColumnFamily cf = ArrayBackedSortedColumns.factory.create(metadata);
cf.delete(DeletionTime.serializer.deserialize(in));
- ColumnIndex.Builder columnIndexer = new ColumnIndex.Builder(cf, key.key, dataFile.stream);
-
- // read column count for version < ja
- int columnCount = Integer.MAX_VALUE;
- if (version.hasRowSizeAndColumnCount)
- columnCount = in.readInt();
+ ColumnIndex.Builder columnIndexer = new ColumnIndex.Builder(cf, key.getKey(), dataFile.stream);
if (cf.deletionInfo().getTopLevelDeletion().localDeletionTime < Integer.MAX_VALUE)
+ {
tombstones.update(cf.deletionInfo().getTopLevelDeletion().localDeletionTime);
+ maxDeletionTimeTracker.update(cf.deletionInfo().getTopLevelDeletion().localDeletionTime);
+ minTimestampTracker.update(cf.deletionInfo().getTopLevelDeletion().markedForDeleteAt);
+ maxTimestampTracker.update(cf.deletionInfo().getTopLevelDeletion().markedForDeleteAt);
+ }
Iterator<RangeTombstone> rangeTombstoneIterator = cf.deletionInfo().rangeIterator();
while (rangeTombstoneIterator.hasNext())
{
RangeTombstone rangeTombstone = rangeTombstoneIterator.next();
tombstones.update(rangeTombstone.getLocalDeletionTime());
- minTimestamp = Math.min(minTimestamp, rangeTombstone.timestamp());
- maxTimestamp = Math.max(maxTimestamp, rangeTombstone.timestamp());
-
- minTimestampTracker.update(rangeTombstone.minTimestamp());
- maxTimestampTracker.update(rangeTombstone.maxTimestamp());
++ minTimestampTracker.update(rangeTombstone.timestamp());
++ maxTimestampTracker.update(rangeTombstone.timestamp());
+ maxDeletionTimeTracker.update(rangeTombstone.getLocalDeletionTime());
minColumnNames = ColumnNameHelper.minComponents(minColumnNames, rangeTombstone.min, metadata.comparator);
maxColumnNames = ColumnNameHelper.maxComponents(maxColumnNames, rangeTombstone.max, metadata.comparator);
}
@@@ -292,12 -267,14 +294,12 @@@
int deletionTime = atom.getLocalDeletionTime();
if (deletionTime < Integer.MAX_VALUE)
- {
tombstones.update(deletionTime);
- minTimestamp = Math.min(minTimestamp, atom.timestamp());
- maxTimestamp = Math.max(maxTimestamp, atom.timestamp());
- }
- minTimestampTracker.update(atom.minTimestamp());
- maxTimestampTracker.update(atom.maxTimestamp());
++ minTimestampTracker.update(atom.timestamp());
++ maxTimestampTracker.update(atom.timestamp());
minColumnNames = ColumnNameHelper.minComponents(minColumnNames, atom.name(), metadata.comparator);
maxColumnNames = ColumnNameHelper.maxComponents(maxColumnNames, atom.name(), metadata.comparator);
- maxLocalDeletionTime = Math.max(maxLocalDeletionTime, atom.getLocalDeletionTime());
+ maxDeletionTimeTracker.update(atom.getLocalDeletionTime());
columnIndexer.add(atom); // This write the atom on disk too
}
@@@ -310,15 -287,14 +312,15 @@@
throw new FSWriteError(e, dataFile.getPath());
}
- sstableMetadataCollector.updateMinTimestamp(minTimestamp)
- .updateMaxTimestamp(maxTimestamp)
- .updateMaxLocalDeletionTime(maxLocalDeletionTime)
- sstableMetadataCollector.updateMinTimestamp(minTimestampTracker.get());
- sstableMetadataCollector.updateMaxTimestamp(maxTimestampTracker.get());
- sstableMetadataCollector.updateMaxLocalDeletionTime(maxDeletionTimeTracker.get());
- sstableMetadataCollector.addRowSize(dataFile.getFilePointer() - currentPosition);
- sstableMetadataCollector.addColumnCount(columnIndexer.writtenAtomCount());
- sstableMetadataCollector.mergeTombstoneHistogram(tombstones);
- sstableMetadataCollector.updateMinColumnNames(minColumnNames);
- sstableMetadataCollector.updateMaxColumnNames(maxColumnNames);
++ sstableMetadataCollector.updateMinTimestamp(minTimestampTracker.get())
++ .updateMaxTimestamp(maxTimestampTracker.get())
++ .updateMaxLocalDeletionTime(maxDeletionTimeTracker.get())
+ .addRowSize(dataFile.getFilePointer() - currentPosition)
+ .addColumnCount(columnIndexer.writtenAtomCount())
+ .mergeTombstoneHistogram(tombstones)
+ .updateMinColumnNames(minColumnNames)
+ .updateMaxColumnNames(maxColumnNames)
+ .updateHasLegacyCounterShards(hasLegacyCounterShards);
afterAppend(key, currentPosition, RowIndexEntry.create(currentPosition, cf.deletionInfo().getTopLevelDeletion(), columnIndexer.build()));
return currentPosition;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/97b1d9f6/test/unit/org/apache/cassandra/cql3/SSTableMetadataTrackingTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/SSTableMetadataTrackingTest.java
index 0000000,9104269..7c3965f
mode 000000,100644..100644
--- a/test/unit/org/apache/cassandra/cql3/SSTableMetadataTrackingTest.java
+++ b/test/unit/org/apache/cassandra/cql3/SSTableMetadataTrackingTest.java
@@@ -1,0 -1,223 +1,160 @@@
+ /*
+ * 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.cql3;
+
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
+ import org.junit.Test;
+
-import org.apache.cassandra.SchemaLoader;
+ import org.apache.cassandra.db.ColumnFamilyStore;
-import org.apache.cassandra.db.ConsistencyLevel;
+ import org.apache.cassandra.db.Keyspace;
-import org.apache.cassandra.gms.Gossiper;
-import org.apache.cassandra.io.sstable.SSTableMetadata;
-import org.apache.cassandra.service.ClientState;
-import static org.apache.cassandra.cql3.QueryProcessor.process;
-import static org.apache.cassandra.cql3.QueryProcessor.processInternal;
++import org.apache.cassandra.io.sstable.metadata.StatsMetadata;
+ import static org.junit.Assert.assertEquals;
+
-public class SSTableMetadataTrackingTest
++public class SSTableMetadataTrackingTest extends CQLTester
+ {
- private static String keyspace = "sstable_metadata_tracking_test";
- private static ClientState clientState;
-
- @BeforeClass
- public static void setup() throws Throwable
- {
- SchemaLoader.loadSchema();
- createKeyspace("CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}");
- clientState = ClientState.forInternalCalls();
- }
-
-
+ @Test
+ public void baseCheck() throws Throwable
+ {
- createTable("CREATE TABLE %s.basecheck (a int, b int, c text, PRIMARY KEY (a, b))");
- ColumnFamilyStore cfs = Keyspace.open(keyspace).getColumnFamilyStore("basecheck");
- execute("INSERT INTO %s.basecheck (a,b,c) VALUES (1,1,'1') using timestamp 9999");
++ createTable("CREATE TABLE %s (a int, b int, c text, PRIMARY KEY (a, b))");
++ ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(currentTable());
++ execute("INSERT INTO %s (a,b,c) VALUES (1,1,'1') using timestamp 9999");
+ cfs.forceBlockingFlush();
- SSTableMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(9999, metadata.minTimestamp);
+ assertEquals(Integer.MAX_VALUE, metadata.maxLocalDeletionTime);
+ cfs.forceMajorCompaction();
+ metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(9999, metadata.minTimestamp);
+ assertEquals(Integer.MAX_VALUE, metadata.maxLocalDeletionTime);
+ }
+
+ @Test
+ public void testMinMaxtimestampRange() throws Throwable
+ {
- createTable("CREATE TABLE %s.minmaxtsrange (a int, b int, c text, PRIMARY KEY (a, b))");
- ColumnFamilyStore cfs = Keyspace.open(keyspace).getColumnFamilyStore("minmaxtsrange");
- execute("INSERT INTO %s.minmaxtsrange (a,b,c) VALUES (1,1,'1') using timestamp 10000");
- execute("DELETE FROM %s.minmaxtsrange USING TIMESTAMP 9999 WHERE a = 1 and b = 1");
++ createTable("CREATE TABLE %s (a int, b int, c text, PRIMARY KEY (a, b))");
++ ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(currentTable());
++ execute("INSERT INTO %s (a,b,c) VALUES (1,1,'1') using timestamp 10000");
++ execute("DELETE FROM %s USING TIMESTAMP 9999 WHERE a = 1 and b = 1");
+ cfs.forceBlockingFlush();
- SSTableMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(9999, metadata.minTimestamp);
+ assertEquals(10000, metadata.maxTimestamp);
+ assertEquals(Integer.MAX_VALUE, metadata.maxLocalDeletionTime, 5);
+ cfs.forceMajorCompaction();
+ metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(9999, metadata.minTimestamp);
+ assertEquals(10000, metadata.maxTimestamp);
+ assertEquals(Integer.MAX_VALUE, metadata.maxLocalDeletionTime, 5);
+ }
+
+ @Test
+ public void testMinMaxtimestampRow() throws Throwable
+ {
- createTable("CREATE TABLE %s.minmaxtsrow (a int, b int, c text, PRIMARY KEY (a, b))");
- ColumnFamilyStore cfs = Keyspace.open(keyspace).getColumnFamilyStore("minmaxtsrow");
- execute("INSERT INTO %s.minmaxtsrow (a,b,c) VALUES (1,1,'1') using timestamp 10000");
- execute("DELETE FROM %s.minmaxtsrow USING TIMESTAMP 9999 WHERE a = 1");
++ createTable("CREATE TABLE %s (a int, b int, c text, PRIMARY KEY (a, b))");
++ ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(currentTable());
++ execute("INSERT INTO %s (a,b,c) VALUES (1,1,'1') using timestamp 10000");
++ execute("DELETE FROM %s USING TIMESTAMP 9999 WHERE a = 1");
+ cfs.forceBlockingFlush();
- SSTableMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(9999, metadata.minTimestamp);
+ assertEquals(10000, metadata.maxTimestamp);
+ assertEquals(Integer.MAX_VALUE, metadata.maxLocalDeletionTime, 5);
+ cfs.forceMajorCompaction();
+ metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(9999, metadata.minTimestamp);
+ assertEquals(10000, metadata.maxTimestamp);
+ assertEquals(Integer.MAX_VALUE, metadata.maxLocalDeletionTime, 5);
+ }
+
+
+ @Test
+ public void testTrackMetadata_rangeTombstone() throws Throwable
+ {
- createTable("CREATE TABLE %s.rangetombstone (a int, b int, c text, PRIMARY KEY (a, b)) WITH gc_grace_seconds = 10000");
- ColumnFamilyStore cfs = Keyspace.open(keyspace).getColumnFamilyStore("rangetombstone");
- execute("DELETE FROM %s.rangetombstone USING TIMESTAMP 9999 WHERE a = 1 and b = 1");
++ createTable("CREATE TABLE %s (a int, b int, c text, PRIMARY KEY (a, b)) WITH gc_grace_seconds = 10000");
++ ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(currentTable());
++ execute("DELETE FROM %s USING TIMESTAMP 9999 WHERE a = 1 and b = 1");
+ cfs.forceBlockingFlush();
+ assertEquals(1, cfs.getSSTables().size());
- SSTableMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(9999, metadata.minTimestamp);
+ assertEquals(9999, metadata.maxTimestamp);
+ assertEquals(System.currentTimeMillis()/1000, metadata.maxLocalDeletionTime, 5);
+ cfs.forceMajorCompaction();
- SSTableMetadata metadata2 = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata2 = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(metadata.maxLocalDeletionTime, metadata2.maxLocalDeletionTime);
+ assertEquals(metadata.minTimestamp, metadata2.minTimestamp);
+ assertEquals(metadata.maxTimestamp, metadata2.maxTimestamp);
+ }
+
+ @Test
+ public void testTrackMetadata_rowTombstone() throws Throwable
+ {
- createTable("CREATE TABLE %s.rowtombstone (a int, b int, c text, PRIMARY KEY (a, b))");
- ColumnFamilyStore cfs = Keyspace.open(keyspace).getColumnFamilyStore("rowtombstone");
- execute("DELETE FROM %s.rowtombstone USING TIMESTAMP 9999 WHERE a = 1");
++ createTable("CREATE TABLE %s (a int, b int, c text, PRIMARY KEY (a, b))");
++ ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(currentTable());
++ execute("DELETE FROM %s USING TIMESTAMP 9999 WHERE a = 1");
+
+ cfs.forceBlockingFlush();
+ assertEquals(1, cfs.getSSTables().size());
- SSTableMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(9999, metadata.minTimestamp);
+ assertEquals(9999, metadata.maxTimestamp);
+ assertEquals(System.currentTimeMillis()/1000, metadata.maxLocalDeletionTime, 5);
+ cfs.forceMajorCompaction();
- SSTableMetadata metadata2 = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata2 = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(metadata.maxLocalDeletionTime, metadata2.maxLocalDeletionTime);
+ assertEquals(metadata.minTimestamp, metadata2.minTimestamp);
+ assertEquals(metadata.maxTimestamp, metadata2.maxTimestamp);
+ }
+
+ @Test
+ public void testTrackMetadata_rowMarker() throws Throwable
+ {
- createTable("CREATE TABLE %s.rowmarker (a int, PRIMARY KEY (a))");
- ColumnFamilyStore cfs = Keyspace.open(keyspace).getColumnFamilyStore("rowmarker");
- execute("INSERT INTO %s.rowmarker (a) VALUES (1) USING TIMESTAMP 9999");
++ createTable("CREATE TABLE %s (a int, PRIMARY KEY (a))");
++ ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(currentTable());
++ execute("INSERT INTO %s (a) VALUES (1) USING TIMESTAMP 9999");
+
+ cfs.forceBlockingFlush();
+ assertEquals(1, cfs.getSSTables().size());
- SSTableMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(9999, metadata.minTimestamp);
+ assertEquals(9999, metadata.maxTimestamp);
+ assertEquals(Integer.MAX_VALUE, metadata.maxLocalDeletionTime);
+ cfs.forceMajorCompaction();
- SSTableMetadata metadata2 = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata2 = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(metadata.maxLocalDeletionTime, metadata2.maxLocalDeletionTime);
+ assertEquals(metadata.minTimestamp, metadata2.minTimestamp);
+ assertEquals(metadata.maxTimestamp, metadata2.maxTimestamp);
+ }
+ @Test
+ public void testTrackMetadata_rowMarkerDelete() throws Throwable
+ {
- createTable("CREATE TABLE %s.rowmarkerdel (a int, PRIMARY KEY (a))");
- ColumnFamilyStore cfs = Keyspace.open(keyspace).getColumnFamilyStore("rowmarkerdel");
- execute("DELETE FROM %s.rowmarkerdel USING TIMESTAMP 9999 WHERE a=1");
++ createTable("CREATE TABLE %s (a int, PRIMARY KEY (a))");
++ ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(currentTable());
++ execute("DELETE FROM %s USING TIMESTAMP 9999 WHERE a=1");
+ cfs.forceBlockingFlush();
+ assertEquals(1, cfs.getSSTables().size());
- SSTableMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(9999, metadata.minTimestamp);
+ assertEquals(9999, metadata.maxTimestamp);
+ assertEquals(System.currentTimeMillis()/1000, metadata.maxLocalDeletionTime, 5);
+ cfs.forceMajorCompaction();
- SSTableMetadata metadata2 = cfs.getSSTables().iterator().next().getSSTableMetadata();
++ StatsMetadata metadata2 = cfs.getSSTables().iterator().next().getSSTableMetadata();
+ assertEquals(metadata.maxLocalDeletionTime, metadata2.maxLocalDeletionTime);
+ assertEquals(metadata.minTimestamp, metadata2.minTimestamp);
+ assertEquals(metadata.maxTimestamp, metadata2.maxTimestamp);
+ }
-
- @AfterClass
- public static void stopGossiper()
- {
- Gossiper.instance.stop();
- }
-
- private static void createKeyspace(String query) throws Throwable
- {
- try
- {
- process(String.format(query, keyspace), ConsistencyLevel.ONE);
- } catch (RuntimeException exc)
- {
- throw exc.getCause();
- }
- }
-
-
- private void createTable(String query) throws Throwable
- {
- try
- {
- process(String.format(query, keyspace), ConsistencyLevel.ONE);
- } catch (RuntimeException exc)
- {
- throw exc.getCause();
- }
- }
-
- private UntypedResultSet execute(String query) throws Throwable
- {
- try
- {
- return processInternal(String.format(query, keyspace));
- } catch (RuntimeException exc)
- {
- if (exc.getCause() != null)
- throw exc.getCause();
- throw exc;
- }
- }
+ }
http://git-wip-us.apache.org/repos/asf/cassandra/blob/97b1d9f6/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/db/RangeTombstoneTest.java
index 45fd61f,4dc7c0b..e266bf6
--- a/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java
+++ b/test/unit/org/apache/cassandra/db/RangeTombstoneTest.java
@@@ -29,33 -24,24 +29,34 @@@ import java.util.TreeSet
import java.util.concurrent.ExecutionException;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterators;
+import org.junit.Test;
+
+import org.apache.cassandra.SchemaLoader;
+import org.apache.cassandra.Util;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.config.IndexType;
import org.apache.cassandra.db.columniterator.OnDiskAtomIterator;
+import org.apache.cassandra.db.compaction.CompactionManager;
import org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy;
-import org.apache.cassandra.db.index.*;
+import org.apache.cassandra.db.composites.CellName;
+import org.apache.cassandra.db.composites.CellNames;
+import org.apache.cassandra.db.composites.Composites;
+import org.apache.cassandra.db.filter.ColumnSlice;
+import org.apache.cassandra.db.filter.IDiskAtomFilter;
+import org.apache.cassandra.db.filter.QueryFilter;
+import org.apache.cassandra.db.filter.SliceQueryFilter;
+import org.apache.cassandra.db.index.PerColumnSecondaryIndex;
+import org.apache.cassandra.db.index.SecondaryIndex;
+import org.apache.cassandra.db.index.SecondaryIndexSearcher;
+import org.apache.cassandra.db.marshal.Int32Type;
import org.apache.cassandra.exceptions.ConfigurationException;
-import org.apache.cassandra.io.sstable.SSTableMetadata;
import org.apache.cassandra.io.sstable.SSTableReader;
-import org.apache.cassandra.thrift.IndexType;
-
-import org.junit.Ignore;
-import org.junit.Test;
-
-import org.apache.cassandra.SchemaLoader;
-import org.apache.cassandra.Util;
-import org.apache.cassandra.db.compaction.CompactionManager;
-import org.apache.cassandra.db.filter.*;
++import org.apache.cassandra.io.sstable.metadata.StatsMetadata;
import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.utils.concurrent.OpOrder;
+import org.apache.cassandra.utils.memory.MemtableAllocator;
import static org.apache.cassandra.Util.dk;
import static org.junit.Assert.assertEquals;
@@@ -120,112 -106,104 +121,205 @@@ public class RangeTombstoneTest extend
cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(7), b(30), false, Integer.MAX_VALUE, System.currentTimeMillis()));
for (int i : new int[]{ 7, 8, 9, 11, 13, 15, 17, 28, 29, 30 })
- assert isLive(cf, cf.getColumn(b(i))) : "Column " + i + " should be live";
+ assert isLive(cf, cf.getColumn(b(i))) : "Cell " + i + " should be live";
for (int i : new int[]{ 10, 12, 14, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 })
- assert !isLive(cf, cf.getColumn(b(i))) : "Column " + i + " shouldn't be live";
+ assert !isLive(cf, cf.getColumn(b(i))) : "Cell " + i + " shouldn't be live";
+ }
+
+ @Test
+ public void rangeTombstoneFilteringTest() throws Exception
+ {
+ CompactionManager.instance.disableAutoCompaction();
+ Keyspace keyspace = Keyspace.open(KSNAME);
+ ColumnFamilyStore cfs = keyspace.getColumnFamilyStore(CFNAME);
+
+ // Inserting data
+ String key = "k111";
+ Mutation rm;
+ ColumnFamily cf;
+
+ rm = new Mutation(KSNAME, ByteBufferUtil.bytes(key));
+ for (int i = 0; i < 40; i += 2)
+ add(rm, i, 0);
+ rm.apply();
+
+ rm = new Mutation(KSNAME, ByteBufferUtil.bytes(key));
+ cf = rm.addOrGet(CFNAME);
+ delete(cf, 5, 10, 1);
+ rm.apply();
+
+ rm = new Mutation(KSNAME, ByteBufferUtil.bytes(key));
+ cf = rm.addOrGet(CFNAME);
+ delete(cf, 15, 20, 2);
+ rm.apply();
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(11), b(14), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ Collection<RangeTombstone> rt = rangeTombstones(cf);
+ assertEquals(0, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(11), b(15), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(1, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(20), b(25), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(1, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(12), b(25), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(1, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(25), b(35), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(0, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(1), b(40), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(2, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(7), b(17), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(2, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(5), b(20), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(2, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(5), b(15), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(2, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(1), b(2), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(0, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(1), b(5), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(1, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(1), b(10), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(1, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(5), b(6), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(1, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(17), b(20), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(1, rt.size());
+
+ cf = cfs.getColumnFamily(QueryFilter.getSliceFilter(dk(key), CFNAME, b(17), b(18), false, Integer.MAX_VALUE, System.currentTimeMillis()));
+ rt = rangeTombstones(cf);
+ assertEquals(1, rt.size());
+
+ ColumnSlice[] slices = new ColumnSlice[]{new ColumnSlice( b(1), b(10)), new ColumnSlice( b(16), b(20))};
+ IDiskAtomFilter sqf = new SliceQueryFilter(slices, false, Integer.MAX_VALUE);
+ cf = cfs.getColumnFamily( new QueryFilter(dk(key), CFNAME, sqf, System.currentTimeMillis()) );
+ rt = rangeTombstones(cf);
+ assertEquals(2, rt.size());
+ }
+
+ private Collection<RangeTombstone> rangeTombstones(ColumnFamily cf)
+ {
+ List<RangeTombstone> tombstones = new ArrayList<RangeTombstone>();
+ Iterators.addAll(tombstones, cf.deletionInfo().rangeIterator());
+ return tombstones;
}
+ @Test
+ public void testTrackTimesRowTombstone() throws ExecutionException, InterruptedException
+ {
+ Keyspace ks = Keyspace.open(KSNAME);
+ ColumnFamilyStore cfs = ks.getColumnFamilyStore(CFNAME);
+ cfs.truncateBlocking();
+ String key = "rt_times";
- RowMutation rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key));
++ Mutation rm = new Mutation(KSNAME, ByteBufferUtil.bytes(key));
+ ColumnFamily cf = rm.addOrGet(CFNAME);
+ long timestamp = System.currentTimeMillis();
+ cf.delete(new DeletionInfo(1000, (int)(timestamp/1000)));
+ rm.apply();
+ cfs.forceBlockingFlush();
+ SSTableReader sstable = cfs.getSSTables().iterator().next();
+ assertTimes(sstable.getSSTableMetadata(), 1000, 1000, (int)(timestamp/1000));
+ cfs.forceMajorCompaction();
+ sstable = cfs.getSSTables().iterator().next();
+ assertTimes(sstable.getSSTableMetadata(), 1000, 1000, (int)(timestamp/1000));
+ }
+
+ @Test
+ public void testTrackTimesRowTombstoneWithData() throws ExecutionException, InterruptedException
+ {
+ Keyspace ks = Keyspace.open(KSNAME);
+ ColumnFamilyStore cfs = ks.getColumnFamilyStore(CFNAME);
+ cfs.truncateBlocking();
+ String key = "rt_times";
- RowMutation rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key));
++ Mutation rm = new Mutation(KSNAME, ByteBufferUtil.bytes(key));
+ add(rm, 5, 999);
+ rm.apply();
+ key = "rt_times2";
- rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key));
++ rm = new Mutation(KSNAME, ByteBufferUtil.bytes(key));
+ ColumnFamily cf = rm.addOrGet(CFNAME);
+ int timestamp = (int)(System.currentTimeMillis()/1000);
+ cf.delete(new DeletionInfo(1000, timestamp));
+ rm.apply();
+ cfs.forceBlockingFlush();
+ SSTableReader sstable = cfs.getSSTables().iterator().next();
+ assertTimes(sstable.getSSTableMetadata(), 999, 1000, Integer.MAX_VALUE);
+ cfs.forceMajorCompaction();
+ sstable = cfs.getSSTables().iterator().next();
+ assertTimes(sstable.getSSTableMetadata(), 999, 1000, Integer.MAX_VALUE);
+ }
+ @Test
+ public void testTrackTimesRangeTombstone() throws ExecutionException, InterruptedException
+ {
+ Keyspace ks = Keyspace.open(KSNAME);
+ ColumnFamilyStore cfs = ks.getColumnFamilyStore(CFNAME);
+ cfs.truncateBlocking();
+ String key = "rt_times";
- RowMutation rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key));
++ Mutation rm = new Mutation(KSNAME, ByteBufferUtil.bytes(key));
+ ColumnFamily cf = rm.addOrGet(CFNAME);
+ long timestamp = System.currentTimeMillis();
+ cf.delete(new DeletionInfo(b(1), b(2), cfs.getComparator(), 1000, (int)(timestamp/1000)));
+ rm.apply();
+ cfs.forceBlockingFlush();
+ SSTableReader sstable = cfs.getSSTables().iterator().next();
+ assertTimes(sstable.getSSTableMetadata(), 1000, 1000, (int)(timestamp/1000));
+ cfs.forceMajorCompaction();
+ sstable = cfs.getSSTables().iterator().next();
+ assertTimes(sstable.getSSTableMetadata(), 1000, 1000, (int)(timestamp/1000));
+ }
+
+ @Test
+ public void testTrackTimesRangeTombstoneWithData() throws ExecutionException, InterruptedException
+ {
+ Keyspace ks = Keyspace.open(KSNAME);
+ ColumnFamilyStore cfs = ks.getColumnFamilyStore(CFNAME);
+ cfs.truncateBlocking();
+ String key = "rt_times";
- RowMutation rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key));
++ Mutation rm = new Mutation(KSNAME, ByteBufferUtil.bytes(key));
+ add(rm, 5, 999);
+ rm.apply();
+ key = "rt_times2";
- rm = new RowMutation(KSNAME, ByteBufferUtil.bytes(key));
++ rm = new Mutation(KSNAME, ByteBufferUtil.bytes(key));
+ ColumnFamily cf = rm.addOrGet(CFNAME);
+ int timestamp = (int)(System.currentTimeMillis()/1000);
+ cf.delete(new DeletionInfo(b(1), b(2), cfs.getComparator(), 1000, timestamp));
+ rm.apply();
+ cfs.forceBlockingFlush();
+ SSTableReader sstable = cfs.getSSTables().iterator().next();
+ assertTimes(sstable.getSSTableMetadata(), 999, 1000, Integer.MAX_VALUE);
+ cfs.forceMajorCompaction();
+ sstable = cfs.getSSTables().iterator().next();
+ assertTimes(sstable.getSSTableMetadata(), 999, 1000, Integer.MAX_VALUE);
+ }
+
- private void assertTimes(SSTableMetadata metadata, long min, long max, int localDeletionTime)
++ private void assertTimes(StatsMetadata metadata, long min, long max, int localDeletionTime)
+ {
+ assertEquals(min, metadata.minTimestamp);
+ assertEquals(max, metadata.maxTimestamp);
+ assertEquals(localDeletionTime, metadata.maxLocalDeletionTime);
+ }
@Test
public void test7810() throws ExecutionException, InterruptedException, IOException