|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.helidb.util.bplus.BPlusTree<K,V>
K
- The type of keys in the tree. If the keys are not
Comparable
, a Comparator
must be used.V
- The type of values in the tree.public class BPlusTree<K,V>
This is a B+ Tree that stores data records (keys and values). B+ Trees provide fast key searches, record insertion and removal. For more information on B+ Tree properties, see this Wikipedia article.
Data is stored in nodes of configurable size. Leaf nodes contain the actual data records, and parent nodes contain information that makes it possible to search for records. Leaf nodes may optionally contain pointers to adjacent leaf nodes. In that case, iteration is enabled for the tree.
A NodeRepository
is used for storing and retrieving the data nodes.
The size of the data nodes is determined by a NodeSizeStrategy
.
The B+ Tree does not support null
keys. It supports null
values if the NodeRepository
that it uses does so.
The B+ Tree is not safe for concurrent access by several threads. Clients must synchronize it externally.
Just like for a Map
, take care if using mutable objects as
keys and/or values. Modifying keys and values may have unpredictable
consequences since the NodeRepository
may have serialized the values
to persistent storage, or it may have cached the values.
Implementation note for subclasses: The B+ Tree keeps track of key and
value modifications by keeping a key and value revision number. This can be
used to detect changes by iterators, for instance. See
getCurrentKeyRevision()
and getCurrentValueRevision()
.
NodeRepository
Nested Class Summary | |
---|---|
protected class |
BPlusTree.AbstractBPlusTreeRecordIterator<T>
This is the abstract base class for iterators that iterate over the tree's records. |
protected class |
BPlusTree.BPlusTreeKeyIterator
An iterator over the tree's keys. |
protected class |
BPlusTree.BPlusTreeNodeIterator
This is an Iterator over the B+ Tree's leaf nodes. |
protected class |
BPlusTree.BPlusTreeRecordIterator
An iterator over the tree's records. |
protected class |
BPlusTree.BPlusTreeValueIterator
An iterator over the tree's values. |
protected static class |
BPlusTree.NodeSearchResult<K,V>
This simple value-only class is used to represent the search result when finding a node. |
Constructor Summary | |
---|---|
BPlusTree(NodeRepository<K> nr,
Comparator<? super K> keyComparator,
LogAdapterHolder lah)
Create a new B+ Tree. |
|
BPlusTree(NodeRepository<K> nr,
LogAdapterHolder lah)
Create a new B+ Tree that has Comparable keys. |
Method Summary | |
---|---|
protected void |
assertNotClosed()
|
void |
clear()
Delete all records in the tree. |
void |
close()
Close the tree. |
boolean |
compact()
Defragment the tree to win back some disk space. |
protected int |
compareKeys(K k1,
K k2)
Compare the two keys. |
boolean |
containsKey(K key)
Does the tree contain the supplied key? |
V |
delete(K key)
Delete the record with the supplied key from the tree. |
V |
find(K key)
Find the value for a key. |
protected BPlusTreeLeafNode<K,V> |
findLeftmostLeafNode()
Find the leftmost leaf node in the tree. |
protected BPlusTree.NodeSearchResult<K,V> |
findNodeFor(K key,
long searchPos,
K keyOfFirstPointer,
LinkedList<BPlusTreeNonLeafNode<K>> parentList)
Find the leaf node where a record with the supplied key can be inserted. |
KeyAndValue<K,V> |
findRecord(K key,
SearchMode mode)
Find the record in the B+ Tree that matches the search key and the search mode most closely. |
protected BPlusTreeLeafNode<K,V> |
findRightmostLeafNode()
Find the rightmost leaf node in the tree, i.e. |
protected int |
getCurrentKeyRevision()
Get the current key revision. |
protected int |
getCurrentValueRevision()
Get the current value revision. |
KeyAndValue<K,V> |
getFirstRecord()
Get the tree's first record, i.e. |
Comparator<? super K> |
getKeyComparator()
Get the Comparator used for establishing the ordering of the keys
in the B+ Tree. |
KeyAndValue<K,V> |
getLastRecord()
Get the tree's last record, i.e. |
KeyAndValue<K,V> |
getNextRecord(K key)
Get the record after the record with the supplied key. |
KeyAndValue<K,V> |
getPreviousRecord(K key)
Get the record before the record with the supplied key. |
void |
insert(K key,
V value)
Insert a new record into the tree. |
boolean |
insertOrReplace(K key,
V value)
If a record with the supplied key exists in the tree, update it with the new value, otherwise insert a new record. |
boolean |
isIteratorSupported()
This method returns true if this B+ Tree supports iteration. |
Iterator<Record<K,V>> |
iterator()
Get an Iterator for iterating over the tree's Record :s. |
Iterator<K> |
keyIterator()
Get an Iterator for iterating over the tree's keys. |
void |
replace(K key,
V newValue)
Update a record with a new value. |
void |
replaceContentsWith(InputStream is,
long dataSize)
Replace the tree with contents read from the supplied InputStream
. |
int |
size()
Get the number of records in the tree. |
String |
toString()
|
Iterator<V> |
valueIterator()
Get an Iterator for iterating over the tree's values. |
long |
writeContentsTo(OutputStream os)
Write the contents of the tree to the supplied OutputStream . |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Constructor Detail |
---|
public BPlusTree(NodeRepository<K> nr, Comparator<? super K> keyComparator, LogAdapterHolder lah) throws IllegalArgumentException
nr
- The NodeRepository
used for storing nodes to and
retrieving nodes from the backing storage.keyComparator
- A Comparator
for comparing keys. This must
be set if the keys themselves are not Comparable
. If they are,
and this is set anyway, the Comparator
is used.lah
- A log adapter holder.
IllegalArgumentException
- If the maximum number of records per
leaf or non-leaf node, as reported by the node repository, is less than
2.BPlusTree(NodeRepository, LogAdapterHolder)
public BPlusTree(NodeRepository<K> nr, LogAdapterHolder lah) throws IllegalArgumentException
Comparable
keys.
nr
- The NodeRepository
used for storing nodes to and
retrieving nodes from the backing storage.lah
- A log adapter holder.
IllegalArgumentException
- If the maximum number of records per
leaf or non-leaf node, as reported by the node repository, is less than
2.BPlusTree(NodeRepository, Comparator, LogAdapterHolder)
Method Detail |
---|
protected void assertNotClosed() throws IllegalStateException
IllegalStateException
- If the B+ Tree has been closed.close()
protected int getCurrentKeyRevision()
protected int getCurrentValueRevision()
public Comparator<? super K> getKeyComparator()
Comparator
used for establishing the ordering of the keys
in the B+ Tree.
Comparator
, or null
if the tree uses
the natural ordering of the keys.protected int compareKeys(K k1, K k2) throws NullPointerException
Comparator
, that is
used. Otherwise, the keys are assumed to be Comparable
.
k1
- The first key.k2
- The second key.
Comparator
.
NullPointerException
- If no Comparator
is set for the tree
and the keys are not Comparable
.protected BPlusTreeLeafNode<K,V> findLeftmostLeafNode()
protected BPlusTreeLeafNode<K,V> findRightmostLeafNode()
public boolean isIteratorSupported() throws IllegalStateException
true
if this B+ Tree supports iteration. For
it to do so, it is required that each leaf node has pointers to its two
adjacent leaf nodes.
IllegalStateException
- If the tree is closed.keyIterator()
,
valueIterator()
,
iterator()
public Iterator<K> keyIterator() throws IllegalStateException, UnsupportedOperationException
Iterator
for iterating over the tree's keys. The keys are
returned in increasing order based on the Comparator
used by the
tree, or in the keys' natural order if no Comparator
is used.
IllegalStateException
- If the tree is closed.
UnsupportedOperationException
- If the tree does not support
iteration. For it to support iteration, it is required that each leaf
node stores pointers to its adjacent leaf nodes. This is configured in
the tree's NodeRepository
.public Iterator<V> valueIterator() throws IllegalStateException, UnsupportedOperationException
Iterator
for iterating over the tree's values. The values
are returned in increasing order of their corresponding keys, based on
the Comparator
used by the tree, or the keys' natural order if no
Comparator
is used.
IllegalStateException
- If the tree is closed.
UnsupportedOperationException
- If the tree does not support
iteration. For it to support iteration, it is required that each leaf
node stores pointers to its adjacent leaf nodes. This is configured in
the tree's NodeRepository
.public Iterator<Record<K,V>> iterator() throws IllegalStateException, UnsupportedOperationException
Iterator
for iterating over the tree's Record
:s.
The records are returned in increasing key order based on the
Comparator
used by the tree, or in the keys' natural order if no
Comparator
is used.
iterator
in interface Iterable<Record<K,V>>
IllegalStateException
- If the tree is closed.
UnsupportedOperationException
- If the tree does not support
iteration. For it to support iteration, it is required that each leaf
node stores pointers to its adjacent leaf nodes. This is configured in
the tree's NodeRepository
.protected BPlusTree.NodeSearchResult<K,V> findNodeFor(K key, long searchPos, K keyOfFirstPointer, LinkedList<BPlusTreeNonLeafNode<K>> parentList)
key
- The key to insert.searchPos
- The position in the NodeRepository
for the
record to search from. Position 0
is the tree's root node.keyOfFirstPointer
- The key corresponding to the node's leftmost
pointer (if any). For the root node, this is null
.parentList
- A LinkedList
(would have been a Deque
in Java 6+) containing all parent nodes that the tree has had to traverse
to find the current node it looks in. For the root node, this List
is empty.
BPlusTree.NodeSearchResult
.public void insert(K key, V value) throws IllegalStateException, KeyExistsException
key
- The record's key.value
- The record's value.
IllegalStateException
- If the tree is closed.
KeyExistsException
- If the key already exists in the tree.public void replace(K key, V newValue) throws IllegalStateException, KeyNotFoundException
key
- The record's key.newValue
- The new value.
IllegalStateException
- If the tree is closed.
KeyNotFoundException
- If there is no record with the supplied key
in the tree.public boolean insertOrReplace(K key, V value) throws IllegalStateException
key
- The key.value
- The value.
true
if an existing record was updated, false
if
a new record was inserted.
IllegalStateException
- If the tree is closed.public V find(K key) throws IllegalStateException
null
.
If the tree supports null
values, use
containsKey(Object)
to determine if a key is set in the tree.
Be careful with modifying the values returned from this method. That may lead to unpredictable behavior from the tree.
key
- The key to search for.
null
if the key was not
found in the tree.
IllegalStateException
- If the tree is closed.getNextRecord(Object)
,
getPreviousRecord(Object)
public KeyAndValue<K,V> findRecord(K key, SearchMode mode) throws IllegalStateException, UnsupportedOperationException
This method supports all search modes defined in SearchMode
. If
any of the CLOSEST_X
methods are used, this tree must be
iterable.
key
- The search key.mode
- The search mode.
null
is
returned.
IllegalStateException
- If the tree is closed.
UnsupportedOperationException
- If an unsupported search mode is
given.find(Object)
public boolean containsKey(K key) throws IllegalStateException
key
- The key to search for.
true
if the tree contains the key.
IllegalStateException
- If the tree is closed.public V delete(K key) throws IllegalStateException
null
is returned.
key
- The key for the record to delete.
null
if the key was
not found in the tree.
IllegalStateException
- If the tree is closed.public int size() throws IllegalStateException
The first time that this method is called, the tree is traversed to count the records. The result is cached, so subsequent invocations should be much faster.
IllegalStateException
- If the tree is closed.public void clear() throws IllegalStateException
IllegalStateException
- If the tree is closed.public long writeContentsTo(OutputStream os) throws WrappedIOException, IllegalStateException
OutputStream
.
os
- The stream to write to. The stream is not closed after
writing.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the tree is closed.public void replaceContentsWith(InputStream is, long dataSize) throws WrappedIOException, IllegalStateException, NotEnoughDataException
InputStream
.
is
- The stream to read from. The stream is not closed after
reading.dataSize
- The total number of bytes to read.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the tree is closed.
NotEnoughDataException
- If there is not enough data available in
the stream.public KeyAndValue<K,V> getFirstRecord() throws WrappedIOException, IllegalStateException
null
if the tree is
empty.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the tree is closed.getLastRecord()
public KeyAndValue<K,V> getLastRecord() throws WrappedIOException, IllegalStateException
null
if the tree is
empty.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the tree is closed.getFirstRecord()
public KeyAndValue<K,V> getNextRecord(K key) throws WrappedIOException, IllegalStateException, UnsupportedOperationException
This method requires that the tree is iterable.
key
- The key to search for.
null
is
returned.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the tree is closed.
UnsupportedOperationException
- If the tree does not support
iteration.getPreviousRecord(Object)
public KeyAndValue<K,V> getPreviousRecord(K key) throws WrappedIOException, IllegalStateException, UnsupportedOperationException
This method requires that the tree is iterable.
key
- The key to search for.
null
is
returned.
WrappedIOException
- On I/O errors.
IllegalStateException
- If the tree is closed.
UnsupportedOperationException
- If the tree does not support
iteration.getNextRecord(Object)
public boolean compact() throws IllegalStateException
This operation involves traversing the whole tree, so it may be slow for large trees.
true
if the tree was compacted, or false
if there
was nothing to compact right now.
IllegalStateException
- If the tree is closed.public void close()
NodeRepository
.
This method can be called several times. All invocations after the first does nothing.
public String toString()
toString
in class Object
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |