belliottsmith commented on code in PR #50:
URL: https://github.com/apache/cassandra-accord/pull/50#discussion_r1241234775
##########
accord-core/src/main/java/accord/utils/ReducingRangeMap.java:
##########
@@ -19,154 +19,163 @@
import accord.api.RoutingKey;
import accord.primitives.*;
-import com.google.common.annotations.VisibleForTesting;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import static accord.utils.SortedArrays.Search.FAST;
+import static accord.utils.SortedArrays.exponentialSearch;
public class ReducingRangeMap<V> extends ReducingIntervalMap<RoutingKey, V>
{
- final RoutingKeys endKeys;
+ public static class SerializerSupport
+ {
+ public static <V> ReducingRangeMap<V> create(boolean inclusiveEnds,
RoutingKey[] ends, V[] values)
+ {
+ return new ReducingRangeMap<>(inclusiveEnds, ends, values);
+ }
+ }
- public ReducingRangeMap(V value)
+ public ReducingRangeMap()
{
- super(value);
- this.endKeys = RoutingKeys.EMPTY;
+ super();
}
- ReducingRangeMap(boolean inclusiveEnds, RoutingKey[] ends, V[] values)
+ protected ReducingRangeMap(boolean inclusiveEnds, RoutingKey[] ends, V[]
values)
{
super(inclusiveEnds, ends, values);
- this.endKeys = RoutingKeys.ofSortedUnique(ends);
}
- public V foldl(Routables<?, ?> routables, BiFunction<V, V, V> fold, V
initialValue)
+ public V foldl(Routables<?> routables, BiFunction<V, V, V> fold, V
accumulator)
+ {
+ return foldl(routables, (a, b, f, ignore) -> f.apply(a, b),
accumulator, fold, null, ignore -> false);
+ }
+
+ public <V2> V2 foldl(Routables<?> routables, BiFunction<V, V2, V2> fold,
V2 accumulator, Predicate<V2> terminate)
+ {
+ return foldl(routables, (a, b, f, ignore) -> f.apply(a, b),
accumulator, fold, null, terminate);
+ }
+
+ public <V2, P1> V2 foldl(Routables<?> routables, TriFunction<V, V2, P1,
V2> fold, V2 accumulator, P1 p1, Predicate<V2> terminate)
{
- return foldl(routables, fold, initialValue, ignore -> false);
+ return foldl(routables, (a, b, f, p) -> f.apply(a, b, p), accumulator,
fold, p1, terminate);
}
- public <V2> V2 foldl(Routables<?, ?> routables, BiFunction<V, V2, V2>
fold, V2 initialValue, Predicate<V2> terminate)
+ public <V2, P1, P2> V2 foldl(Routables<?> routables, QuadFunction<V, V2,
P1, P2, V2> fold, V2 accumulator, P1 p1, P2 p2, Predicate<V2> terminate)
+ {
+ return foldl(routables, (v, v2, param1, param2, i, j) -> fold.apply(v,
v2, param1, param2), accumulator, p1, p2, terminate);
+ }
+
+ public <V2, P1, P2> V2 foldl(Routables<?> routables,
IndexedRangeQuadFunction<V, V2, P1, P2, V2> fold, V2 accumulator, P1 p1, P2 p2,
Predicate<V2> terminate)
{
switch (routables.domain())
{
default: throw new AssertionError();
- case Key: return foldl((AbstractKeys<?, ?>) routables, fold,
initialValue, terminate);
- case Range: return foldl((AbstractRanges<?>) routables, fold,
initialValue, terminate);
+ case Key: return foldl((AbstractKeys<?>) routables, fold,
accumulator, p1, p2, terminate);
+ case Range: return foldl((AbstractRanges<?>) routables, fold,
accumulator, p1, p2, terminate);
}
}
// TODO (required): test
- public <V2> V2 foldl(AbstractKeys<?, ?> keys, BiFunction<V, V2, V2>
reduce, V2 accumulator, Predicate<V2> terminate)
+ public <V2, P1, P2> V2 foldl(AbstractKeys<?> keys,
IndexedRangeQuadFunction<V, V2, P1, P2, V2> fold, V2 accumulator, P1 p1, P2 p2,
Predicate<V2> terminate)
{
- int i = 0, j = 0;
+ if (values.length == 0)
+ return accumulator;
+
+ int i = 0, j = keys.findNext(0, starts[0], FAST);
+ if (j < 0) j = -1 - j;
+ else if (inclusiveEnds) ++j;
+
while (j < keys.size())
{
- i = endKeys.findNext(i, keys.get(j), FAST);
- if (i < 0) i = -1 - i;
- else if (!inclusiveEnds) ++i;
+ i = exponentialSearch(starts, i, starts.length, keys.get(j));
+ if (i < 0) i = -2 - i;
+ else if (inclusiveEnds) --i;
- accumulator = reduce.apply(values[i], accumulator);
- if (terminate.test(accumulator))
+ if (i >= values.length)
return accumulator;
- if (i == endKeys.size())
- return j + 1 == keys.size() ? accumulator :
reduce.apply(values[i], accumulator);
+ int nextj = keys.findNext(j, starts[i + 1], FAST);
+ if (nextj < 0) nextj = -1 -nextj;
+ else if (inclusiveEnds) ++nextj;
- j = keys.findNext(j + 1, endKeys.get(i), FAST);
- if (j < 0) j = -1 - j;
+ if (j != nextj && values[i] != null)
+ {
+ accumulator = fold.apply(values[i], accumulator, p1, p2, j,
nextj);
+ if (terminate.test(accumulator))
+ return accumulator;
+ }
+ ++i;
+ j = nextj;
}
return accumulator;
}
// TODO (required): test
- public <V2> V2 foldl(AbstractRanges<?> ranges, BiFunction<V, V2, V2>
reduce, V2 accumulator, Predicate<V2> terminate)
+ public <V2, P1, P2> V2 foldl(AbstractRanges<?> ranges,
IndexedRangeQuadFunction<V, V2, P1, P2, V2> fold, V2 accumulator, P1 p1, P2 p2,
Predicate<V2> terminate)
{
- int i = 0, j = 0;
+ if (values.length == 0)
+ return accumulator;
+
+ // TODO (desired): first searches should be binarySearch
+ int j = ranges.findNext(0, starts[0], FAST);
+ if (j < 0) j = -1 - j;
+ else if (inclusiveEnds && ranges.get(j).end().equals(starts[0])) ++j;
+
+ int i = 0;
while (j < ranges.size())
{
Range range = ranges.get(j);
- i = endKeys.findNext(i, range.start(), FAST);
- if (i < 0) i = -1 - i;
- else if (inclusiveEnds) ++i;
+ RoutingKey start = range.start();
+ int nexti = exponentialSearch(starts, i, starts.length, start);
+ if (nexti < 0) i = Math.max(i, -2 - nexti);
+ else if (nexti > i && !inclusiveStarts()) i = nexti - 1;
+ else i = nexti;
+
+ if (i >= values.length)
+ return accumulator;
- int nexti = endKeys.findNext(i, range.end(), FAST);
- if (nexti < 0) nexti = -nexti;
- else if (inclusiveEnds) ++nexti;
+ int toj, nextj = ranges.findNext(j, starts[i + 1], FAST);
+ if (nextj < 0) toj = nextj = -1 -nextj;
+ else
+ {
+ toj = nextj + 1;
+ if (inclusiveEnds && ranges.get(nextj).end().equals(starts[i +
1]))
+ ++nextj;
+ }
- while (i < nexti)
+ if (toj > j && values[i] != null)
{
- accumulator = reduce.apply(values[i++], accumulator);
+ accumulator = fold.apply(values[i], accumulator, p1, p2, j,
toj);
if (terminate.test(accumulator))
return accumulator;
}
- if (i > endKeys.size())
- return accumulator;
-
- j = ranges.findNext(j + 1, endKeys.get(i - 1), FAST);
- if (j < 0) j = -1 - j;
+ ++i;
+ j = nextj;
}
return accumulator;
}
- /**
- * returns a copy of this ReducingRangeMap limited to the ranges supplied,
with all other ranges reporting the "zero" value
- */
- @VisibleForTesting
- static <V> ReducingRangeMap<V> trim(ReducingRangeMap<V> existing, Ranges
ranges, BiFunction<V, V, V> reduce)
+ public static <V> ReducingRangeMap<V> create(Ranges ranges, V value)
{
- boolean inclusiveEnds = inclusiveEnds(existing.inclusiveEnds,
existing.size() > 0, ranges.size() > 0 && ranges.get(0).endInclusive(),
ranges.size() > 0);
- ReducingRangeMap.Builder<V> builder = new
ReducingRangeMap.Builder<>(inclusiveEnds, existing.size());
+ if (value == null)
+ throw new IllegalArgumentException();
Review Comment:
I disagree; IllegalArgumentException is more specific than
NullPointerException when null is an illegal argument.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]