belliottsmith commented on code in PR #6:
URL: https://github.com/apache/cassandra-accord/pull/6#discussion_r939512213


##########
accord-core/src/main/java/accord/primitives/Keys.java:
##########
@@ -0,0 +1,449 @@
+package accord.primitives;
+
+import java.util.*;
+import java.util.function.IntFunction;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import accord.api.Key;
+import accord.utils.IndexedFold;
+import accord.utils.IndexedFoldIntersectToLong;
+import accord.utils.IndexedFoldToLong;
+import accord.utils.IndexedPredicate;
+import accord.utils.IndexedRangeFoldToLong;
+import accord.utils.SortedArrays;
+import org.apache.cassandra.utils.concurrent.Inline;
+
+@SuppressWarnings("rawtypes")
+// TODO: this should probably be a BTree
+// TODO: check that foldl call-sites are inlined and optimised by HotSpot
+public class Keys implements Iterable<Key>
+{
+    public static final Keys EMPTY = new Keys(new Key[0]);
+
+    final Key[] keys;
+
+    public Keys(SortedSet<? extends Key> keys)
+    {
+        this.keys = keys.toArray(Key[]::new);
+    }
+
+    public Keys(Collection<? extends Key> keys)
+    {
+        this.keys = keys.toArray(Key[]::new);
+        Arrays.sort(this.keys);
+    }
+
+    public Keys(Key[] keys)
+    {
+        this.keys = keys;
+        Arrays.sort(keys);
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        Keys keys1 = (Keys) o;
+        return Arrays.equals(keys, keys1.keys);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return Arrays.hashCode(keys);
+    }
+
+    public int indexOf(Key key)
+    {
+        return Arrays.binarySearch(keys, key);
+    }
+
+    public boolean contains(Key key)
+    {
+        return indexOf(key) >= 0;
+    }
+
+    public Key get(int indexOf)
+    {
+        return keys[indexOf];
+    }
+
+    public boolean isEmpty()
+    {
+        return keys.length == 0;
+    }
+
+    public int size()
+    {
+        return keys.length;
+    }
+
+    public Keys select(int[] indexes)
+    {
+        Key[] selection = new Key[indexes.length];
+        for (int i = 0 ; i < indexes.length ; ++i)
+            selection[i] = keys[indexes[i]];
+        return new Keys(selection);
+    }
+
+    /**
+     * return true if this keys collection contains all keys found in the 
given keys
+     */
+    public boolean containsAll(Keys that)
+    {
+        if (that.isEmpty())
+            return true;
+
+        return foldlIntersect(that, (li, ri, k, p, v) -> v + 1, 0, 0, 0) == 
that.size();
+    }
+
+    public Keys union(Keys that)
+    {
+        return wrap(SortedArrays.linearUnion(keys, that.keys, Key[]::new), 
that);
+    }
+
+    public Keys intersect(Keys that)
+    {
+        return wrap(SortedArrays.linearIntersection(keys, that.keys, 
Key[]::new), that);
+    }
+
+    public Keys slice(KeyRanges ranges)
+    {
+        return wrap(SortedArrays.sliceWithOverlaps(keys, ranges.ranges, 
Key[]::new, (k, r) -> -r.compareTo(k), KeyRange::compareTo));
+    }
+
+    public int search(int lowerBound, int upperBound, Object key, 
Comparator<Object> comparator)
+    {
+        return Arrays.binarySearch(keys, lowerBound, upperBound, key, 
comparator);
+    }
+
+    public int findNext(Key key, int startIndex)
+    {
+        return SortedArrays.exponentialSearch(keys, startIndex, keys.length, 
key);
+    }
+
+    // returns thisIdx in top 32 bits, thatIdx in bottom
+    public long findNextIntersection(int thisIdx, Keys that, int thatIdx)
+    {
+        return SortedArrays.findNextIntersection(this.keys, thisIdx, 
that.keys, thatIdx);
+    }
+
+    public Keys with(Key key)
+    {
+        int insertPos = Arrays.binarySearch(keys, key);
+        if (insertPos >= 0)
+            return this;
+        insertPos = -1 - insertPos;
+
+        Key[] src = keys;
+        Key[] trg = new Key[src.length + 1];
+        System.arraycopy(src, 0, trg, 0, insertPos);
+        trg[insertPos] = key;
+        System.arraycopy(src, insertPos, trg, insertPos + 1, src.length - 
insertPos);
+        return new Keys(trg);
+    }
+
+    public Stream<Key> stream()
+    {
+        return Stream.of(keys);
+    }
+
+    @Override
+    public Iterator<Key> iterator()
+    {
+        return new Iterator<>()
+        {
+            int i = 0;
+            @Override
+            public boolean hasNext()
+            {
+                return i < keys.length;
+            }
+
+            @Override
+            public Key next()
+            {
+                return keys[i++];
+            }
+        };
+    }
+
+    public static Keys of(Key k0, Key... kn)
+    {
+        Key[] keys = new Key[kn.length + 1];
+        keys[0] = k0;
+        for (int i=0; i<kn.length; i++)
+            keys[i + 1] = kn[i];
+
+        return new Keys(keys);
+    }
+
+    public boolean any(KeyRanges ranges, Predicate<Key> predicate)
+    {
+        return 1 == foldl(ranges, (i1, key, i2, i3) -> predicate.test(key) ? 1 
: 0, 0, 0, 1);
+    }
+
+    public boolean any(IndexedPredicate<Key> predicate)
+    {
+        return 1 == foldl((i, key, p, v) -> predicate.test(i, key) ? 1 : 0, 0, 
0, 1);
+    }
+
+    /**
+     * Count the number of keys matching the predicate and intersecting with 
the given ranges.
+     * If terminateAfter is greater than 0, the method will return once 
terminateAfter matches are encountered
+     */
+    @Inline
+    public <V> V foldl(KeyRanges rs, IndexedFold<Key, V> fold, V accumulator)
+    {
+        int ai = 0, ri = 0;
+        while (true)
+        {
+            long ari = rs.findNextIntersection(ri, this, ai);
+            if (ari < 0)
+                break;
+
+            ai = (int)(ari >>> 32);
+            ri = (int)ari;
+            KeyRange range = rs.get(ri);
+            int nextai = range.higherKeyIndex(this, ai + 1, keys.length);
+            while (ai < nextai)
+            {
+                accumulator = fold.apply(ai, get(ai), accumulator);
+                ++ai;
+            }
+        }
+
+        return accumulator;
+    }
+
+    @Inline
+    public long foldl(KeyRanges rs, IndexedFoldToLong<Key> fold, long param, 
long initialValue, long terminalValue)

Review Comment:
   If we get rid of it then `ShardedRanges::addKeyIndex` likely becomes a 
non-static lambda.



-- 
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]

Reply via email to