private ComplexColumnData transformAndFilter(DeletionTime newDeletion, Function<? super Cell, ? extends Cell> function) { Object[] transformed = BTree.transformAndFilter(cells, function); if (cells == transformed && newDeletion == complexDeletion) return this; if (newDeletion == DeletionTime.LIVE && BTree.isEmpty(transformed)) return null; return new ComplexColumnData(column, transformed, newDeletion); }
private ComplexColumnData transformAndFilter(DeletionTime newDeletion, Function<? super Cell, ? extends Cell> function) { Object[] transformed = BTree.transformAndFilter(cells, function); if (cells == transformed && newDeletion == complexDeletion) return this; if (newDeletion == DeletionTime.LIVE && BTree.isEmpty(transformed)) return null; return new ComplexColumnData(column, transformed, newDeletion); }
private ComplexColumnData transformAndFilter(DeletionTime newDeletion, Function<? super Cell, ? extends Cell> function) { Object[] transformed = BTree.transformAndFilter(cells, function); if (cells == transformed && newDeletion == complexDeletion) return this; if (newDeletion == DeletionTime.LIVE && BTree.isEmpty(transformed)) return null; return new ComplexColumnData(column, transformed, newDeletion); }
private ComplexColumnData transformAndFilter(DeletionTime newDeletion, Function<? super Cell, ? extends Cell> function) { Object[] transformed = BTree.transformAndFilter(cells, function); if (cells == transformed && newDeletion == complexDeletion) return this; if (newDeletion == DeletionTime.LIVE && BTree.isEmpty(transformed)) return null; return new ComplexColumnData(column, transformed, newDeletion); }
/** * 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()); }
/** * 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()); }
/** * 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 Row transformAndFilter(LivenessInfo info, Deletion deletion, Function<ColumnData, ColumnData> function) { Object[] transformed = BTree.transformAndFilter(btree, function); if (btree == transformed && info == this.primaryKeyLivenessInfo && deletion == this.deletion) return this; if (info.isEmpty() && deletion.isLive() && BTree.isEmpty(transformed)) return null; int minDeletionTime = minDeletionTime(transformed, info, deletion.time()); return BTreeRow.create(clustering, info, deletion, transformed, minDeletionTime); }
private Row transformAndFilter(LivenessInfo info, Deletion deletion, Function<ColumnData, ColumnData> function) { Object[] transformed = BTree.transformAndFilter(btree, function); if (btree == transformed && info == this.primaryKeyLivenessInfo && deletion == this.deletion) return this; if (info.isEmpty() && deletion.isLive() && BTree.isEmpty(transformed)) return null; int minDeletionTime = minDeletionTime(transformed, info, deletion.time()); return BTreeRow.create(clustering, info, deletion, transformed, minDeletionTime); }
private Row transformAndFilter(LivenessInfo info, Deletion deletion, Function<ColumnData, ColumnData> function) { Object[] transformed = BTree.transformAndFilter(btree, function); if (btree == transformed && info == this.primaryKeyLivenessInfo && deletion == this.deletion) return this; if (info.isEmpty() && deletion.isLive() && BTree.isEmpty(transformed)) return null; int minDeletionTime = minDeletionTime(transformed, info, deletion.time()); return BTreeRow.create(clustering, info, deletion, transformed, minDeletionTime); }
private Row transformAndFilter(LivenessInfo info, Deletion deletion, Function<ColumnData, ColumnData> function) { Object[] transformed = BTree.transformAndFilter(btree, function); if (btree == transformed && info == this.primaryKeyLivenessInfo && deletion == this.deletion) return this; if (info.isEmpty() && deletion.isLive() && BTree.isEmpty(transformed)) return null; int minDeletionTime = minDeletionTime(transformed, info, deletion.time()); return BTreeRow.create(clustering, info, deletion, transformed, minDeletionTime); }
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; }
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; }
/** * Modify this update to set every timestamp for live data to {@code newTimestamp} and * every deletion timestamp to {@code newTimestamp - 1}. * * There is no reason to use that expect on the Paxos code path, where we need ensure that * anything inserted use the ballot timestamp (to respect the order of update decided by * the Paxos algorithm). We use {@code newTimestamp - 1} for deletions because tombstones * always win on timestamp equality and we don't want to delete our own insertions * (typically, when we overwrite a collection, we first set a complex deletion to delete the * previous collection before adding new elements. If we were to set that complex deletion * to the same timestamp that the new elements, it would delete those elements). And since * tombstones always wins on timestamp equality, using -1 guarantees our deletion will still * delete anything from a previous update. */ public void updateAllTimestamp(long newTimestamp) { Holder holder = holder(); deletionInfo.updateAllTimestamp(newTimestamp - 1); Object[] tree = BTree.<Row>transformAndFilter(holder.tree, (x) -> x.updateAllTimestamp(newTimestamp)); Row staticRow = holder.staticRow.updateAllTimestamp(newTimestamp); EncodingStats newStats = EncodingStats.Collector.collect(staticRow, BTree.<Row>iterator(tree), deletionInfo); this.holder = new Holder(holder.columns, tree, deletionInfo, staticRow, newStats); }
/** * Modify this update to set every timestamp for live data to {@code newTimestamp} and * every deletion timestamp to {@code newTimestamp - 1}. * * There is no reason to use that expect on the Paxos code path, where we need ensure that * anything inserted use the ballot timestamp (to respect the order of update decided by * the Paxos algorithm). We use {@code newTimestamp - 1} for deletions because tombstones * always win on timestamp equality and we don't want to delete our own insertions * (typically, when we overwrite a collection, we first set a complex deletion to delete the * previous collection before adding new elements. If we were to set that complex deletion * to the same timestamp that the new elements, it would delete those elements). And since * tombstones always wins on timestamp equality, using -1 guarantees our deletion will still * delete anything from a previous update. */ public void updateAllTimestamp(long newTimestamp) { Holder holder = holder(); deletionInfo.updateAllTimestamp(newTimestamp - 1); Object[] tree = BTree.<Row>transformAndFilter(holder.tree, (x) -> x.updateAllTimestamp(newTimestamp)); Row staticRow = holder.staticRow.updateAllTimestamp(newTimestamp); EncodingStats newStats = EncodingStats.Collector.collect(staticRow, BTree.<Row>iterator(tree), deletionInfo); this.holder = new Holder(holder.columns, tree, deletionInfo, staticRow, newStats); }
/** * Modify this update to set every timestamp for live data to {@code newTimestamp} and * every deletion timestamp to {@code newTimestamp - 1}. * * There is no reason to use that expect on the Paxos code path, where we need ensure that * anything inserted use the ballot timestamp (to respect the order of update decided by * the Paxos algorithm). We use {@code newTimestamp - 1} for deletions because tombstones * always win on timestamp equality and we don't want to delete our own insertions * (typically, when we overwrite a collection, we first set a complex deletion to delete the * previous collection before adding new elements. If we were to set that complex deletion * to the same timestamp that the new elements, it would delete those elements). And since * tombstones always wins on timestamp equality, using -1 guarantees our deletion will still * delete anything from a previous update. */ public void updateAllTimestamp(long newTimestamp) { Holder holder = holder(); deletionInfo.updateAllTimestamp(newTimestamp - 1); Object[] tree = BTree.<Row>transformAndFilter(holder.tree, (x) -> x.updateAllTimestamp(newTimestamp)); Row staticRow = holder.staticRow.updateAllTimestamp(newTimestamp); EncodingStats newStats = EncodingStats.Collector.collect(staticRow, BTree.<Row>iterator(tree), deletionInfo); this.holder = new Holder(holder.columns, tree, deletionInfo, staticRow, newStats); }
/** * Modify this update to set every timestamp for live data to {@code newTimestamp} and * every deletion timestamp to {@code newTimestamp - 1}. * * There is no reason to use that expect on the Paxos code path, where we need ensure that * anything inserted use the ballot timestamp (to respect the order of update decided by * the Paxos algorithm). We use {@code newTimestamp - 1} for deletions because tombstones * always win on timestamp equality and we don't want to delete our own insertions * (typically, when we overwrite a collection, we first set a complex deletion to delete the * previous collection before adding new elements. If we were to set that complex deletion * to the same timestamp that the new elements, it would delete those elements). And since * tombstones always wins on timestamp equality, using -1 guarantees our deletion will still * delete anything from a previous update. */ public void updateAllTimestamp(long newTimestamp) { Holder holder = holder(); deletionInfo.updateAllTimestamp(newTimestamp - 1); Object[] tree = BTree.<Row>transformAndFilter(holder.tree, (x) -> x.updateAllTimestamp(newTimestamp)); Row staticRow = holder.staticRow.updateAllTimestamp(newTimestamp); EncodingStats newStats = EncodingStats.Collector.collect(staticRow, BTree.<Row>iterator(tree), deletionInfo); this.holder = new Holder(holder.columns, tree, deletionInfo, staticRow, newStats); }
/** * 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()); }