This is an automated email from the ASF dual-hosted git repository.
benedict pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra-accord.git
The following commit(s) were added to refs/heads/trunk by this push:
new ad6d9c74 Fix AbstractKeys.without (and CoordinateEphemeralRead
execution in future epoch)
ad6d9c74 is described below
commit ad6d9c748984d64518377510434e59923b7c3183
Author: Benedict Elliott Smith <[email protected]>
AuthorDate: Tue Nov 12 13:04:37 2024 +0000
Fix AbstractKeys.without (and CoordinateEphemeralRead execution in future
epoch)
patch by Benedict; reviewed by David Capwell for CASSANDRA-20095
---
.../accord/coordinate/CoordinateEphemeralRead.java | 2 +-
.../src/main/java/accord/primitives/Keys.java | 11 +++--
.../main/java/accord/primitives/RoutingKeys.java | 4 ++
.../src/main/java/accord/utils/SortedArrays.java | 10 ++--
accord-core/src/test/java/accord/KeysTest.java | 57 ++++++++++++++++++++++
5 files changed, 73 insertions(+), 11 deletions(-)
diff --git
a/accord-core/src/main/java/accord/coordinate/CoordinateEphemeralRead.java
b/accord-core/src/main/java/accord/coordinate/CoordinateEphemeralRead.java
index ab571c70..565b3905 100644
--- a/accord-core/src/main/java/accord/coordinate/CoordinateEphemeralRead.java
+++ b/accord-core/src/main/java/accord/coordinate/CoordinateEphemeralRead.java
@@ -136,6 +136,6 @@ public class CoordinateEphemeralRead extends
AbstractCoordinatePreAccept<Result,
{
Deps deps = Deps.merge(oks, oks.domainSize(), SortedListMap::getValue,
ok -> ok.deps);
topologies = node.topology().reselect(topologies,
QuorumEpochIntersections.preaccept.include, route, executeAtEpoch,
executeAtEpoch, Owned);
- new ExecuteEphemeralRead(node, topologies, route, txnId, txn,
executeAtEpoch, deps, this).start();
+ new ExecuteEphemeralRead(node, topologies, route,
txnId.withEpoch(executeAtEpoch), txn, executeAtEpoch, deps, this).start();
}
}
diff --git a/accord-core/src/main/java/accord/primitives/Keys.java
b/accord-core/src/main/java/accord/primitives/Keys.java
index abfd62b5..3469db7d 100644
--- a/accord-core/src/main/java/accord/primitives/Keys.java
+++ b/accord-core/src/main/java/accord/primitives/Keys.java
@@ -262,16 +262,22 @@ public class Keys extends AbstractKeys<Key> implements
Seekables<Key, Keys>
public static Keys of(Set<? extends Key> keys)
{
+ if (keys.size() == 0)
+ return EMPTY;
return ofUnique(keys.toArray(new Key[0]));
}
public static Keys ofSorted(Key ... keys)
{
+ if (keys.length == 0)
+ return EMPTY;
return new Keys(SortedArrays.toUnique(keys));
}
public static Keys ofSortedUnique(Key ... keys)
{
+ if (keys.length == 0)
+ return EMPTY;
if (!isSortedUnique(keys))
throw new IllegalArgumentException(Arrays.toString(keys) + " is
not sorted");
return new Keys(keys);
@@ -282,11 +288,6 @@ public class Keys extends AbstractKeys<Key> implements
Seekables<Key, Keys>
return ofSortedUnique(keys.toArray(new Key[0]));
}
- static Keys ofSortedUnchecked(Key ... keys)
- {
- return new Keys(keys);
- }
-
private Keys wrap(Key[] wrap, AbstractKeys<Key> that)
{
return wrap == keys ? this : wrap == that.keys && that instanceof Keys
? (Keys)that : new Keys(wrap);
diff --git a/accord-core/src/main/java/accord/primitives/RoutingKeys.java
b/accord-core/src/main/java/accord/primitives/RoutingKeys.java
index c9f67cac..25e40d97 100644
--- a/accord-core/src/main/java/accord/primitives/RoutingKeys.java
+++ b/accord-core/src/main/java/accord/primitives/RoutingKeys.java
@@ -49,6 +49,8 @@ public class RoutingKeys extends AbstractUnseekableKeys
implements Unseekables<R
public static RoutingKeys of(RoutingKey ... keys)
{
+ if (keys.length == 0)
+ return EMPTY;
return new RoutingKeys(toUnique(sort(keys)));
}
@@ -68,6 +70,8 @@ public class RoutingKeys extends AbstractUnseekableKeys
implements Unseekables<R
public static RoutingKeys ofSortedUnique(RoutingKey ... keys)
{
+ if (keys.length == 0)
+ return EMPTY;
checkArgument(isSortedUnique(keys));
return new RoutingKeys(keys);
}
diff --git a/accord-core/src/main/java/accord/utils/SortedArrays.java
b/accord-core/src/main/java/accord/utils/SortedArrays.java
index f6d5e714..a1cfe6ef 100644
--- a/accord-core/src/main/java/accord/utils/SortedArrays.java
+++ b/accord-core/src/main/java/accord/utils/SortedArrays.java
@@ -748,15 +748,15 @@ public class SortedArrays
while (keepFrom < keepTo && subtractFrom < subtractTo)
{
- I leftKey = keep[keepFrom];
- I rightKey = subtract[subtractFrom];
- int cmp = leftKey == rightKey ? 0 : comparator.compare(leftKey,
rightKey);
+ I keepKey = keep[keepFrom];
+ I subtractKey = subtract[subtractFrom];
+ int cmp = keepKey == subtractKey ? 0 : comparator.compare(keepKey,
subtractKey);
- if (cmp > 0)
+ if (cmp < 0)
{
result[resultSize++] = keep[keepFrom++];
}
- else if (cmp < 0)
+ else if (cmp > 0)
{
++subtractFrom;
}
diff --git a/accord-core/src/test/java/accord/KeysTest.java
b/accord-core/src/test/java/accord/KeysTest.java
index 138de0d3..67a329e3 100644
--- a/accord-core/src/test/java/accord/KeysTest.java
+++ b/accord-core/src/test/java/accord/KeysTest.java
@@ -19,19 +19,31 @@
package accord;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.IntFunction;
import java.util.stream.IntStream;
import accord.api.Key;
+import accord.api.RoutingKey;
import accord.impl.IntKey;
import accord.impl.IntKey.Raw;
+import accord.primitives.AbstractKeys;
import accord.primitives.Range;
import accord.primitives.Ranges;
import accord.primitives.Keys;
+import accord.primitives.RoutableKey;
+import accord.primitives.Routables;
+import accord.primitives.RoutingKeys;
import accord.utils.Gen;
import accord.utils.Gens;
+import accord.utils.RandomTestRunner;
+import org.agrona.collections.IntHashSet;
+
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -225,6 +237,51 @@ public class KeysTest
});
}
+ @Test
+ public void keysWithout()
+ {
+ without(IntKey::key, Key[]::new, Keys::of, Keys::without);
+ }
+
+ @Test
+ public void routingKeysWithout()
+ {
+ without(IntKey::routing, RoutingKey[]::new, RoutingKeys::of,
RoutingKeys::without);
+ }
+
+ private <K extends RoutableKey, KS extends AbstractKeys<K>> void
without(IntFunction<K> keyFactory,
+
IntFunction<K[]> arrayFactory,
+
Function<K[], KS> keysFactory,
+
BiFunction<KS, KS, Routables<K>> without)
+ {
+ final int maxSize = 100;
+ final int maxKey = 1000;
+ for (int test = 0 ; test < 10000 ; ++test)
+ {
+ RandomTestRunner.test().check(rs -> {
+ K[] keys = arrayFactory.apply(rs.nextInt(2, maxSize));
+ IntHashSet used = new IntHashSet();
+ for (int i = 0 ; i < keys.length ; ++i)
+ {
+ int k = rs.nextInt(maxKey);
+ while (!used.add(k)) k = rs.nextInt(maxKey);
+ keys[i] = keyFactory.apply(k);
+ }
+ int addTo = rs.nextInt(1, keys.length);
+ int removeFrom = addTo - rs.nextInt(addTo + 1);
+ KS add = keysFactory.apply(Arrays.copyOf(keys, addTo));
+ KS remove = keysFactory.apply(Arrays.copyOfRange(keys,
removeFrom, keys.length));
+ Routables<K> result = without.apply(add, remove);
+ Assertions.assertEquals(removeFrom, result.size());
+ if (removeFrom == addTo)
+ Assertions.assertSame(result, add);
+ Arrays.sort(keys, 0, removeFrom);
+ for (int i = 0 ; i < removeFrom ; ++i)
+ Assertions.assertEquals(keys[i], result.get(i));
+ });
+ }
+ }
+
@Test
public void foldl()
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]