/** * Takes a btree and transforms it using the provided function, filtering out any null results. * The result of any transformation must sort identically wrt the other results as their originals */ public static <V> Object[] transformAndFilter(Object[] btree, Function<? super V, ? extends V> function) { if (isEmpty(btree)) return btree; // TODO: can be made more efficient FiltrationTracker<V> wrapped = new FiltrationTracker<>(function); Object[] result = transformAndFilter(btree, wrapped); if (!wrapped.failed) return result; // take the already transformed bits from the head of the partial result Iterable<V> head = iterable(result, 0, wrapped.index - 1, Dir.ASC); // and concatenate with remainder of original tree, with transformation applied Iterable<V> remainder = iterable(btree, wrapped.index + 1, size(btree) - 1, Dir.ASC); remainder = filter(transform(remainder, function), (x) -> x != null); Iterable<V> build = concat(head, remainder); return buildInternal(build, -1, UpdateFunction.<V>noOp()); }
private static <V> Object[] transformAndFilter(Object[] btree, FiltrationTracker<V> function) { Object[] result = btree; boolean isLeaf = isLeaf(btree); int childOffset = isLeaf ? Integer.MAX_VALUE : getChildStart(btree); int limit = isLeaf ? getLeafKeyEnd(btree) : btree.length - 1; for (int i = 0 ; i < limit ; i++) { // we want to visit in iteration order, so we visit our key nodes inbetween our children int idx = isLeaf ? i : (i / 2) + (i % 2 == 0 ? childOffset : 0); Object current = btree[idx]; Object updated = idx < childOffset ? function.apply((V) current) : transformAndFilter((Object[]) current, function); if (updated != current) { if (result == btree) result = btree.clone(); result[idx] = updated; } if (function.failed) return result; } return result; }
private static <V> Object[] transformAndFilter(Object[] btree, FiltrationTracker<V> function) { Object[] result = btree; boolean isLeaf = isLeaf(btree); int childOffset = isLeaf ? Integer.MAX_VALUE : getChildStart(btree); int limit = isLeaf ? getLeafKeyEnd(btree) : btree.length - 1; for (int i = 0 ; i < limit ; i++) { // we want to visit in iteration order, so we visit our key nodes inbetween our children int idx = isLeaf ? i : (i / 2) + (i % 2 == 0 ? childOffset : 0); Object current = btree[idx]; Object updated = idx < childOffset ? function.apply((V) current) : transformAndFilter((Object[]) current, function); if (updated != current) { if (result == btree) result = btree.clone(); result[idx] = updated; } if (function.failed) return result; } return result; }
/** * Takes a btree and transforms it using the provided function, filtering out any null results. * The result of any transformation must sort identically wrt the other results as their originals */ public static <V> Object[] transformAndFilter(Object[] btree, Function<? super V, ? extends V> function) { if (isEmpty(btree)) return btree; // TODO: can be made more efficient FiltrationTracker<V> wrapped = new FiltrationTracker<>(function); Object[] result = transformAndFilter(btree, wrapped); if (!wrapped.failed) return result; // take the already transformed bits from the head of the partial result Iterable<V> head = iterable(result, 0, wrapped.index - 1, Dir.ASC); // and concatenate with remainder of original tree, with transformation applied Iterable<V> remainder = iterable(btree, wrapped.index + 1, size(btree) - 1, Dir.ASC); remainder = filter(transform(remainder, function), (x) -> x != null); Iterable<V> build = concat(head, remainder); return buildInternal(build, -1, UpdateFunction.<V>noOp()); }
private static <V> Object[] transformAndFilter(Object[] btree, FiltrationTracker<V> function) { Object[] result = btree; boolean isLeaf = isLeaf(btree); int childOffset = isLeaf ? Integer.MAX_VALUE : getChildStart(btree); int limit = isLeaf ? getLeafKeyEnd(btree) : btree.length - 1; for (int i = 0 ; i < limit ; i++) { // we want to visit in iteration order, so we visit our key nodes inbetween our children int idx = isLeaf ? i : (i / 2) + (i % 2 == 0 ? childOffset : 0); Object current = btree[idx]; Object updated = idx < childOffset ? function.apply((V) current) : transformAndFilter((Object[]) current, function); if (updated != current) { if (result == btree) result = btree.clone(); result[idx] = updated; } if (function.failed) return result; } return result; }
/** * Takes a btree and transforms it using the provided function, filtering out any null results. * The result of any transformation must sort identically wrt the other results as their originals */ public static <V> Object[] transformAndFilter(Object[] btree, Function<? super V, ? extends V> function) { if (isEmpty(btree)) return btree; // TODO: can be made more efficient FiltrationTracker<V> wrapped = new FiltrationTracker<>(function); Object[] result = transformAndFilter(btree, wrapped); if (!wrapped.failed) return result; // take the already transformed bits from the head of the partial result Iterable<V> head = iterable(result, 0, wrapped.index - 1, Dir.ASC); // and concatenate with remainder of original tree, with transformation applied Iterable<V> remainder = iterable(btree, wrapped.index + 1, size(btree) - 1, Dir.ASC); remainder = filter(transform(remainder, function), (x) -> x != null); Iterable<V> build = concat(head, remainder); return buildInternal(build, -1, UpdateFunction.<V>noOp()); }
private static <V> Object[] transformAndFilter(Object[] btree, FiltrationTracker<V> function) { Object[] result = btree; boolean isLeaf = isLeaf(btree); int childOffset = isLeaf ? Integer.MAX_VALUE : getChildStart(btree); int limit = isLeaf ? getLeafKeyEnd(btree) : btree.length - 1; for (int i = 0 ; i < limit ; i++) { // we want to visit in iteration order, so we visit our key nodes inbetween our children int idx = isLeaf ? i : (i / 2) + (i % 2 == 0 ? childOffset : 0); Object current = btree[idx]; Object updated = idx < childOffset ? function.apply((V) current) : transformAndFilter((Object[]) current, function); if (updated != current) { if (result == btree) result = btree.clone(); result[idx] = updated; } if (function.failed) return result; } return result; }
/** * Takes a btree and transforms it using the provided function, filtering out any null results. * The result of any transformation must sort identically wrt the other results as their originals */ public static <V> Object[] transformAndFilter(Object[] btree, Function<? super V, ? extends V> function) { if (isEmpty(btree)) return btree; // TODO: can be made more efficient FiltrationTracker<V> wrapped = new FiltrationTracker<>(function); Object[] result = transformAndFilter(btree, wrapped); if (!wrapped.failed) return result; // take the already transformed bits from the head of the partial result Iterable<V> head = iterable(result, 0, wrapped.index - 1, Dir.ASC); // and concatenate with remainder of original tree, with transformation applied Iterable<V> remainder = iterable(btree, wrapped.index + 1, size(btree) - 1, Dir.ASC); remainder = filter(transform(remainder, function), (x) -> x != null); Iterable<V> build = concat(head, remainder); return buildInternal(build, -1, UpdateFunction.<V>noOp()); }