Package org.organicdesign.fp.collections
Class RrbTree<E>
- java.lang.Object
-
- org.organicdesign.fp.collections.RrbTree<E>
-
- All Implemented Interfaces:
java.lang.Iterable<E>,java.util.Collection<E>,java.util.List<E>,BaseList<E>,Sized,UnmodCollection<E>,UnmodIterable<E>,UnmodList<E>,UnmodSortedCollection<E>,UnmodSortedIterable<E>,Indented,Transformable<E>
- Direct Known Subclasses:
RrbTree.ImRrbt,RrbTree.MutableRrbt
public abstract class RrbTree<E> extends java.lang.Object implements BaseList<E>, Indented
An RRB Tree is an immutable List (like Clojure's PersistentVector) that also supports random inserts, deletes, and can be split and joined back together in logarithmic time. This is based on the paper, "RRB-Trees: Efficient Immutable Vectors" by Phil Bagwell and Tiark Rompf, with the following differences:
- The Relaxed nodes can be sized between n/3 and 2n/3 (Bagwell/Rompf specify n and n-1)
- The Join operation sticks the shorter tree unaltered into the larger tree (except for very small trees which just get concatenated).
Details were filled in from the Cormen, Leiserson, Rivest & Stein Algorithms book entry on B-Trees. Also with an awareness of the Clojure PersistentVector by Rich Hickey. All errors are by Glen Peterson.
History (what little I know):
1972: B-Tree: Rudolf Bayer and Ed McCreight
1998: Purely Functional Data Structures: Chris Okasaki
2007: Clojure's Persistent Vector (and HashMap) implementations: Rich Hickey
2012: RRB-Tree: Phil Bagwell and Tiark Rompf
Compared to other collections (timings summary from 2017-06-11):
- append() -
RrbTree.ImRrbtvaries between 90% and 100% of the speed ofPersistentVector(biggest difference above 100K).RrbTree.MutableRrbtvaries between 45% and 80% of the speed ofPersistentVector.MutableVector(biggest difference from 100 to 1M). - get() - varies between 50% and 150% of the speed of PersistentVector (PV wins above 1K) if you build RRB using append(). If you build rrb using random inserts (worst case), it goes from 90% at 10 items down to 15% of the speed of the PV at 1M items.
- iterate() - is about the same speed as PersistentVector
- insert(0, item) - beats ArrayList above 1K items (worse than ArrayList below 100 items).
- insert(random, item) - beats ArrayList above 10K items (worse than ArrayList until then).
- O(log n) split(), join(), and remove() (not timed yet).
Latest detailed timing results are here.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classRrbTree.ImRrbt<E>Immutable version of anRrbTree.static classRrbTree.MutableRrbt<E>Mutable version of anRrbTree.-
Nested classes/interfaces inherited from interface org.organicdesign.fp.collections.UnmodList
UnmodList.AbstractUnmodList<E>
-
-
Constructor Summary
Constructors Constructor Description RrbTree()
-
Method Summary
All Methods Static Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description abstract RrbTree<E>append(E t)Adds one item to the end of the ImList.static <T> RrbTree.ImRrbt<T>empty()Returns the empty, immutable RRB-Tree (there is only one)static <T> RrbTree.MutableRrbt<T>emptyMutable()Returns the empty, mutable RRB-Tree (there is only one)booleanequals(java.lang.Object other)abstract Eget(int i)inthashCode()This implementation is correct and compatible with java.util.AbstractList, but O(n).abstract java.lang.StringindentedStr(int indent)Returns a string where line breaks extend the given amount of indentation.abstract RrbTree<E>insert(int idx, E element)Inserts an item in the RRB tree pushing the current element at that index and all subsequent elements to the right.abstract UnmodSortedIterator<E>iterator()A convenience method to get a listIterator.abstract RrbTree<E>join(RrbTree<E> that)Joins the given tree to the right side of this tree (or this to the left side of that one) in something like O(log n) time.abstract RrbTree<E>replace(int index, E item)Replace the item at the given index.abstract intsize()Returns the number of items in this collection or iterable.abstract Tuple2<? extends RrbTree<E>,? extends RrbTree<E>>split(int splitIndex)Divides this RRB-Tree such that every index less-than the given index ends up in the left-hand tree and the indexed item and all subsequent ones end up in the right-hand tree.RrbTree<E>without(int index)Returns a new RrbTree minus the given item (all items to the right are shifted left one) This is O(log n).-
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface org.organicdesign.fp.collections.BaseList
concat, get, head, reverse
-
Methods inherited from interface org.organicdesign.fp.xform.Transformable
toImList, toImMap, toImRrbt, toImSet, toImSortedMap, toImSortedSet, toMutableList, toMutableMap, toMutableRrbt, toMutableSet, toMutableSortedMap, toMutableSortedSet
-
Methods inherited from interface org.organicdesign.fp.collections.UnmodIterable
drop, dropWhile, filter, flatMap, fold, foldUntil, map, precat, take, takeWhile
-
Methods inherited from interface org.organicdesign.fp.collections.UnmodList
add, add, addAll, addAll, clear, contains, containsAll, indexOf, isEmpty, lastIndexOf, listIterator, listIterator, remove, remove, removeAll, removeIf, replaceAll, retainAll, set, sort, subList, toArray, toArray
-
-
-
-
Method Detail
-
empty
public static <T> RrbTree.ImRrbt<T> empty()
Returns the empty, immutable RRB-Tree (there is only one)
-
emptyMutable
public static <T> RrbTree.MutableRrbt<T> emptyMutable()
Returns the empty, mutable RRB-Tree (there is only one)
-
insert
public abstract RrbTree<E> insert(int idx, E element)
Inserts an item in the RRB tree pushing the current element at that index and all subsequent elements to the right.- Parameters:
idx- the insertion pointelement- the item to insert- Returns:
- a new RRB-Tree with the item inserted.
-
iterator
public abstract UnmodSortedIterator<E> iterator()
A convenience method to get a listIterator.- Specified by:
iteratorin interfacejava.util.Collection<E>- Specified by:
iteratorin interfacejava.lang.Iterable<E>- Specified by:
iteratorin interfacejava.util.List<E>- Specified by:
iteratorin interfaceUnmodCollection<E>- Specified by:
iteratorin interfaceUnmodIterable<E>- Specified by:
iteratorin interfaceUnmodList<E>- Specified by:
iteratorin interfaceUnmodSortedCollection<E>- Specified by:
iteratorin interfaceUnmodSortedIterable<E>
-
join
public abstract RrbTree<E> join(RrbTree<E> that)
Joins the given tree to the right side of this tree (or this to the left side of that one) in something like O(log n) time.
-
replace
public abstract RrbTree<E> replace(int index, E item)
Replace the item at the given index. Note: i.replace(i.size(), o) used to be equivalent to i.concat(o), but it probably won't be for the RRB tree implementation, so this will change too.
-
size
public abstract int size()
Returns the number of items in this collection or iterable.
-
split
public abstract Tuple2<? extends RrbTree<E>,? extends RrbTree<E>> split(int splitIndex)
Divides this RRB-Tree such that every index less-than the given index ends up in the left-hand tree and the indexed item and all subsequent ones end up in the right-hand tree.- Parameters:
splitIndex- the split point (excluded from the left-tree, included in the right one)- Returns:
- two new sub-trees as determined by the split point. If the point is 0 or this.size() one tree will be empty (but never null).
-
without
public RrbTree<E> without(int index)
Returns a new RrbTree minus the given item (all items to the right are shifted left one) This is O(log n).
-
equals
public boolean equals(java.lang.Object other)
-
hashCode
public int hashCode()
This implementation is correct and compatible with java.util.AbstractList, but O(n).
-
indentedStr
public abstract java.lang.String indentedStr(int indent)
Returns a string where line breaks extend the given amount of indentation.- Specified by:
indentedStrin interfaceIndented- Parameters:
indent- the amount of indent to start at. Pretty-printed subsequent lines may have additional indent.- Returns:
- a string with the given starting offset (in spaces) for every line.
-
-