mirror of https://github.com/apache/cassandra
tombstones take priority over non-tombstones w/ the same timestamp in supercolumn and column. this makes HH management deterministic.
patch by jbellis; reviewed by Jun Rao for CASSANDRA-34 git-svn-id: https://svn.apache.org/repos/asf/incubator/cassandra/trunk@771935 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f17487c541
commit
8dcf76ab27
|
|
@ -198,6 +198,17 @@ public final class Column implements IColumn
|
|||
assert isMarkedForDelete;
|
||||
return ByteBuffer.wrap(value).getInt();
|
||||
}
|
||||
|
||||
// note that we do not call this simply compareTo since it also makes sense to compare Columns by name
|
||||
public long comparePriority(Column o)
|
||||
{
|
||||
if (isMarkedForDelete)
|
||||
{
|
||||
// tombstone always wins ties.
|
||||
return timestamp < o.timestamp ? -1 : 1;
|
||||
}
|
||||
return timestamp - o.timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
class ColumnSerializer implements ICompactSerializer2<IColumn>
|
||||
|
|
@ -302,5 +313,6 @@ class ColumnSerializer implements ICompactSerializer2<IColumn>
|
|||
int size = dis.readInt();
|
||||
dis.skip(size);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ public final class ColumnFamily
|
|||
}
|
||||
else
|
||||
{
|
||||
if (oldColumn.timestamp() <= column.timestamp())
|
||||
if (((Column)oldColumn).comparePriority((Column)column) <= 0)
|
||||
{
|
||||
columns_.put(name, column);
|
||||
size_.addAndGet(column.size());
|
||||
|
|
|
|||
|
|
@ -615,19 +615,25 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean
|
|||
if (cf == null)
|
||||
return null;
|
||||
|
||||
// in case of a timestamp tie, tombstones get priority over non-tombstones.
|
||||
// we want this to be deterministic in general to avoid confusion;
|
||||
// either way (tombstone or non- getting priority) would be fine,
|
||||
// but we picked this way because it makes removing delivered hints
|
||||
// easier for HintedHandoffManager.
|
||||
for (String cname : new ArrayList<String>(cf.getColumns().keySet()))
|
||||
{
|
||||
IColumn c = cf.getColumns().get(cname);
|
||||
if (c instanceof SuperColumn)
|
||||
{
|
||||
long minTimestamp = Math.max(c.getMarkedForDeleteAt(), cf.getMarkedForDeleteAt());
|
||||
// don't operate directly on the supercolumn, it could be the one in the memtable
|
||||
// don't operate directly on the supercolumn, it could be the one in the memtable.
|
||||
// instead, create a new SC and add in the subcolumns that qualify.
|
||||
cf.remove(cname);
|
||||
SuperColumn sc = new SuperColumn(cname);
|
||||
sc.markForDeleteAt(c.getLocalDeletionTime(), c.getMarkedForDeleteAt());
|
||||
for (IColumn subColumn : c.getSubColumns())
|
||||
{
|
||||
if (subColumn.timestamp() >= minTimestamp)
|
||||
if (subColumn.timestamp() > minTimestamp)
|
||||
{
|
||||
if (!subColumn.isMarkedForDelete() || subColumn.getLocalDeletionTime() > gcBefore)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -176,8 +176,8 @@ public final class SuperColumn implements IColumn, Serializable
|
|||
|
||||
public void addColumn(String name, IColumn column)
|
||||
{
|
||||
if ( column instanceof SuperColumn )
|
||||
throw new UnsupportedOperationException("A super column cannot hold other super columns.");
|
||||
if (!(column instanceof Column))
|
||||
throw new UnsupportedOperationException("A super column can only contain simple columns.");
|
||||
IColumn oldColumn = columns_.get(name);
|
||||
if ( oldColumn == null )
|
||||
{
|
||||
|
|
@ -186,7 +186,7 @@ public final class SuperColumn implements IColumn, Serializable
|
|||
}
|
||||
else
|
||||
{
|
||||
if ( oldColumn.timestamp() <= column.timestamp() )
|
||||
if (((Column)oldColumn).comparePriority((Column)column) <= 0)
|
||||
{
|
||||
columns_.put(name, column);
|
||||
int delta = (-1)*oldColumn.size();
|
||||
|
|
|
|||
Loading…
Reference in New Issue