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 2011/04/15 16:33:59 UTC

svn commit: r1092722 - in /cassandra/branches/cassandra-0.7: CHANGES.txt src/java/org/apache/cassandra/db/ColumnFamilyStore.java test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java

Author: jbellis
Date: Fri Apr 15 14:33:59 2011
New Revision: 1092722

URL: http://svn.apache.org/viewvc?rev=1092722&view=rev
Log:
fix duplicate results from CFS.scan
patch by Pavel Yaskevich and jbellis for CASSANDRA-2406

Modified:
    cassandra/branches/cassandra-0.7/CHANGES.txt
    cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
    cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java

Modified: cassandra/branches/cassandra-0.7/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/CHANGES.txt?rev=1092722&r1=1092721&r2=1092722&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.7/CHANGES.txt Fri Apr 15 14:33:59 2011
@@ -28,6 +28,7 @@
  * Try harder to close files after compaction (CASSANDRA-2431)
  * re-set bootstrapped flag after move finishes (CASSANDRA-2435)
  * use 64KB flush buffer instead of in_memory_compaction_limit (CASSANDRA-2463)
+ * fix duplicate results from CFS.scan (CASSANDRA-2406)
 
 
 0.7.4

Modified: cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=1092722&r1=1092721&r2=1092722&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java (original)
+++ cassandra/branches/cassandra-0.7/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Fri Apr 15 14:33:59 2011
@@ -1547,6 +1547,10 @@ public class ColumnFamilyStore implement
         ByteBuffer startKey = clause.start_key;
         QueryPath path = new QueryPath(columnFamily);
 
+        // we need to store last data key accessed to avoid duplicate results
+        // because in the while loop new iteration we can access the same column if start_key was not set
+        ByteBuffer lastDataKey = null;
+
         // fetch row keys matching the primary expression, fetch the slice predicate for each
         // and filter by remaining expressions.  repeat until finished w/ assigned range or index row is exhausted.
         outer:
@@ -1578,10 +1582,11 @@ public class ColumnFamilyStore implement
                     continue;
                 dataKey = column.name();
                 n++;
+
                 DecoratedKey dk = partitioner.decorateKey(dataKey);
                 if (!range.right.equals(partitioner.getMinimumToken()) && range.right.compareTo(dk.token) < 0)
                     break outer;
-                if (!range.contains(dk.token))
+                if (!range.contains(dk.token) || dataKey.equals(lastDataKey))
                     continue;
 
                 // get the row columns requested, and additional columns for the expressions if necessary
@@ -1622,7 +1627,8 @@ public class ColumnFamilyStore implement
             }
             if (n < clause.count || startKey.equals(dataKey))
                 break;
-            startKey = dataKey;
+
+            lastDataKey = startKey = dataKey;
         }
 
         return rows;

Modified: cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java?rev=1092722&r1=1092721&r2=1092722&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java (original)
+++ cassandra/branches/cassandra-0.7/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java Fri Apr 15 14:33:59 2011
@@ -211,6 +211,35 @@ public class ColumnFamilyStoreTest exten
     }
 
     @Test
+    public void testLargeScan() throws IOException
+    {
+        RowMutation rm;
+        for (int i = 0; i < 100; i++)
+        {
+            rm = new RowMutation("Keyspace1", ByteBufferUtil.bytes("key" + i));
+            rm.add(new QueryPath("Indexed1", null, ByteBufferUtil.bytes("birthdate")), ByteBufferUtil.bytes(34L), 0);
+            rm.add(new QueryPath("Indexed1", null, ByteBufferUtil.bytes("notbirthdate")), ByteBufferUtil.bytes((long) (i % 2)), 0);
+            rm.applyUnsafe();
+        }
+
+        IndexExpression expr = new IndexExpression(ByteBufferUtil.bytes("birthdate"), IndexOperator.EQ, ByteBufferUtil.bytes(34L));
+        IndexExpression expr2 = new IndexExpression(ByteBufferUtil.bytes("notbirthdate"), IndexOperator.EQ, ByteBufferUtil.bytes(1L));
+        IndexClause clause = new IndexClause(Arrays.asList(expr, expr2), ByteBufferUtil.EMPTY_BYTE_BUFFER, 100);
+        IFilter filter = new IdentityQueryFilter();
+        IPartitioner p = StorageService.getPartitioner();
+        Range range = new Range(p.getMinimumToken(), p.getMinimumToken());
+        List<Row> rows = Table.open("Keyspace1").getColumnFamilyStore("Indexed1").scan(clause, range, filter);
+
+        assert rows != null;
+        assert rows.size() == 50 : rows.size();
+        Set<DecoratedKey> keys = new HashSet<DecoratedKey>();
+        // extra check that there are no duplicate results -- see https://issues.apache.org/jira/browse/CASSANDRA-2406
+        for (Row row : rows)
+            keys.add(row.key);
+        assert rows.size() == keys.size();
+    }
+
+    @Test
     public void testIndexDeletions() throws IOException
     {
         ColumnFamilyStore cfs = Table.open("Keyspace3").getColumnFamilyStore("Indexed1");