Range.compareTo() violates the contract of Comparable

patch by jasobrown and blambov for CASSANDRA-11216
This commit is contained in:
Jason Brown 2016-02-26 11:53:03 -08:00
parent 941d13dac8
commit ecbeb0841e
3 changed files with 27 additions and 9 deletions

View File

@ -1,4 +1,5 @@
2.2.6
* Range.compareTo() violates the contract of Comparable (CASSANDRA-11216)
* Avoid NPE when serializing ErrorMessage with null message (CASSANDRA-11167)
* Replacing an aggregate with a new version doesn't reset INITCOND (CASSANDRA-10840)
* (cqlsh) cqlsh cannot be called through symlink (CASSANDRA-11037)

View File

@ -32,6 +32,8 @@ import org.apache.cassandra.utils.Pair;
* A Range is responsible for the tokens between (left, right].
*
* Used by the partitioner and by map/reduce by-token range scans.
*
* Note: this class has a natural ordering that is inconsistent with equals
*/
public class Range<T extends RingPosition<T>> extends AbstractBounds<T> implements Comparable<Range<T>>, Serializable
{
@ -254,18 +256,18 @@ public class Range<T extends RingPosition<T>> extends AbstractBounds<T> implemen
return left.compareTo(right) >= 0;
}
/**
* Note: this class has a natural ordering that is inconsistent with equals
*/
public int compareTo(Range<T> rhs)
{
/*
* If the range represented by the "this" pointer
* is a wrap around then it is the smaller one.
*/
if ( isWrapAround(left, right) )
return -1;
if ( isWrapAround(rhs.left, rhs.right) )
return 1;
boolean lhsWrap = isWrapAround(left, right);
boolean rhsWrap = isWrapAround(rhs.left, rhs.right);
// if one of the two wraps, that's the smaller one.
if (lhsWrap != rhsWrap)
return Boolean.compare(!lhsWrap, !rhsWrap);
// otherwise compare by right.
return right.compareTo(rhs.right);
}

View File

@ -661,4 +661,19 @@ public class RangeTest
{
return new Murmur3Partitioner.LongToken(t);
}
@Test
public void testCompareTo_SameObject_WrapAround()
{
Range<Token> range = r(10, -10);
assertEquals(0, range.compareTo(range));
}
@Test
public void testCompareTo_BothWrapAround()
{
Range<Token> r0 = r(10, -10);
Range<Token> r1 = r(20, -5);
assertNotSame(r0.compareTo(r1), r1.compareTo(r0));
}
}