org.apache.cassandra.utils
Class MerkleTree

java.lang.Object
  extended by org.apache.cassandra.utils.MerkleTree
All Implemented Interfaces:
java.io.Serializable

public class MerkleTree
extends java.lang.Object
implements java.io.Serializable

A MerkleTree implemented as a binary tree. A MerkleTree is a full binary tree that represents a perfect binary tree of depth 'hashdepth'. In a perfect binary tree, each leaf contains a sequentially hashed range, and each inner node contains the binary hash of its two children. In the MerkleTree, many ranges will not be split to the full depth of the perfect binary tree: the leaves of this tree are Leaf objects, which contain the computed values of the nodes that would be below them if the tree were perfect. The hash values of the inner nodes of the MerkleTree are calculated lazily based on their children when the hash of a range is requested with hash(range). Inputs passed to TreeRange.validate should be calculated using a very secure hash, because all hashing internal to the tree is accomplished using XOR. If two MerkleTrees have the same hashdepth, they represent a perfect tree of the same depth, and can always be compared, regardless of size or splits.

See Also:
Serialized Form

Nested Class Summary
static class MerkleTree.RowHash
          Hash value representing a row, to be used to pass hashes to the MerkleTree.
static class MerkleTree.TreeRange
          The public interface to a range in the tree.
static class MerkleTree.TreeRangeIterator
          Performs a depth-first, inorder traversal of invalid nodes under the given root and intersecting the given range.
 
Field Summary
static int CONSISTENT
           
static int FULLY_INCONSISTENT
           
 byte hashdepth
           
static int PARTIALLY_INCONSISTENT
           
static byte RECOMMENDED_DEPTH
           
 
Constructor Summary
MerkleTree(IPartitioner partitioner, byte hashdepth, long maxsize)
           
 
Method Summary
 void compact(Token t)
          Compacts the smallest subranges evenly split by the given token into a single range.
static java.util.List<MerkleTree.TreeRange> difference(MerkleTree ltree, MerkleTree rtree)
           
 byte[] hash(Range range)
          Hash the given range in the tree.
 void init()
          Initializes this tree by splitting it until hashdepth is reached, or until an additional level of splits would violate maxsize.
 void invalidate(Token t)
          Invalidates the ranges containing the given token.
 MerkleTree.TreeRangeIterator invalids(Range range)
          Returns a lazy iterator of invalid TreeRanges that need to be filled in order to make the given Range valid.
 long maxsize()
           
 void maxsize(long maxsize)
           
 IPartitioner partitioner()
           
 void partitioner(IPartitioner partitioner)
          TODO: Find another way to use the local partitioner after serialization.
 long size()
          The number of distinct ranges contained in this tree.
 boolean split(Token t)
          Splits the range containing the given token, if no tree limits would be violated.
 java.lang.String toString()
           
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

RECOMMENDED_DEPTH

public static final byte RECOMMENDED_DEPTH
See Also:
Constant Field Values

CONSISTENT

public static final int CONSISTENT
See Also:
Constant Field Values

FULLY_INCONSISTENT

public static final int FULLY_INCONSISTENT
See Also:
Constant Field Values

PARTIALLY_INCONSISTENT

public static final int PARTIALLY_INCONSISTENT
See Also:
Constant Field Values

hashdepth

public final byte hashdepth
Constructor Detail

MerkleTree

public MerkleTree(IPartitioner partitioner,
                  byte hashdepth,
                  long maxsize)
Parameters:
partitioner - The partitioner in use.
hashdepth - The maximum depth of the tree. 100/(2^depth) is the % of the key space covered by each subrange of a fully populated tree.
maxsize - The maximum number of subranges in the tree.
Method Detail

init

public void init()
Initializes this tree by splitting it until hashdepth is reached, or until an additional level of splits would violate maxsize. NB: Replaces all nodes in the tree.


partitioner

public IPartitioner partitioner()

size

public long size()
The number of distinct ranges contained in this tree. This is a reasonable measure of the memory usage of the tree (assuming 'this.order' is significant).


maxsize

public long maxsize()

maxsize

public void maxsize(long maxsize)

partitioner

public void partitioner(IPartitioner partitioner)
TODO: Find another way to use the local partitioner after serialization.


difference

public static java.util.List<MerkleTree.TreeRange> difference(MerkleTree ltree,
                                                              MerkleTree rtree)
Parameters:
ltree - First tree.
rtree - Second tree.
Returns:
A list of the largest contiguous ranges where the given trees disagree.

invalidate

public void invalidate(Token t)
Invalidates the ranges containing the given token.


hash

public byte[] hash(Range range)
Hash the given range in the tree. The range must have been generated with recursive applications of partitioner.midpoint(). NB: Currently does not support wrapping ranges that do not end with partitioner.getMinimumToken().

Returns:
Null if any subrange of the range is invalid, or if the exact range cannot be calculated using this tree.

split

public boolean split(Token t)
Splits the range containing the given token, if no tree limits would be violated. If the range would be split to a depth below hashdepth, or if the tree already contains maxsize subranges, this operation will fail.

Returns:
True if the range was successfully split.

compact

public void compact(Token t)
Compacts the smallest subranges evenly split by the given token into a single range. Asserts that the given Token falls between two compactable subranges.


invalids

public MerkleTree.TreeRangeIterator invalids(Range range)
Returns a lazy iterator of invalid TreeRanges that need to be filled in order to make the given Range valid.

Parameters:
range - The range to find invalid subranges for.

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object


Copyright © 2010 The Apache Software Foundation