Skip to content

Commit

Permalink
backport fix from #1156 to fix range queries better; see CASSANDRA-1042
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.apache.org/repos/asf/cassandra/branches/cassandra-0.6@982580 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
jbellis committed Aug 5, 2010
1 parent 0651bc5 commit ab00a16
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 38 deletions.
1 change: 1 addition & 0 deletions CHANGES.txt
@@ -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)
Expand Down
48 changes: 10 additions & 38 deletions src/java/org/apache/cassandra/service/StorageProxy.java
Expand Up @@ -553,7 +553,7 @@ public static List<Row> getRangeSlice(RangeSliceCommand command, ConsistencyLeve

// 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)
Expand Down Expand Up @@ -600,43 +600,6 @@ public static List<Row> getRangeSlice(RangeSliceCommand command, ConsistencyLeve
return rows.size() > command.max_keys ? rows.subList(0, command.max_keys) : rows;
}

/**
* 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,
Expand Down Expand Up @@ -684,6 +647,15 @@ public int compare(AbstractBounds o1, AbstractBounds o2)
// 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)
Expand Down

0 comments on commit ab00a16

Please sign in to comment.