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");