private BitMappedTrie<T> prepend(java.util.Iterator<? extends T> iterator, int size) { BitMappedTrie<T> result = this; while (size > 0) { Object array = result.array; int shift = result.depthShift, offset = result.offset; if (result.isFullLeft()) { array = obj().copyUpdate(obj().empty(), BRANCHING_FACTOR - 1, array); shift += BRANCHING_BASE; offset = treeSize(BRANCHING_FACTOR - 1, shift); } final int index = offset - 1; final int delta = Math.min(size, lastDigit(index) + 1); size -= delta; array = result.modify(array, shift, index, COPY_NODE, prependToLeaf(iterator)); result = new BitMappedTrie<>(type, array, offset - delta, result.length + delta, shift); } return result; } private boolean isFullLeft() { return offset == 0; }
BitMappedTrie<T> appendAll(Iterable<? extends T> iterable) { final Collections.IterableWithSize<? extends T> iter = withSize(iterable); try { return append(iter.iterator(), iter.size()); } catch (ClassCastException ignored) { return boxed().append(iter.iterator(), iter.size()); } } private BitMappedTrie<T> append(java.util.Iterator<? extends T> iterator, int size) {
private BitMappedTrie<T> append(java.util.Iterator<? extends T> iterator, int size) { BitMappedTrie<T> result = this; while (size > 0) { Object array = result.array; int shift = result.depthShift; if (result.isFullRight()) { array = obj().asArray(array); shift += BRANCHING_BASE; } final int index = offset + result.length; final int leafSpace = lastDigit(index); final int delta = Math.min(size, BRANCHING_FACTOR - leafSpace); size -= delta; array = result.modify(array, shift, index, COPY_NODE, appendToLeaf(iterator, leafSpace + delta)); result = new BitMappedTrie<>(type, array, offset, result.length + delta, shift); } return result; } private boolean isFullRight() { return (offset + length + 1) > treeSize(BRANCHING_FACTOR, depthShift); }
BitMappedTrie<T> update(int index, T element) { try { final Object root = modify(array, depthShift, offset + index, COPY_NODE, updateLeafWith(type, element)); return new BitMappedTrie<>(type, root, offset, length, depthShift); } catch (ClassCastException ignored) { return boxed().update(index, element); } } private NodeModifier updateLeafWith(ArrayType<T> type, T element) { return (a, i) -> type.copyUpdate(a, i, element); }
BitMappedTrie<T> drop(int n) { if (n <= 0) { return this; } else if (n >= length) { return empty(); } else { final int index = offset + n; final Object root = arePointingToSameLeaf(0, n) ? array : modify(array, depthShift, index, obj()::copyDrop, IDENTITY); return collapsed(type, root, index, length - n, depthShift); } }
private Object modifyNonLeaf(Object root, int depthShift, int index, NodeModifier node, NodeModifier leaf) { int previousIndex = firstDigit(index, depthShift); root = node.apply(root, previousIndex); Object array = root; for (int shift = depthShift - BRANCHING_BASE; shift >= BRANCHING_BASE; shift -= BRANCHING_BASE) { final int prev = previousIndex; previousIndex = digit(index, shift); array = setNewNode(node, prev, array, previousIndex); } final Object newLeaf = leaf.apply(obj().getAt(array, previousIndex), lastDigit(index)); obj().setAt(array, previousIndex, newLeaf); return root; } private Object setNewNode(NodeModifier node, int previousIndex, Object array, int offset) {
private static <T> BitMappedTrie<T> collapsed(ArrayType<T> type, Object array, int offset, int length, int shift) { for (; shift > 0; shift -= BRANCHING_BASE) { final int skippedElements = obj().lengthOf(array) - 1; if (skippedElements != digit(offset, shift)) { break; } array = obj().getAt(array, skippedElements); offset -= treeSize(skippedElements, shift); } return new BitMappedTrie<>(type, array, offset, length, shift); }
private Object getLeafGeneral(int index) { index += offset; Object leaf = obj().getAt(array, firstDigit(index, depthShift)); for (int shift = depthShift - BRANCHING_BASE; shift > 0; shift -= BRANCHING_BASE) { leaf = obj().getAt(leaf, digit(index, shift)); } return leaf; }
BitMappedTrie<T> prependAll(Iterable<? extends T> iterable) { final Collections.IterableWithSize<? extends T> iter = withSize(iterable); try { return prepend(iter.reverseIterator(), iter.size()); } catch (ClassCastException ignored) { return boxed().prepend(iter.reverseIterator(), iter.size()); } } private BitMappedTrie<T> prepend(java.util.Iterator<? extends T> iterator, int size) {
private static <T> BitMappedTrie<T> ofAll(Object array, ArrayType<T> type, int size) { int shift = 0; for (ArrayType<T> t = type; t.lengthOf(array) > BRANCHING_FACTOR; shift += BRANCHING_BASE) { array = t.grouped(array, BRANCHING_FACTOR); t = obj(); } return new BitMappedTrie<>(type, array, 0, size, shift); }
@Override public Vector<T> appendAll(Iterable<? extends T> iterable) { Objects.requireNonNull(iterable, "iterable is null"); if (isEmpty()) { return ofAll(iterable); } if (io.vavr.collection.Collections.isEmpty(iterable)){ return this; } return new Vector<>(trie.appendAll(iterable)); }
@Override public Vector<T> drop(int n) { return wrap(trie.drop(n)); }
BitMappedTrie<T> take(int n) { if (n >= length) { return this; } else if (n <= 0) { return empty(); } else { final int index = n - 1; final Object root = arePointingToSameLeaf(index, length - 1) ? array : modify(array, depthShift, offset + index, obj()::copyTake, IDENTITY); return collapsed(type, root, offset, n, depthShift); } }
BitMappedTrie<T> update(int index, T element) { try { final Object root = modify(array, depthShift, offset + index, COPY_NODE, updateLeafWith(type, element)); return new BitMappedTrie<>(type, root, offset, length, depthShift); } catch (ClassCastException ignored) { return boxed().update(index, element); } } private NodeModifier updateLeafWith(ArrayType<T> type, T element) { return (a, i) -> type.copyUpdate(a, i, element); }
private Object modifyNonLeaf(Object root, int depthShift, int index, NodeModifier node, NodeModifier leaf) { int previousIndex = firstDigit(index, depthShift); root = node.apply(root, previousIndex); Object array = root; for (int shift = depthShift - BRANCHING_BASE; shift >= BRANCHING_BASE; shift -= BRANCHING_BASE) { final int prev = previousIndex; previousIndex = digit(index, shift); array = setNewNode(node, prev, array, previousIndex); } final Object newLeaf = leaf.apply(obj().getAt(array, previousIndex), lastDigit(index)); obj().setAt(array, previousIndex, newLeaf); return root; } private Object setNewNode(NodeModifier node, int previousIndex, Object array, int offset) {
private static <T> BitMappedTrie<T> collapsed(ArrayType<T> type, Object array, int offset, int length, int shift) { for (; shift > 0; shift -= BRANCHING_BASE) { final int skippedElements = obj().lengthOf(array) - 1; if (skippedElements != digit(offset, shift)) { break; } array = obj().getAt(array, skippedElements); offset -= treeSize(skippedElements, shift); } return new BitMappedTrie<>(type, array, offset, length, shift); }
private Object getLeafGeneral(int index) { index += offset; Object leaf = obj().getAt(array, firstDigit(index, depthShift)); for (int shift = depthShift - BRANCHING_BASE; shift > 0; shift -= BRANCHING_BASE) { leaf = obj().getAt(leaf, digit(index, shift)); } return leaf; }
BitMappedTrie<T> prependAll(Iterable<? extends T> iterable) { final Collections.IterableWithSize<? extends T> iter = withSize(iterable); try { return prepend(iter.reverseIterator(), iter.size()); } catch (ClassCastException ignored) { return boxed().prepend(iter.reverseIterator(), iter.size()); } } private BitMappedTrie<T> prepend(java.util.Iterator<? extends T> iterator, int size) {