Author: jbellis
Date: Thu Aug 5 12:39:51 2010
New Revision: 982580
URL: http://svn.apache.org/viewvc?rev=982580&view=rev
Log:
backport fix from #1156 to fix range queries better; see CASSANDRA-1042
Modified:
cassandra/branches/cassandra-0.6/CHANGES.txt
cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageProxy.java
Modified: cassandra/branches/cassandra-0.6/CHANGES.txt
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/CHANGES.txt?rev=982580&r1=982579&r2=982580&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.6/CHANGES.txt Thu Aug 5 12:39:51 2010
@@ -1,4 +1,5 @@
0.6.5
+ * fix for range query starting with the wrong token range (CASSANDRA-1042)
* page within a single row during hinted handoff (CASSANDRA-1327)
* fix compilation on non-sun JKDs (CASSANDRA-1061)
* remove String.trim() call on row keys in batch mutations (CASSANDRA-1235)
Modified:
cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageProxy.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageProxy.java?rev=982580&r1=982579&r2=982580&view=diff
==============================================================================
---
cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageProxy.java
(original)
+++
cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageProxy.java
Thu Aug 5 12:39:51 2010
@@ -553,7 +553,7 @@ public class StorageProxy implements Sto
// now scan until we have enough results
List<Row> rows = new ArrayList<Row>(command.max_keys);
- for (AbstractBounds range : getRangeIterator(ranges,
command.range.left))
+ for (AbstractBounds range : ranges)
{
List<InetAddress> liveEndpoints =
StorageService.instance.getLiveNaturalEndpoints(command.keyspace, range.right);
if (liveEndpoints.size() < responseCount)
@@ -601,43 +601,6 @@ public class StorageProxy implements Sto
}
/**
- * returns an iterator that will return ranges in ring order, starting
with the one that contains the start token
- */
- private static Iterable<AbstractBounds> getRangeIterator(final
List<AbstractBounds> ranges, Token start)
- {
- // find the one to start with
- int i;
- for (i = 0; i < ranges.size(); i++)
- {
- AbstractBounds range = ranges.get(i);
- if (range.contains(start) || range.left.equals(start))
- break;
- }
- AbstractBounds range = ranges.get(i);
- assert range.contains(start) || range.left.equals(start); // make sure
the loop didn't just end b/c ranges were exhausted
-
- // return an iterable that starts w/ the correct range and iterates
the rest in ring order
- final int begin = i;
- return new Iterable<AbstractBounds>()
- {
- public Iterator<AbstractBounds> iterator()
- {
- return new AbstractIterator<AbstractBounds>()
- {
- int n = 0;
-
- protected AbstractBounds computeNext()
- {
- if (n == ranges.size())
- return endOfData();
- return ranges.get((begin + n++) % ranges.size());
- }
- };
- }
- };
- }
-
- /**
* compute all ranges we're going to query, in sorted order, so that we
get the correct results back.
* 1) computing range intersections is necessary because nodes can be
replica destinations for many ranges,
* so if we do not restrict each scan to the specific range we want we
will get duplicate results.
@@ -684,6 +647,15 @@ public class StorageProxy implements Sto
// sort in order that the original query range would see them.
int queryOrder1 = queryRange.left.compareTo(o1.left);
int queryOrder2 = queryRange.left.compareTo(o2.left);
+
+ // check for exact match with query start
+ assert !(queryOrder1 == 0 && queryOrder2 == 0);
+ if (queryOrder1 == 0)
+ return -1;
+ if (queryOrder2 == 0)
+ return 1;
+
+ // order segments in order they should be traversed
if (queryOrder1 < queryOrder2)
return -1; // o1 comes after query start, o2 wraps to after
if (queryOrder1 > queryOrder2)