Author: jbellis
Date: Sat Aug 21 16:51:11 2010
New Revision: 987788
URL: http://svn.apache.org/viewvc?rev=987788&view=rev
Log:
fix Clock regression in handling timestamp ties (tombstone takes precedence,
then column w/ higher value. patch by jbellis
Modified:
cassandra/trunk/src/java/org/apache/cassandra/db/Column.java
cassandra/trunk/src/java/org/apache/cassandra/db/clock/TimestampReconciler.java
cassandra/trunk/test/unit/org/apache/cassandra/db/ColumnFamilyTest.java
Modified: cassandra/trunk/src/java/org/apache/cassandra/db/Column.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/Column.java?rev=987788&r1=987787&r2=987788&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/db/Column.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/db/Column.java Sat Aug 21
16:51:11 2010
@@ -171,49 +171,6 @@ public class Column implements IColumn
throw new IllegalStateException("column is not marked for delete");
}
- // note that we do not call this simply compareTo since it also makes
sense to compare Columns by name
- public ClockRelationship comparePriority(Column o)
- {
- ClockRelationship rel = clock.compare(o.clock());
-
- // tombstone always wins ties.
- if (isMarkedForDelete())
- {
- switch (rel)
- {
- case EQUAL:
- return ClockRelationship.GREATER_THAN;
- default:
- return rel;
- }
- }
- if (o.isMarkedForDelete())
- {
- switch (rel)
- {
- case EQUAL:
- return ClockRelationship.LESS_THAN;
- default:
- return rel;
- }
- }
-
- // compare value as tie-breaker for equal clocks
- if (ClockRelationship.EQUAL == rel)
- {
- int valRel = FBUtilities.compareByteArrays(value, o.value);
- if (1 == valRel)
- return ClockRelationship.GREATER_THAN;
- if (0 == valRel)
- return ClockRelationship.EQUAL;
- // -1 == valRel
- return ClockRelationship.LESS_THAN;
- }
-
- // neither is tombstoned and clocks are different
- return rel;
- }
-
@Override
public boolean equals(Object o)
{
Modified:
cassandra/trunk/src/java/org/apache/cassandra/db/clock/TimestampReconciler.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/clock/TimestampReconciler.java?rev=987788&r1=987787&r2=987788&view=diff
==============================================================================
---
cassandra/trunk/src/java/org/apache/cassandra/db/clock/TimestampReconciler.java
(original)
+++
cassandra/trunk/src/java/org/apache/cassandra/db/clock/TimestampReconciler.java
Sat Aug 21 16:51:11 2010
@@ -19,6 +19,7 @@ package org.apache.cassandra.db.clock;
import org.apache.cassandra.db.Column;
import org.apache.cassandra.db.IClock.ClockRelationship;
+import org.apache.cassandra.utils.FBUtilities;
/**
* Keeps the column with the highest timestamp. If both are equal
@@ -37,6 +38,13 @@ public final class TimestampReconciler e
switch (cr)
{
case EQUAL:
+ // tombstones take precedence. (if both are tombstones, then it
doesn't matter which one we use.)
+ if (left.isMarkedForDelete())
+ return left;
+ if (right.isMarkedForDelete())
+ return right;
+ // break ties by comparing values.
+ return FBUtilities.compareByteArrays(left.value(), right.value())
< 0 ? right : left;
case GREATER_THAN:
return left;
case LESS_THAN:
Modified:
cassandra/trunk/test/unit/org/apache/cassandra/db/ColumnFamilyTest.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/db/ColumnFamilyTest.java?rev=987788&r1=987787&r2=987788&view=diff
==============================================================================
--- cassandra/trunk/test/unit/org/apache/cassandra/db/ColumnFamilyTest.java
(original)
+++ cassandra/trunk/test/unit/org/apache/cassandra/db/ColumnFamilyTest.java Sat
Aug 21 16:51:11 2010
@@ -129,5 +129,17 @@ public class ColumnFamilyTest extends Sc
assert 3 == cf_result.getColumnCount() : "Count is " +
cf_new.getColumnCount();
//addcolumns will only add if timestamp >= old timestamp
assert Arrays.equals(val,
cf_result.getColumn("col2".getBytes()).value());
+
+ // check that tombstone wins timestamp ties
+ cf_result.deleteColumn("col1".getBytes(), 0, new TimestampClock(3));
+ assert cf_result.getColumn("col1".getBytes()).isMarkedForDelete();
+ cf_result.addColumn(QueryPath.column("col1".getBytes()), val2, new
TimestampClock(3));
+ assert cf_result.getColumn("col1".getBytes()).isMarkedForDelete();
+
+ // check that column value wins timestamp ties in absence of tombstone
+ cf_result.addColumn(QueryPath.column("col3".getBytes()), val, new
TimestampClock(2));
+ assert Arrays.equals(cf_result.getColumn("col3".getBytes()).value(),
val2);
+ cf_result.addColumn(QueryPath.column("col3".getBytes()),
"z".getBytes(), new TimestampClock(2));
+ assert Arrays.equals(cf_result.getColumn("col3".getBytes()).value(),
"z".getBytes());
}
}