Package org.pkl.core.util.paguro
Class RrbTree<E>
java.lang.Object
org.pkl.core.util.paguro.RrbTree<E>
- All Implemented Interfaces:
Iterable<E>,Collection<E>,List<E>,SequencedCollection<E>,org.organicdesign.fp.collections.BaseList<E>,org.organicdesign.fp.collections.Sized,org.organicdesign.fp.collections.UnmodCollection<E>,org.organicdesign.fp.collections.UnmodIterable<E>,org.organicdesign.fp.collections.UnmodList<E>,org.organicdesign.fp.collections.UnmodSortedCollection<E>,org.organicdesign.fp.collections.UnmodSortedIterable<E>,org.organicdesign.fp.indent.Indented,org.organicdesign.fp.xform.Transformable<E>
- Direct Known Subclasses:
RrbTree.ImRrbt,RrbTree.MutRrbt
public abstract class RrbTree<E>
extends Object
implements org.organicdesign.fp.collections.BaseList<E>, org.organicdesign.fp.indent.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:
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
- 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 McCreight1998: 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.MutRrbtvaries between 45% and 80% of the speed ofPersistentVector.MutVector(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 ClassesModifier and TypeClassDescriptionstatic classImmutable version of anRrbTree.static classMutable version of anRrbTree.protected static interfaceprotected static classThis class is the return type when splitting a node.Nested classes/interfaces inherited from interface org.organicdesign.fp.collections.UnmodIterable
org.organicdesign.fp.collections.UnmodIterable.UnIterableNested classes/interfaces inherited from interface org.organicdesign.fp.collections.UnmodList
org.organicdesign.fp.collections.UnmodList.AbstractUnmodList<E> -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionappendSome(org.organicdesign.fp.function.Fn0<? extends org.organicdesign.fp.oneOf.Option<E>> supplier) static <T> RrbTree.ImRrbt<T> empty()Returns the empty, immutable RRB-Tree (there is only one)static <T> RrbTree.MutRrbt<T> Returns the empty, mutable RRB-Tree (there is only one)booleanabstract Eget(int i) inthashCode()This implementation is correct and compatible with java.util.AbstractList, but O(n).abstract StringindentedStr(int indent) Inserts an item in the RRB tree pushing the current element at that index and all subsequent elements to the right.abstract org.organicdesign.fp.collections.UnmodSortedIterator<E> iterator()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.makeNew(E[] f, int fi, int fl, RrbTree.Node<E> r, int s) Allows removing duplicated code by letting super-class produce new members of subclass types.mt()Creates a new empty ("M-T") tree of the appropriate (mutable/immutable) type.Precat is implemented here because it is a very cheap operation on an RRB-Tree.abstract intsize()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.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, waitMethods inherited from interface org.organicdesign.fp.collections.BaseList
concat, get, head, reverseMethods inherited from interface java.util.Collection
parallelStream, stream, toArrayMethods inherited from interface java.util.List
addFirst, addLast, getFirst, getLast, removeFirst, removeLast, reversed, spliteratorMethods inherited from interface org.organicdesign.fp.xform.Transformable
any, toImList, toImMap, toImRrbt, toImSet, toImSortedMap, toImSortedSet, toMutList, toMutMap, toMutRrbt, toMutSet, toMutSortedMap, toMutSortedSetMethods inherited from interface org.organicdesign.fp.collections.UnmodIterable
drop, dropWhile, filter, flatMap, fold, foldUntil, map, take, takeWhile, whereNonNullMethods 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
-
Constructor Details
-
RrbTree
public RrbTree()
-
-
Method Details
-
empty
Returns the empty, immutable RRB-Tree (there is only one) -
emptyMutable
Returns the empty, mutable RRB-Tree (there is only one) -
append
- Specified by:
appendin interfaceorg.organicdesign.fp.collections.BaseList<E>
-
appendSome
public abstract RrbTree<E> appendSome(org.organicdesign.fp.function.Fn0<? extends org.organicdesign.fp.oneOf.Option<E>> supplier) - Specified by:
appendSomein interfaceorg.organicdesign.fp.collections.BaseList<E>
-
get
-
insert
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
- Specified by:
iteratorin interfaceCollection<E>- Specified by:
iteratorin interfaceIterable<E>- Specified by:
iteratorin interfaceList<E>- Specified by:
iteratorin interfaceorg.organicdesign.fp.collections.UnmodCollection<E>- Specified by:
iteratorin interfaceorg.organicdesign.fp.collections.UnmodIterable<E>- Specified by:
iteratorin interfaceorg.organicdesign.fp.collections.UnmodList<E>- Specified by:
iteratorin interfaceorg.organicdesign.fp.collections.UnmodSortedCollection<E>- Specified by:
iteratorin interfaceorg.organicdesign.fp.collections.UnmodSortedIterable<E>
-
join
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. -
makeNew
Allows removing duplicated code by letting super-class produce new members of subclass types. -
mt
Creates a new empty ("M-T") tree of the appropriate (mutable/immutable) type. -
precat
Precat is implemented here because it is a very cheap operation on an RRB-Tree. It's not implemented on PersistentVector because it is very expensive there. -
replace
- Specified by:
replacein interfaceorg.organicdesign.fp.collections.BaseList<E>
-
size
public abstract int size() -
split
public org.organicdesign.fp.tuple.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
Returns a new RrbTree minus the given item (all items to the right are shifted left one) This is O(log n). -
equals
-
hashCode
public int hashCode()This implementation is correct and compatible with java.util.AbstractList, but O(n). -
indentedStr
- Specified by:
indentedStrin interfaceorg.organicdesign.fp.indent.Indented
-