com.bigdata.btree
Class Leaf

java.lang.Object
  extended by com.bigdata.btree.PO
      extended by com.bigdata.btree.AbstractNode<Leaf>
          extended by com.bigdata.btree.Leaf
All Implemented Interfaces:
IAbstractNodeData, ILeafData, IAbstractNode, IDirty, IIdentityAccess, IDataRecordAccess
Direct Known Subclasses:
IndexSegment.ImmutableNodeFactory.ImmutableLeaf

public class Leaf
extends AbstractNode<Leaf>
implements ILeafData

A B+-Tree leaf.

Tuple revision timestamps

When tuple revision timestamps are maintained, they must be propagated to the parents if we insert or remove a tuple, but also need to be propagated if we update a tuple in a manner which changes the min/max version timestamp. This is done either by Node.updateEntryCount(AbstractNode, int), when the #of tuples in the leaf was changed, or by Node.updateMinMaxVersionTimestamp(AbstractNode) when the #of tuples in the leaf is unchanged.

The getMinimumVersionTimestamp() and getMaximumVersionTimestamp() can be used to efficiently filter iterators so as to only visit those nodes and leaves which have updates for some revision timestamp range. This filtering is effective because if we reject a node has not having data for the revision range of interest, then we do not need to consider any of the nodes or leaves spanned by that node.

Note that revision timestamps ARE NOT commit timestamps. See ITransactionService and IsolatedFusedView for more about this and how to obtain and work with revision timestamps.

Version:
$Id: Leaf.java 2265 2009-10-26 12:51:06Z thompsonbry $
Author:
Bryan Thompson

Nested Class Summary
static interface Leaf.ILeafListener
          An interface that may be used to register for and receive events when the state of a Leaf is changed.
 
Field Summary
 
Fields inherited from class com.bigdata.btree.AbstractNode
btree, INFO, log, parent, referenceCount, self
 
Fields inherited from class com.bigdata.btree.PO
deleted, dirty, identity
 
Fields inherited from interface com.bigdata.btree.IIdentityAccess
NULL
 
Constructor Summary
protected Leaf(AbstractBTree btree)
          Creates a new mutable leaf.
protected Leaf(AbstractBTree btree, long addr, ILeafData data)
          De-serialization constructor.
protected Leaf(Leaf src)
          Copy constructor.
 
Method Summary
 void addLeafListener(Leaf.ILeafListener l)
          Register an Leaf.ILeafListener with this Leaf.
protected  void copyDown(int entryIndex, int count)
          Copies all keys and values from the specified start index down by one in order to make room to insert a key and value at that index.
 AbstractFixedByteArrayBuffer data()
          The coded (aka compressed) data.
 void delete()
          Deletes the persistence capable object.
 boolean dump(org.apache.log4j.Level level, PrintStream out, int height, boolean recursive)
          Dump the data onto the PrintStream.
 ITupleIterator entryIterator()
          Iterator visits the tuples in this leaf in key order.
protected  void fireInvalidateLeafEvent()
          Fire an Leaf.ILeafListener.invalidateLeaf() event to any registered listeners.
 ILeafData getDelegate()
          Return the delegate IAbstractNodeData object.
 boolean getDeleteMarker(int index)
          Return true iff the entry at the specified index is marked as deleted.
 int getKeyCount()
          Return the #of keys in the node or leaf.
 IRaba getKeys()
          The object used to contain and manage the keys.
 long getMaximumVersionTimestamp()
          The most recent tuple revision timestamp associated with any tuple spanned by this node or leaf.
 long getMinimumVersionTimestamp()
          The earliest tuple revision timestamp associated with any tuple spanned by this node or leaf.
 long getNextAddr()
          The address of the next leaf in key order, 0L if it is known that there is no next leaf, and -1L if either: (a) it is not known whether there is a next leaf; or (b) it is known but the address of that leaf is not known to the caller.
 long getPriorAddr()
          The address of the previous leaf in key order, 0L if it is known that there is no previous leaf, and -1L if either: (a) it is not known whether there is a previous leaf; or (b) it is known but the address of that leaf is not known to the caller.
 int getSpannedTupleCount()
          The #of tuples spanned by this node or leaf.
 int getValueCount()
          The #of values in the leaf (this MUST be equal to the #of keys for a leaf).
 IRaba getValues()
          Return the object storing the logical byte[][] containing the values for the leaf.
 long getVersionTimestamp(int index)
          The version timestamp for the entry at the specified index.
 boolean hasDeleteMarkers()
          Return true iff the leaf maintains delete markers.
 boolean hasVersionTimestamps()
          Return true iff the leaf maintains version timestamps.
 int indexOf(byte[] key)
          Recursive search locates the appropriate leaf and returns the index position of the entry.
 Tuple insert(byte[] searchKey, byte[] newval, boolean delete, long timestamp, Tuple tuple)
          Insert or update an entry in the leaf as appropriate.
 boolean isCoded()
          true iff this is a coded data structure.
 boolean isDoubleLinked()
          Return true if the leaf data record supports encoding of the address of the previous and next leaf in the B+Tree order.
 boolean isLeaf()
          Always returns true.
 boolean isReadOnly()
          The result depends on the implementation.
 byte[] keyAt(int entryIndex)
          Recursive search locates the entry at the specified index position in the btree and returns the key for that entry.
 Tuple lookup(byte[] searchKey, Tuple tuple)
          Lookup a key.
protected  int maxKeys()
          Return branchingFactor, which is the maximum #of keys for a Leaf.
protected  void merge(AbstractNode sibling, boolean isRightSibling)
          Merge the keys and values from the sibling into this leaf, delete the sibling from the store and remove the sibling from the parent.
protected  int minKeys()
          Return (branchingFactor + 1) << 1
 Iterator<AbstractNode> postOrderIterator(byte[] fromKey, byte[] toKey)
          Visits this leaf.
 Iterator<AbstractNode> postOrderNodeIterator(boolean dirtyNodesOnly)
          Visits this leaf if unless it is not dirty and the flag is true, in which case the returned iterator will not visit anything.
protected  void redistributeKeys(AbstractNode sibling, boolean isRightSibling)
          Redistributes a key from the specified sibling into this leaf in order to bring this leaf up to the minimum #of keys.
 Tuple remove(byte[] key, Tuple tuple)
          Recursive search locates the appropriate leaf and removes the entry for the key.
protected  IAbstractNode split()
           Split an over-capacity leaf (a leaf with maxKeys+1 keys), creating a new rightSibling.
 String toString()
          Human readable representation of the ILeafData plus transient information associated with the Leaf.
 void valueAt(int entryIndex, Tuple tuple)
          Recursive search locates the entry at the specified index position in the btree and returns the value for that entry.
 
Methods inherited from class com.bigdata.btree.AbstractNode
assertInvariants, assertKeysMonotonic, copyKey, copyOnWrite, copyOnWrite, dump, dump, getBranchingFactor, getParent, indent, isLeftMostNode, isRightMostNode, join, keyAsString, postOrderNodeIterator, rangeIterator
 
Methods inherited from class com.bigdata.btree.PO
getIdentity, isDeleted, isDirty, isPersistent, setDirty, toShortString
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

Leaf

protected Leaf(AbstractBTree btree,
               long addr,
               ILeafData data)
De-serialization constructor.

Note: The de-serialization constructor (and ONLY the de-serialization constructor) ALWAYS creates a clean leaf. Therefore the PO.dirty flag passed up from this constructor has the value false.

Parameters:
btree - The tree to which the leaf belongs.
addr - The address of this leaf.
data - The data record.

Leaf

protected Leaf(AbstractBTree btree)
Creates a new mutable leaf.

Parameters:
btree - A mutable B+Tree.

Leaf

protected Leaf(Leaf src)
Copy constructor.

Parameters:
src - The source node (must be immutable).
See Also:
AbstractNode.copyOnWrite()
Method Detail

minKeys

protected final int minKeys()
Return (branchingFactor + 1) << 1

Specified by:
minKeys in class AbstractNode<Leaf>

maxKeys

protected final int maxKeys()
Return branchingFactor, which is the maximum #of keys for a Leaf.

Specified by:
maxKeys in class AbstractNode<Leaf>

getDelegate

public final ILeafData getDelegate()
Description copied from class: AbstractNode
Return the delegate IAbstractNodeData object.


isLeaf

public final boolean isLeaf()
Always returns true.

Specified by:
isLeaf in interface IAbstractNodeData
Specified by:
isLeaf in class AbstractNode<Leaf>

isReadOnly

public final boolean isReadOnly()
The result depends on the implementation. The Leaf will be mutable when it is first created and is made immutable when it is persisted. If there is a mutation operation, the backing ILeafData is automatically converted into a mutable instance.

Specified by:
isReadOnly in interface IAbstractNodeData

isCoded

public final boolean isCoded()
Description copied from interface: IAbstractNodeData
true iff this is a coded data structure.

Specified by:
isCoded in interface IAbstractNodeData

data

public final AbstractFixedByteArrayBuffer data()
Description copied from interface: IAbstractNodeData
The coded (aka compressed) data.

Specified by:
data in interface IAbstractNodeData
Specified by:
data in interface IDataRecordAccess

getDeleteMarker

public final boolean getDeleteMarker(int index)
Description copied from interface: ILeafData
Return true iff the entry at the specified index is marked as deleted.

Specified by:
getDeleteMarker in interface ILeafData

getKeyCount

public final int getKeyCount()
Description copied from interface: IAbstractNodeData
Return the #of keys in the node or leaf. A node has nkeys+1 children. A leaf has nkeys keys and values. The maximum #of keys for a node is one less than the branching factor of the B+Tree. The maximum #of keys for a leaf is the branching factor of the B+Tree.

Specified by:
getKeyCount in interface IAbstractNodeData
Returns:
The #of defined keys.

getKeys

public final IRaba getKeys()
Description copied from interface: IAbstractNodeData
The object used to contain and manage the keys.

Specified by:
getKeys in interface IAbstractNodeData

getSpannedTupleCount

public final int getSpannedTupleCount()
Description copied from interface: IAbstractNodeData
The #of tuples spanned by this node or leaf. For a leaf this is always the #of keys.

Specified by:
getSpannedTupleCount in interface IAbstractNodeData
See Also:
INodeData#getChildEntryCounts()

getValueCount

public final int getValueCount()
Description copied from interface: ILeafData
The #of values in the leaf (this MUST be equal to the #of keys for a leaf).

Specified by:
getValueCount in interface ILeafData
Returns:
The #of values in the leaf.

getValues

public final IRaba getValues()
Description copied from interface: ILeafData
Return the object storing the logical byte[][] containing the values for the leaf. When the leaf maintains delete markers you MUST check whether or not the tuple is deleted before requesting its value.

Specified by:
getValues in interface ILeafData
See Also:
ILeafData.hasDeleteMarkers(), ILeafData.getDeleteMarker(int)

getVersionTimestamp

public final long getVersionTimestamp(int index)
Description copied from interface: ILeafData
The version timestamp for the entry at the specified index.

Specified by:
getVersionTimestamp in interface ILeafData
Returns:
The version timestamp for the index entry.

hasDeleteMarkers

public final boolean hasDeleteMarkers()
Description copied from interface: ILeafData
Return true iff the leaf maintains delete markers.

Specified by:
hasDeleteMarkers in interface ILeafData

hasVersionTimestamps

public final boolean hasVersionTimestamps()
Description copied from interface: ILeafData
Return true iff the leaf maintains version timestamps.

Specified by:
hasVersionTimestamps in interface IAbstractNodeData
Specified by:
hasVersionTimestamps in interface ILeafData

getMinimumVersionTimestamp

public final long getMinimumVersionTimestamp()
Description copied from interface: IAbstractNodeData
The earliest tuple revision timestamp associated with any tuple spanned by this node or leaf. If there are NO tuples for the leaf, then this MUST return Long.MAX_VALUE since the initial value of the minimum version timestamp is always the largest possible long integer.

Specified by:
getMinimumVersionTimestamp in interface IAbstractNodeData

getMaximumVersionTimestamp

public final long getMaximumVersionTimestamp()
Description copied from interface: IAbstractNodeData
The most recent tuple revision timestamp associated with any tuple spanned by this node or leaf. If there are NO tuples for the leaf, then this MUST return Long.MIN_VALUE since the initial value of the maximum version timestamp is always the smallest possible long integer.

Specified by:
getMaximumVersionTimestamp in interface IAbstractNodeData

isDoubleLinked

public final boolean isDoubleLinked()
Description copied from interface: ILeafData
Return true if the leaf data record supports encoding of the address of the previous and next leaf in the B+Tree order.

Specified by:
isDoubleLinked in interface ILeafData

getPriorAddr

public final long getPriorAddr()
Description copied from interface: ILeafData
The address of the previous leaf in key order, 0L if it is known that there is no previous leaf, and -1L if either: (a) it is not known whether there is a previous leaf; or (b) it is known but the address of that leaf is not known to the caller.

Specified by:
getPriorAddr in interface ILeafData

getNextAddr

public final long getNextAddr()
Description copied from interface: ILeafData
The address of the next leaf in key order, 0L if it is known that there is no next leaf, and -1L if either: (a) it is not known whether there is a next leaf; or (b) it is known but the address of that leaf is not known to the caller.

Specified by:
getNextAddr in interface ILeafData

delete

public void delete()
Description copied from interface: IIdentityAccess
Deletes the persistence capable object. Both transient and persistent objects may be logically deleted. If the object is persistent then its space on the store is deallocated.

Specified by:
delete in interface IIdentityAccess
Overrides:
delete in class AbstractNode<Leaf>

insert

public Tuple insert(byte[] searchKey,
                    byte[] newval,
                    boolean delete,
                    long timestamp,
                    Tuple tuple)
Insert or update an entry in the leaf as appropriate. The caller MUST ensure by appropriate navigation of parent nodes that the key for the next tuple either exists in or belongs in this leaf. If the leaf overflows then it is split after the insert. FIXME maintain min/max version timestamps.

Specified by:
insert in class AbstractNode<Leaf>
Parameters:
searchKey - The key (non-null).
newval - The value (may be null).
delete - true iff the entry is to marked as deleted (delete markers must be supported for if this is true).
timestamp - The timestamp associated with the version (the value is ignored unless version metadata is being maintained).
tuple - A tuple that may be used to obtain the data and metadata for the pre-existing index entry overwritten by the insert operation (optional).
Returns:
The tuple iff there was a pre-existing entry under that key and null otherwise.

lookup

public Tuple lookup(byte[] searchKey,
                    Tuple tuple)
Description copied from class: AbstractNode
Lookup a key.

Specified by:
lookup in class AbstractNode<Leaf>
Parameters:
searchKey - The search key.
tuple - A tuple that may be used to obtain the data and metadata for the pre-existing index entry (required).
Returns:
The tuple iff there was a pre-existing entry under that key and null otherwise.

indexOf

public int indexOf(byte[] key)
Description copied from class: AbstractNode
Recursive search locates the appropriate leaf and returns the index position of the entry.

Specified by:
indexOf in class AbstractNode<Leaf>
Parameters:
key - The search key.
Returns:
the index of the search key, if found; otherwise, (-(insertion point) - 1). The insertion point is defined as the point at which the key would be found it it were inserted into the btree without intervening mutations. Note that this guarantees that the return value will be >= 0 if and only if the key is found.

keyAt

public byte[] keyAt(int entryIndex)
Description copied from class: AbstractNode
Recursive search locates the entry at the specified index position in the btree and returns the key for that entry.

Specified by:
keyAt in class AbstractNode<Leaf>
Parameters:
entryIndex - The index position of the entry (origin zero and relative to this node or leaf).
Returns:
The key at that index position.

valueAt

public void valueAt(int entryIndex,
                    Tuple tuple)
Description copied from class: AbstractNode
Recursive search locates the entry at the specified index position in the btree and returns the value for that entry.

Specified by:
valueAt in class AbstractNode<Leaf>
Parameters:
entryIndex - The index position of the entry (origin zero and relative to this node or leaf).
tuple - A tuple that may be used to obtain the data and metadata for the pre-existing index entry (required).

split

protected IAbstractNode split()

Split an over-capacity leaf (a leaf with maxKeys+1 keys), creating a new rightSibling. The splitIndex (the index of the first key to move to the rightSibling) is (maxKeys+1)/2. The key at the splitIndex is also inserted as the new separatorKey into the parent. All keys and values starting with splitIndex are moved to the new rightSibling. If this leaf is the root of the tree (no parent), then a new root Node is created without any keys and is made the parent of this leaf. In any case, we then insert( separatorKey, rightSibling ) into the parent node, which may cause the parent node itself to split.

Specified by:
split in class AbstractNode<Leaf>
Returns:
The new rightSibling leaf. FIXME maintain min/max version timestamps.

redistributeKeys

protected void redistributeKeys(AbstractNode sibling,
                                boolean isRightSibling)
Redistributes a key from the specified sibling into this leaf in order to bring this leaf up to the minimum #of keys. This also updates the separator key in the parent for the right most of (this, sibling). While the #of entries spanned by the children of the common parent is changed by this method note that there is no net change in the #of entries spanned by that parent node.

Specified by:
redistributeKeys in class AbstractNode<Leaf>
Parameters:
sibling - A direct sibling of this leaf (either the left or right sibling). The sibling MUST be mutable.
isRightSibling - True iff the sibling is the rightSibling of this node.
TODO:
Modify to always choose the shortest separator key from within a region in which the split is reasonable. This will help keep down the size of the separator keys in the nodes. FIXME maintain min/max version timestamps.

merge

protected void merge(AbstractNode sibling,
                     boolean isRightSibling)
Merge the keys and values from the sibling into this leaf, delete the sibling from the store and remove the sibling from the parent. This will trigger recursive AbstractNode.join() if the parent node is now deficient. While this changes the #of entries spanned by the current node it does NOT effect the #of entries spanned by the parent. Likewise, while the min/max tuple revision timestamp may change for this Leaf, it WILL NOT change for its parent Node (since this operation does not remove any tuples).

Specified by:
merge in class AbstractNode<Leaf>
Parameters:
sibling - A direct sibling of this leaf (does NOT need to be mutable). The sibling MUST have exactly the minimum #of keys. FIXME maintain min/max version timestamps.
isRightSibling - True iff the sibling is the rightSibling of this node.

copyDown

protected void copyDown(int entryIndex,
                        int count)
Copies all keys and values from the specified start index down by one in order to make room to insert a key and value at that index.

Parameters:
entryIndex - The index of the first key and value to be copied.

remove

public Tuple remove(byte[] key,
                    Tuple tuple)
Description copied from class: AbstractNode
Recursive search locates the appropriate leaf and removes the entry for the key.

Note: It is an error to call this method if delete markers are in use.

Specified by:
remove in class AbstractNode<Leaf>
Parameters:
key - The search key.
tuple - A tuple that may be used to obtain the data and metadata for the pre-existing index entry that was either removed by the remove operation (optional).
Returns:
The tuple iff there was a pre-existing entry under that key and null otherwise.

postOrderNodeIterator

public Iterator<AbstractNode> postOrderNodeIterator(boolean dirtyNodesOnly)
Visits this leaf if unless it is not dirty and the flag is true, in which case the returned iterator will not visit anything.

Specified by:
postOrderNodeIterator in class AbstractNode<Leaf>
Parameters:
dirtyNodesOnly - When true, only dirty nodes and leaves will be visited
Returns:
Iterator visiting AbstractNodes.

postOrderIterator

public Iterator<AbstractNode> postOrderIterator(byte[] fromKey,
                                                byte[] toKey)
Visits this leaf.

Specified by:
postOrderIterator in class AbstractNode<Leaf>
Parameters:
fromKey - The first key that will be visited (inclusive). When null there is no lower bound.
toKey - The first key that will NOT be visited (exclusive). When null there is no upper bound.
Returns:
Iterator visiting AbstractNodes.

entryIterator

public ITupleIterator entryIterator()
Iterator visits the tuples in this leaf in key order.

Specified by:
entryIterator in interface IAbstractNode
Overrides:
entryIterator in class AbstractNode<Leaf>

dump

public boolean dump(org.apache.log4j.Level level,
                    PrintStream out,
                    int height,
                    boolean recursive)
Description copied from class: AbstractNode
Dump the data onto the PrintStream.

Specified by:
dump in class AbstractNode<Leaf>
Parameters:
level - The logging level.
out - Where to write the dump.
height - The height of this node in the tree or -1 iff you need to invoke this method on a node or leaf whose height in the tree is not known.
recursive - When true, the node will be dumped recursively using a pre-order traversal.
Returns:
True unless an inconsistency was detected.

toString

public String toString()
Human readable representation of the ILeafData plus transient information associated with the Leaf.

Overrides:
toString in class PO

addLeafListener

public final void addLeafListener(Leaf.ILeafListener l)
Register an Leaf.ILeafListener with this Leaf. Listeners are automatically removed by the JVM shortly after they become only weakly reachable.

Parameters:
l - The listener.
Throws:
IllegalStateException - if the owning AbstractBTree is read-only.

fireInvalidateLeafEvent

protected final void fireInvalidateLeafEvent()
Fire an Leaf.ILeafListener.invalidateLeaf() event to any registered listeners.



Copyright © 2006-2009 SYSTAP, LLC. All Rights Reserved.