You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2012/07/10 19:07:02 UTC

[5/6] git commit: fix mixing user-provided timestamps and local deletion time for #4396

fix mixing user-provided timestamps and local deletion time for #4396


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

Branch: refs/heads/cassandra-1.1
Commit: 84a1d6059bbaab375817a33179bb8de63121176b
Parents: 5bcfcbc
Author: Jonathan Ellis <jb...@apache.org>
Authored: Tue Jul 10 08:35:23 2012 -0500
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Tue Jul 10 08:35:23 2012 -0500

----------------------------------------------------------------------
 .../cassandra/db/AbstractColumnContainer.java      |    3 +-
 .../cassandra/db/compaction/CompactionsTest.java   |   40 +++++++++++++++
 2 files changed, 42 insertions(+), 1 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/84a1d605/src/java/org/apache/cassandra/db/AbstractColumnContainer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/AbstractColumnContainer.java b/src/java/org/apache/cassandra/db/AbstractColumnContainer.java
index af8a010..439c5e4 100644
--- a/src/java/org/apache/cassandra/db/AbstractColumnContainer.java
+++ b/src/java/org/apache/cassandra/db/AbstractColumnContainer.java
@@ -256,8 +256,9 @@ public abstract class AbstractColumnContainer implements IColumnContainer, IIter
         if (isMarkedForDelete() && getLocalDeletionTime() < gcBefore)
             return true;
 
+        long deletedAt = getMarkedForDeleteAt();
         for (IColumn column : columns)
-            if (column.mostRecentLiveChangeAt() < getLocalDeletionTime() || column.hasIrrelevantData(gcBefore))
+            if (column.mostRecentLiveChangeAt() <= deletedAt || column.hasIrrelevantData(gcBefore))
                 return true;
 
         return false;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/84a1d605/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java b/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
index 1179919..46c0054 100644
--- a/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
+++ b/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
@@ -35,11 +35,14 @@ import org.apache.cassandra.CleanupHelper;
 import org.apache.cassandra.Util;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.db.*;
+import org.apache.cassandra.db.columniterator.IColumnIterator;
+import org.apache.cassandra.db.columniterator.IdentityQueryFilter;
 import org.apache.cassandra.db.compaction.OperationType;
 import org.apache.cassandra.db.filter.QueryFilter;
 import org.apache.cassandra.db.filter.QueryPath;
 import org.apache.cassandra.io.sstable.*;
 import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.utils.FBUtilities;
 
 public class CompactionsTest extends CleanupHelper
 {
@@ -128,6 +131,43 @@ public class CompactionsTest extends CleanupHelper
         assertMaxTimestamp(store, maxTimestampExpected);
     }
 
+    @Test
+    public void testSuperColumnTombstones() throws IOException, ExecutionException, InterruptedException
+    {
+        Table table = Table.open(TABLE1);
+        ColumnFamilyStore cfs = table.getColumnFamilyStore("Super1");
+        cfs.disableAutoCompaction();
+
+        DecoratedKey key = Util.dk("tskey");
+        ByteBuffer scName = ByteBufferUtil.bytes("TestSuperColumn");
+
+        // a subcolumn
+        RowMutation rm = new RowMutation(TABLE1, key.key);
+        rm.add(new QueryPath("Super1", scName, ByteBufferUtil.bytes(0)),
+               ByteBufferUtil.EMPTY_BYTE_BUFFER,
+               FBUtilities.timestampMicros());
+        rm.apply();
+        cfs.forceBlockingFlush();
+
+        // shadow the subcolumn with a supercolumn tombstone
+        rm = new RowMutation(TABLE1, key.key);
+        rm.delete(new QueryPath("Super1", scName), FBUtilities.timestampMicros());
+        rm.apply();
+        cfs.forceBlockingFlush();
+
+        CompactionManager.instance.performMaximal(cfs);
+        assertEquals(1, cfs.getSSTables().size());
+
+        // check that the shadowed column is gone
+        SSTableReader sstable = cfs.getSSTables().iterator().next();
+        SSTableScanner scanner = sstable.getScanner(new QueryFilter(null, new QueryPath("Super1", scName), new IdentityQueryFilter()));
+        scanner.seekTo(key);
+        IColumnIterator iter = scanner.next();
+        assertEquals(key, iter.getKey());
+        SuperColumn sc = (SuperColumn) iter.next();
+        assert sc.getSubColumns().isEmpty();
+    }
+
     public void assertMaxTimestamp(ColumnFamilyStore store, long maxTimestampExpected)
     {
         long maxTimestampObserved = Long.MIN_VALUE;