cassandra的删除

在cassandra1.2版本删除以前,删除基本上只有整个Column的删除,整个SuperColumn的删除,整个Rowkey的删除。

在cassandra1.0.6版本中,DeletionInfo只有两个属性:1、markedForDeleteAt,删除的毫秒数,用于判断记录是否有效的;2、localDeletionTime,删除时间的秒数,用于记录是否需要物理删除。

 protected static class DeletionInfo
    {
        public final long markedForDeleteAt;
        public final int localDeletionTime;

        public DeletionInfo()
        {
            this(Long.MIN_VALUE, Integer.MIN_VALUE);
        }

        public DeletionInfo(long markedForDeleteAt, int localDeletionTime)
        {
            this.markedForDeleteAt = markedForDeleteAt;
            this.localDeletionTime = localDeletionTime;
        }
    }


无论是在memtable中保存整个内存数据中的map,map为rowkey对应columnfamily的key-value结构,在columnfamily中有一个ISortedColumn用于存放rowkey下的记录(superCF则是SuperColumn的集合,standCF则是StandCF的集合)。每一条记录都会有自己有效的时间戳timestamp,在ColumnFamily中还有一个DeletionInfo用于标记,这个rowkey何时做过delete,是对于整个rowkey而言的,ISortedColumn中任何一个IColumn的时间戳小于DeletionInfo中的markedForDeleteAt的时候,就可以判断IColumn已经被删除了。supercolumn中集合和DeletionInfo,也是相同的作用,用于处理supername级的删除。



cassandra1.2中,DeletionInfo已经做出了很大的改动了,将整体记录(无论是row还是superColumn)的删除,都增强为范围删除。

1、DeletionInfo的属性已经改变为:

(1)topLevel是DeletionTime相当于以前版本的DeletionInfo,DeletionTime中也有markedForDeleteAt和localDeletionTime。

(2)ranges是IntervalTree的树,表示RangeTomstone里面有开始的值start,结束值end,删除标记DeletionTime,这棵树可以找到一个值所在范围的删除标记。


private static final Serializer serializer = new Serializer();

    // We don't have way to represent the full interval of keys (Interval don't support the minimum token as the right bound),
    // so we keep the topLevel deletion info separatly. This also slightly optimize the case of full row deletion which is rather common.
    private final DeletionTime topLevel;
    private final IntervalTree ranges;

    public static final DeletionInfo LIVE = new DeletionInfo(DeletionTime.LIVE, IntervalTree.emptyTree());

2、DeletionInfo不在是原来版本的两个时间标记,意味着删除多次的时候,不再是简单的覆盖就可以搞定了

删除需要考虑多种情况:

(1)第一次范围删除,就可以直接生成删除标记DeletionInfo

(2)直接进行整条记录的删除,那么这个时候DeletionInfo中只有topLevel,可以比较删除时间,然后保留最新的记录

(3)多次范围删除,topLvel保留最新的删除时间,而将范围删除的树进行hashSet的合并以后重新生成。

/**
     * Returns a new DeletionInfo containing of this plus the provided {@code
     * newInfo}.
     */
    public DeletionInfo add(DeletionInfo newInfo)
    {
        if (ranges.isEmpty())
        {
            return topLevel.markedForDeleteAt < newInfo.topLevel.markedForDeleteAt
                 ? newInfo
                 : newInfo.ranges.isEmpty() ? this : new DeletionInfo(topLevel, newInfo.ranges);
        }
        else
        {
            if (newInfo.ranges.isEmpty())
            {
                return topLevel.markedForDeleteAt < newInfo.topLevel.markedForDeleteAt
                     ? new DeletionInfo(newInfo.topLevel, ranges)
                     : this;
            }
            else
            {
                // Need to merge both ranges
                Set merged = new HashSet();
                Iterables.addAll(merged, Iterables.concat(ranges, newInfo.ranges));
                return new DeletionInfo(topLevel.markedForDeleteAt < newInfo.topLevel.markedForDeleteAt ? newInfo.topLevel : topLevel,
                                        IntervalTree.build(merged, ranges.comparator()));
            }
        }
    }


3、记录有效性的判断。如果记录时间小于整条记录的删除标记,则此记录已经被删除。或者可以找到范围删除标记,判断记录是否被删除

public boolean isDeleted(ByteBuffer name, long timestamp)
    {
        if (isLive())
            return false;
        if (timestamp <= topLevel.markedForDeleteAt)
            return true;

        for (DeletionTime d : ranges.search(name))
        {
            if (timestamp <= d.markedForDeleteAt)
                return true;
        }
        return false;
    }


测试一下DeletionInfo的各种表现

public class TestDeletionInfo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		RangeTombstone stone1 = new RangeTombstone(ByteBufferUtil.bytes(0),ByteBufferUtil.bytes(5),new DeletionTime(1L,1));
		DeletionInfo info1 = new DeletionInfo(stone1,BytesType.instance);
		
		RangeTombstone stone2 = new RangeTombstone(ByteBufferUtil.bytes(3),ByteBufferUtil.bytes(5),new DeletionTime(3L,3));
		DeletionInfo info2 = new DeletionInfo(stone2,BytesType.instance);
		
		DeletionInfo info3 = info1.add(info2);
		System.out.println(info3.isDeleted(ByteBufferUtil.bytes(2), 1L));
		System.out.println(info3.isDeleted(ByteBufferUtil.bytes(2), 2L));
		System.out.println(info3.isDeleted(ByteBufferUtil.bytes(3), 2L));
		System.out.println(info3.isDeleted(ByteBufferUtil.bytes(4), 2L));
		System.out.println(info3.isDeleted(ByteBufferUtil.bytes(5), 2L));
	}

}

得到的结果为:

true
false
true
true
true


你可能感兴趣的:(cassandra的删除)