From e9d3050a2b90f1bb7b9635ba17f35b052b659659 Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" Date: Tue, 3 Dec 2024 07:38:31 -0600 Subject: [PATCH] Binary search WIP --- binary-search/pom.xml | 56 ++++++++++++ .../common/binarysearch/BinarySearch.java | 72 +++++++++++++++ .../binarysearch/CustomMidpointIntRange.java | 70 ++++++++++++++ .../binarysearch/CustomMidpointLongRange.java | 68 ++++++++++++++ .../common/binarysearch/IntRange.java | 91 +++++++++++++++++++ .../common/binarysearch/LongRange.java | 91 +++++++++++++++++++ .../common/binarysearch/ObjRange.java | 52 +++++++++++ binary-search/src/main/java/module-info.java | 5 + .../common/binarysearch/TestIntRange.java | 68 ++++++++++++++ .../function/ExceptionObjIntFunction.java | 16 ++++ .../function/ExceptionObjIntPredicate.java | 24 +++++ .../function/ExceptionObjLongFunction.java | 16 ++++ .../function/ExceptionObjLongPredicate.java | 24 +++++ .../common/function/ObjIntFunction.java | 16 ++++ .../common/function/ObjIntPredicate.java | 24 +++++ .../common/function/ObjLongFunction.java | 16 ++++ .../common/function/ObjLongPredicate.java | 24 +++++ pom.xml | 1 + 18 files changed, 734 insertions(+) create mode 100644 binary-search/pom.xml create mode 100644 binary-search/src/main/java/io/smallrye/common/binarysearch/BinarySearch.java create mode 100644 binary-search/src/main/java/io/smallrye/common/binarysearch/CustomMidpointIntRange.java create mode 100644 binary-search/src/main/java/io/smallrye/common/binarysearch/CustomMidpointLongRange.java create mode 100644 binary-search/src/main/java/io/smallrye/common/binarysearch/IntRange.java create mode 100644 binary-search/src/main/java/io/smallrye/common/binarysearch/LongRange.java create mode 100644 binary-search/src/main/java/io/smallrye/common/binarysearch/ObjRange.java create mode 100644 binary-search/src/main/java/module-info.java create mode 100644 binary-search/src/test/java/io/smallrye/common/binarysearch/TestIntRange.java create mode 100644 function/src/main/java/io/smallrye/common/function/ExceptionObjIntFunction.java create mode 100644 function/src/main/java/io/smallrye/common/function/ExceptionObjIntPredicate.java create mode 100644 function/src/main/java/io/smallrye/common/function/ExceptionObjLongFunction.java create mode 100644 function/src/main/java/io/smallrye/common/function/ExceptionObjLongPredicate.java create mode 100644 function/src/main/java/io/smallrye/common/function/ObjIntFunction.java create mode 100644 function/src/main/java/io/smallrye/common/function/ObjIntPredicate.java create mode 100644 function/src/main/java/io/smallrye/common/function/ObjLongFunction.java create mode 100644 function/src/main/java/io/smallrye/common/function/ObjLongPredicate.java diff --git a/binary-search/pom.xml b/binary-search/pom.xml new file mode 100644 index 00000000..6830b6c5 --- /dev/null +++ b/binary-search/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + + + io.smallrye.common + smallrye-common-parent + 2.9.0-SNAPSHOT + + + smallrye-common-binary-search + + SmallRye Common: Binary search + + + + ${project.groupId} + smallrye-common-function + + + org.junit.jupiter + junit-jupiter-engine + test + + + + + + coverage + + @{jacocoArgLine} + + + + + org.jacoco + jacoco-maven-plugin + + + report + verify + + report + + + + + + + + + + + \ No newline at end of file diff --git a/binary-search/src/main/java/io/smallrye/common/binarysearch/BinarySearch.java b/binary-search/src/main/java/io/smallrye/common/binarysearch/BinarySearch.java new file mode 100644 index 00000000..effd1f25 --- /dev/null +++ b/binary-search/src/main/java/io/smallrye/common/binarysearch/BinarySearch.java @@ -0,0 +1,72 @@ +package io.smallrye.common.binarysearch; + +/** + * A utility class which provides multiple variations on binary searching. + * + *

Ranges

+ * + * The binary search algorithm operates over a range of values. + * The search will always return in logarithmic time with respect to the search interval. + * This implementation supports multiple kinds of value ranges: + * + * + * Each of these methods returns an object with {@code find()} methods that perform variations on the binary search. + * + *

Range predicates

+ * + * Ranges are searched by predicate. + * The predicate is evaluated for the lowest value within the range + * (that is, the value closest to the {@code from} argument) for which it returns {@code true}. + * If no value satisfies the predicate, the highest value (that is, the value given for the {@code to} argument) is returned. + * The value returned by each {@code find()} method is always within the range {@code [from, to]}. + *

+ * In order to be well-defined, the predicate must be continuous, which is to say that + * given some value {@code n} which is the first value in the interval which satisfies the predicate, + * the predicate must return {@code false} for all {@code < n} and {@code true} for all {@code >= n} + * over the interval of {@code [from, to)}. + * If this constraint does not hold, then the results of the search will not be well-defined. + * The behavior of the predicate outside of this range does not affect the well-definedness of the search operation. + * + *

Inverted ranges

+ * + * It is possible to search over an inverted range, i.e. + * a range for which {@code to} is numerically lower than {@code from}. + * While such searches are well-defined, it should be noted that the {@code from} bound + * remains inclusive while the {@code to} bound remains exclusive, + * which might be surprising in some circumstances. + */ +public final class BinarySearch { + private BinarySearch() { + } + + /** + * {@return an object which can perform binary searches over an integer range (not null)} + * The returned object operates on a signed range by default. + * + * @see IntRange#unsigned() + */ + public static IntRange intRange() { + return IntRange.signed; + } + + /** + * {@return an object which can perform binary searches over a long integer range (not null)} + * The returned object operates on a signed range by default. + * + * @see LongRange#unsigned() + */ + public static LongRange longRange() { + return LongRange.signed; + } + + /** + * {@return an object which can perform binary searches over an object range (not null)} + */ + public static ObjRange objRange() { + return ObjRange.instance; + } +} diff --git a/binary-search/src/main/java/io/smallrye/common/binarysearch/CustomMidpointIntRange.java b/binary-search/src/main/java/io/smallrye/common/binarysearch/CustomMidpointIntRange.java new file mode 100644 index 00000000..5d63ae22 --- /dev/null +++ b/binary-search/src/main/java/io/smallrye/common/binarysearch/CustomMidpointIntRange.java @@ -0,0 +1,70 @@ +package io.smallrye.common.binarysearch; + +import java.util.Comparator; +import java.util.function.BiPredicate; +import java.util.function.IntBinaryOperator; +import java.util.function.IntPredicate; +import java.util.function.Predicate; + +import io.smallrye.common.function.ObjIntFunction; +import io.smallrye.common.function.ObjIntPredicate; + +/** + * Binary searches over an integer range which use a customized midpoint function. + * + * @see IntRange#customMidpoint() + */ +public final class CustomMidpointIntRange { + private CustomMidpointIntRange() { + } + + static final CustomMidpointIntRange instance = new CustomMidpointIntRange(); + + public int find(int from, int to, IntBinaryOperator midpoint, IntPredicate test) { + return find(test, from, to, midpoint, IntPredicate::test); + } + + public int find(C collection, int from, int to, IntBinaryOperator midpoint, ObjIntPredicate test) { + int low = from; + int high = to; + + int mid = midpoint.applyAsInt(low, high); + int newMid; + for (;;) { + if (test.test(collection, mid)) { + high = mid; + newMid = midpoint.applyAsInt(low, high); + if (mid == newMid) { + return low; + } + } else { + low = mid; + newMid = midpoint.applyAsInt(low, high); + if (mid == newMid) { + return high; + } + } + mid = newMid; + } + } + + public int find(C collection, int from, int to, IntBinaryOperator midpoint, ObjIntFunction keyExtractor, + Predicate test) { + return find(collection, test, from, to, midpoint, keyExtractor, Predicate::test); + } + + public int find(C collection, V searchVal, int from, int to, IntBinaryOperator midpoint, + ObjIntFunction keyExtractor, BiPredicate keyTester) { + return find(collection, from, to, midpoint, (c, i) -> keyTester.test(searchVal, keyExtractor.apply(c, i))); + } + + public int findFirst(C collection, K searchKey, int from, int to, IntBinaryOperator midpoint, + ObjIntFunction keyExtractor, Comparator cmp) { + return find(collection, searchKey, from, to, midpoint, keyExtractor, (v, k) -> cmp.compare(v, k) >= 0); + } + + public > int findFirst(C collection, K searchKey, int from, int to, + IntBinaryOperator midpoint, ObjIntFunction keyExtractor) { + return findFirst(collection, searchKey, from, to, midpoint, keyExtractor, Comparator.naturalOrder()); + } +} diff --git a/binary-search/src/main/java/io/smallrye/common/binarysearch/CustomMidpointLongRange.java b/binary-search/src/main/java/io/smallrye/common/binarysearch/CustomMidpointLongRange.java new file mode 100644 index 00000000..f3285452 --- /dev/null +++ b/binary-search/src/main/java/io/smallrye/common/binarysearch/CustomMidpointLongRange.java @@ -0,0 +1,68 @@ +package io.smallrye.common.binarysearch; + +import java.util.Comparator; +import java.util.function.BiPredicate; +import java.util.function.LongBinaryOperator; +import java.util.function.LongPredicate; +import java.util.function.Predicate; + +import io.smallrye.common.function.ObjLongFunction; +import io.smallrye.common.function.ObjLongPredicate; + +/** + * + */ +public final class CustomMidpointLongRange { + private CustomMidpointLongRange() { + } + + static final CustomMidpointLongRange instance = new CustomMidpointLongRange(); + + public long find(long from, long to, LongBinaryOperator midpoint, LongPredicate test) { + return find(test, from, to, midpoint, LongPredicate::test); + } + + public long find(C collection, long from, long to, LongBinaryOperator midpoint, ObjLongPredicate test) { + long low = from; + long high = to; + + long mid = midpoint.applyAsLong(low, high); + long newMid; + for (;;) { + if (test.test(collection, mid)) { + high = mid; + newMid = midpoint.applyAsLong(low, high); + if (mid == newMid) { + return low; + } + } else { + low = mid; + newMid = midpoint.applyAsLong(low, high); + if (mid == newMid) { + return high; + } + } + mid = newMid; + } + } + + public long find(C collection, long from, long to, LongBinaryOperator midpoint, ObjLongFunction keyExtractor, + Predicate test) { + return find(collection, test, from, to, midpoint, keyExtractor, Predicate::test); + } + + public long find(C collection, V searchVal, long from, long to, LongBinaryOperator midpoint, + ObjLongFunction keyExtractor, BiPredicate keyTester) { + return find(collection, from, to, midpoint, (c, i) -> keyTester.test(searchVal, keyExtractor.apply(c, i))); + } + + public long findFirst(C collection, K searchKey, long from, long to, LongBinaryOperator midpoint, + ObjLongFunction keyExtractor, Comparator cmp) { + return find(collection, searchKey, from, to, midpoint, keyExtractor, (v, k) -> cmp.compare(v, k) >= 0); + } + + public > long findFirst(C collection, K searchKey, long from, long to, + LongBinaryOperator midpoint, ObjLongFunction keyExtractor) { + return findFirst(collection, searchKey, from, to, midpoint, keyExtractor, Comparator.naturalOrder()); + } +} diff --git a/binary-search/src/main/java/io/smallrye/common/binarysearch/IntRange.java b/binary-search/src/main/java/io/smallrye/common/binarysearch/IntRange.java new file mode 100644 index 00000000..64c3ca2d --- /dev/null +++ b/binary-search/src/main/java/io/smallrye/common/binarysearch/IntRange.java @@ -0,0 +1,91 @@ +package io.smallrye.common.binarysearch; + +import java.util.Comparator; +import java.util.function.BiPredicate; +import java.util.function.IntBinaryOperator; +import java.util.function.IntPredicate; +import java.util.function.Predicate; + +import io.smallrye.common.function.ObjIntFunction; +import io.smallrye.common.function.ObjIntPredicate; + +/** + * Binary searches over an integer range. + * + * @see BinarySearch#intRange() + */ +public final class IntRange { + private final IntBinaryOperator midpoint; + + private IntRange(IntBinaryOperator midpoint) { + this.midpoint = midpoint; + } + + static final IntRange signed = new IntRange(IntRange::signedMidpoint); + static final IntRange unsigned = new IntRange(IntRange::unsignedMidpoint); + + private static int signedMidpoint(int from, int to) { + return from + (to - from >> 1); + } + + private static int unsignedMidpoint(int from, int to) { + return from + (to - from >>> 1); + } + + /** + * Get the lowest index within the given range that satisfies the given test. + * + * @param from the low end of the range (inclusive) + * @param to the high end of the range (exclusive) + * @param test the test (must not be {@code null}) + * @return the lowest index within the range which satisfies the test, or {@code to} if no values satisfy the range + */ + public int find(int from, int to, IntPredicate test) { + return find(test, from, to, IntPredicate::test); + } + + public int find(C collection, int from, int to, ObjIntPredicate test) { + return customMidpoint().find(collection, from, to, midpoint, test); + } + + public int find(C collection, int from, int to, ObjIntFunction keyExtractor, Predicate test) { + return customMidpoint().find(collection, from, to, midpoint, keyExtractor, test); + } + + public int find(C collection, V searchVal, int from, int to, ObjIntFunction keyExtractor, + BiPredicate keyTester) { + return customMidpoint().find(collection, searchVal, from, to, midpoint, keyExtractor, keyTester); + } + + public int findFirst(C collection, K searchKey, int from, int to, ObjIntFunction keyExtractor, + Comparator cmp) { + return customMidpoint().findFirst(collection, searchKey, from, to, midpoint, keyExtractor, cmp); + } + + public > int findFirst(C collection, K searchKey, int from, int to, + ObjIntFunction keyExtractor) { + return customMidpoint().findFirst(collection, searchKey, from, to, midpoint, keyExtractor); + } + + /** + * {@return an object which can perform binary searches over a signed range (not null)} + */ + public IntRange signed() { + return signed; + } + + /** + * {@return an object which can perform binary searches over an unsigned range (not null)} + */ + public IntRange unsigned() { + return unsigned; + } + + /** + * {@return an object which performs binary searches over a range defined by a custom midpoint function (not + * null)} + */ + public CustomMidpointIntRange customMidpoint() { + return CustomMidpointIntRange.instance; + } +} diff --git a/binary-search/src/main/java/io/smallrye/common/binarysearch/LongRange.java b/binary-search/src/main/java/io/smallrye/common/binarysearch/LongRange.java new file mode 100644 index 00000000..e8499581 --- /dev/null +++ b/binary-search/src/main/java/io/smallrye/common/binarysearch/LongRange.java @@ -0,0 +1,91 @@ +package io.smallrye.common.binarysearch; + +import java.util.Comparator; +import java.util.function.BiPredicate; +import java.util.function.LongBinaryOperator; +import java.util.function.LongPredicate; +import java.util.function.Predicate; + +import io.smallrye.common.function.ObjLongFunction; +import io.smallrye.common.function.ObjLongPredicate; + +/** + * Binary searches over a long integer range. + * + * @see BinarySearch#longRange() + */ +public final class LongRange { + private final LongBinaryOperator midpoint; + + private LongRange(LongBinaryOperator midpoint) { + this.midpoint = midpoint; + } + + static final LongRange signed = new LongRange(LongRange::signedMidpoint); + static final LongRange unsigned = new LongRange(LongRange::unsignedMidpoint); + + private static long signedMidpoint(long from, long to) { + return from + (to - from >> 1); + } + + private static long unsignedMidpoint(long from, long to) { + return from + (to - from >>> 1); + } + + /** + * Get the lowest index within the given range that satisfies the given test. + * + * @param from the low end of the range (inclusive) + * @param to the high end of the range (exclusive) + * @param test the test (must not be {@code null}) + * @return the lowest index within the range which satisfies the test, or {@code to} if no values satisfy the range + */ + public long find(long from, long to, LongPredicate test) { + return find(test, from, to, LongPredicate::test); + } + + public long find(C collection, long from, long to, ObjLongPredicate test) { + return customMidpoint().find(collection, from, to, midpoint, test); + } + + public long find(C collection, long from, long to, ObjLongFunction keyExtractor, Predicate test) { + return customMidpoint().find(collection, from, to, midpoint, keyExtractor, test); + } + + public long find(C collection, V searchVal, long from, long to, ObjLongFunction keyExtractor, + BiPredicate keyTester) { + return customMidpoint().find(collection, searchVal, from, to, midpoint, keyExtractor, keyTester); + } + + public long findFirst(C collection, K searchKey, long from, long to, ObjLongFunction keyExtractor, + Comparator cmp) { + return customMidpoint().findFirst(collection, searchKey, from, to, midpoint, keyExtractor, cmp); + } + + public > long findFirst(C collection, K searchKey, long from, long to, + ObjLongFunction keyExtractor) { + return customMidpoint().findFirst(collection, searchKey, from, to, midpoint, keyExtractor); + } + + /** + * {@return an object which can perform binary searches over a signed range (not null)} + */ + public LongRange signed() { + return signed; + } + + /** + * {@return an object which can perform binary searches over an unsigned range (not null)} + */ + public LongRange unsigned() { + return unsigned; + } + + /** + * {@return an object which performs binary searches over a range defined by a custom midpoint function (not + * null)} + */ + public CustomMidpointLongRange customMidpoint() { + return CustomMidpointLongRange.instance; + } +} diff --git a/binary-search/src/main/java/io/smallrye/common/binarysearch/ObjRange.java b/binary-search/src/main/java/io/smallrye/common/binarysearch/ObjRange.java new file mode 100644 index 00000000..049d2f38 --- /dev/null +++ b/binary-search/src/main/java/io/smallrye/common/binarysearch/ObjRange.java @@ -0,0 +1,52 @@ +package io.smallrye.common.binarysearch; + +import java.util.Objects; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; +import java.util.function.BinaryOperator; +import java.util.function.Predicate; + +/** + * Binary searches over a range of objects. + * + * @see BinarySearch#objRange() + */ +public final class ObjRange { + private ObjRange() { + } + + static final ObjRange instance = new ObjRange(); + + public T find(T from, T to, BinaryOperator midpoint, Predicate test) { + return find(test, from, to, midpoint, Predicate::test); + } + + public T find(C collection, T from, T to, BinaryOperator midpoint, BiPredicate test) { + T low = from; + T high = to; + + T mid = midpoint.apply(low, high); + T newMid; + for (;;) { + if (test.test(collection, mid)) { + high = mid; + newMid = midpoint.apply(low, high); + if (Objects.equals(mid, newMid)) { + return low; + } + } else { + low = mid; + newMid = midpoint.apply(low, high); + if (Objects.equals(mid, newMid)) { + return high; + } + } + mid = newMid; + } + } + + public T find(C collection, T from, T to, BinaryOperator midpoint, BiFunction keyExtractor, + Predicate test) { + return find(collection, from, to, midpoint, (c, idx) -> test.test(keyExtractor.apply(c, idx))); + } +} diff --git a/binary-search/src/main/java/module-info.java b/binary-search/src/main/java/module-info.java new file mode 100644 index 00000000..77002559 --- /dev/null +++ b/binary-search/src/main/java/module-info.java @@ -0,0 +1,5 @@ +module io.smallrye.common.binarysearch { + requires io.smallrye.common.function; + + exports io.smallrye.common.binarysearch; +} \ No newline at end of file diff --git a/binary-search/src/test/java/io/smallrye/common/binarysearch/TestIntRange.java b/binary-search/src/test/java/io/smallrye/common/binarysearch/TestIntRange.java new file mode 100644 index 00000000..1a63de62 --- /dev/null +++ b/binary-search/src/test/java/io/smallrye/common/binarysearch/TestIntRange.java @@ -0,0 +1,68 @@ +package io.smallrye.common.binarysearch; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public final class TestIntRange { + public TestIntRange() { + } + + private static final int MAX_INT_UNSIGNED = 0xffffffff; // == -1 + + @Test + public void testEmptyRange() { + assertEquals(1, BinarySearch.intRange().find(1, 1, i -> true)); + assertEquals(10, BinarySearch.intRange().find(10, 10, i -> true)); + } + + @Test + public void testRange() { + assertEquals(0, BinarySearch.intRange().find(0, 10, i -> i >= -100)); + assertEquals(0, BinarySearch.intRange().find(0, 10, i -> i >= 0)); + assertEquals(1, BinarySearch.intRange().find(0, 10, i -> i > 0)); + assertEquals(4, BinarySearch.intRange().find(0, 10, i -> i >= 4)); + assertEquals(5, BinarySearch.intRange().find(0, 10, i -> i > 4)); + assertEquals(5, BinarySearch.intRange().find(0, 10, i -> i >= 5)); + assertEquals(6, BinarySearch.intRange().find(0, 10, i -> i > 5)); + assertEquals(10, BinarySearch.intRange().find(0, 10, i -> i >= 10)); + assertEquals(10, BinarySearch.intRange().find(0, 10, i -> false)); + assertEquals(0, BinarySearch.intRange().find(0, 10, i -> true)); + // signed-specific ranges + assertEquals(-10, BinarySearch.intRange().find(-10, 10, i -> true)); + } + + @Test + public void testRangeUnsigned() { + assertEquals(0, BinarySearch.intRange().unsigned().find(0, 10, i -> i >= 0)); + assertEquals(1, BinarySearch.intRange().unsigned().find(0, 10, i -> i > 0)); + assertEquals(4, BinarySearch.intRange().unsigned().find(0, 10, i -> i >= 4)); + assertEquals(5, BinarySearch.intRange().unsigned().find(0, 10, i -> i > 4)); + assertEquals(5, BinarySearch.intRange().unsigned().find(0, 10, i -> i >= 5)); + assertEquals(6, BinarySearch.intRange().unsigned().find(0, 10, i -> i > 5)); + assertEquals(10, BinarySearch.intRange().unsigned().find(0, 10, i -> i >= 10)); + assertEquals(10, BinarySearch.intRange().unsigned().find(0, 10, i -> false)); + assertEquals(0, BinarySearch.intRange().unsigned().find(0, 10, i -> true)); + // unsigned-specific ranges + assertEquals(0, BinarySearch.intRange().unsigned().find(0, MAX_INT_UNSIGNED, i -> true)); + assertEquals(0x8000_0000, BinarySearch.intRange().unsigned().find(0, MAX_INT_UNSIGNED, + i -> Integer.compareUnsigned(i, 0x8000_0000) >= 0)); + } + + @Test + public void testBigRange() { + assertEquals(1025, BinarySearch.intRange().find(0, Integer.MAX_VALUE, i -> i >= 1025)); + assertEquals(1026, BinarySearch.intRange().find(0, Integer.MAX_VALUE, i -> i >= 1026)); + assertEquals(99210, BinarySearch.intRange().find(49203, 848392, i -> i >= 99210)); + assertEquals(Integer.MAX_VALUE, BinarySearch.intRange().find(0, Integer.MAX_VALUE, i -> false)); + assertEquals(0, BinarySearch.intRange().find(0, Integer.MAX_VALUE, i -> true)); + } + + @Test + public void testRevRange() { + assertEquals(5, BinarySearch.intRange().find(9, -1, i -> i < 5)); + assertEquals(6, BinarySearch.intRange().find(9, -1, i -> i <= 5)); + assertEquals(0, BinarySearch.intRange().find(9, -1, i -> i < 0)); + assertEquals(1, BinarySearch.intRange().find(9, -1, i -> i <= 0)); + } +} diff --git a/function/src/main/java/io/smallrye/common/function/ExceptionObjIntFunction.java b/function/src/main/java/io/smallrye/common/function/ExceptionObjIntFunction.java new file mode 100644 index 00000000..f2270d26 --- /dev/null +++ b/function/src/main/java/io/smallrye/common/function/ExceptionObjIntFunction.java @@ -0,0 +1,16 @@ +package io.smallrye.common.function; + +import java.util.Objects; + +/** + * A function which operates on an object and an integer, yielding an object. + */ +public interface ExceptionObjIntFunction { + R apply(T arg1, int arg2) throws E; + + default ExceptionObjIntFunction andThen(ExceptionFunction after) + throws E { + Objects.requireNonNull(after); + return (T t, int u) -> after.apply(apply(t, u)); + } +} diff --git a/function/src/main/java/io/smallrye/common/function/ExceptionObjIntPredicate.java b/function/src/main/java/io/smallrye/common/function/ExceptionObjIntPredicate.java new file mode 100644 index 00000000..70104e67 --- /dev/null +++ b/function/src/main/java/io/smallrye/common/function/ExceptionObjIntPredicate.java @@ -0,0 +1,24 @@ +package io.smallrye.common.function; + +import java.util.Objects; + +/** + * A predicate that operates on an object and an integer. + */ +public interface ExceptionObjIntPredicate { + boolean test(T object, int value) throws E; + + default ExceptionObjIntPredicate and(ExceptionObjIntPredicate other) { + Objects.requireNonNull(other); + return (t, i) -> test(t, i) && other.test(t, i); + } + + default ExceptionObjIntPredicate negate() { + return (t, i) -> !test(t, i); + } + + default ExceptionObjIntPredicate or(ExceptionObjIntPredicate other) { + Objects.requireNonNull(other); + return (t, i) -> test(t, i) || other.test(t, i); + } +} diff --git a/function/src/main/java/io/smallrye/common/function/ExceptionObjLongFunction.java b/function/src/main/java/io/smallrye/common/function/ExceptionObjLongFunction.java new file mode 100644 index 00000000..55e5ed61 --- /dev/null +++ b/function/src/main/java/io/smallrye/common/function/ExceptionObjLongFunction.java @@ -0,0 +1,16 @@ +package io.smallrye.common.function; + +import java.util.Objects; + +/** + * A function which operates on an object and a long integer, yielding an object. + */ +public interface ExceptionObjLongFunction { + R apply(T arg1, long arg2) throws E; + + default ExceptionObjLongFunction andThen(ExceptionFunction after) + throws E { + Objects.requireNonNull(after); + return (T t, long u) -> after.apply(apply(t, u)); + } +} diff --git a/function/src/main/java/io/smallrye/common/function/ExceptionObjLongPredicate.java b/function/src/main/java/io/smallrye/common/function/ExceptionObjLongPredicate.java new file mode 100644 index 00000000..0d0df0a9 --- /dev/null +++ b/function/src/main/java/io/smallrye/common/function/ExceptionObjLongPredicate.java @@ -0,0 +1,24 @@ +package io.smallrye.common.function; + +import java.util.Objects; + +/** + * A predicate that operates on an object and a long integer. + */ +public interface ExceptionObjLongPredicate { + boolean test(T object, long value); + + default ExceptionObjLongPredicate and(ExceptionObjLongPredicate other) { + Objects.requireNonNull(other); + return (t, i) -> test(t, i) && other.test(t, i); + } + + default ExceptionObjLongPredicate negate() { + return (t, i) -> !test(t, i); + } + + default ExceptionObjLongPredicate or(ExceptionObjLongPredicate other) { + Objects.requireNonNull(other); + return (t, i) -> test(t, i) || other.test(t, i); + } +} diff --git a/function/src/main/java/io/smallrye/common/function/ObjIntFunction.java b/function/src/main/java/io/smallrye/common/function/ObjIntFunction.java new file mode 100644 index 00000000..fcc5c6ae --- /dev/null +++ b/function/src/main/java/io/smallrye/common/function/ObjIntFunction.java @@ -0,0 +1,16 @@ +package io.smallrye.common.function; + +import java.util.Objects; +import java.util.function.Function; + +/** + * A function which operates on an object and an integer, yielding an object. + */ +public interface ObjIntFunction { + R apply(T arg1, int arg2); + + default ObjIntFunction andThen(Function after) { + Objects.requireNonNull(after); + return (T t, int u) -> after.apply(apply(t, u)); + } +} diff --git a/function/src/main/java/io/smallrye/common/function/ObjIntPredicate.java b/function/src/main/java/io/smallrye/common/function/ObjIntPredicate.java new file mode 100644 index 00000000..c7c33d55 --- /dev/null +++ b/function/src/main/java/io/smallrye/common/function/ObjIntPredicate.java @@ -0,0 +1,24 @@ +package io.smallrye.common.function; + +import java.util.Objects; + +/** + * A predicate that operates on an object and an integer. + */ +public interface ObjIntPredicate { + boolean test(T object, int value); + + default ObjIntPredicate and(ObjIntPredicate other) { + Objects.requireNonNull(other); + return (t, i) -> test(t, i) && other.test(t, i); + } + + default ObjIntPredicate negate() { + return (t, i) -> !test(t, i); + } + + default ObjIntPredicate or(ObjIntPredicate other) { + Objects.requireNonNull(other); + return (t, i) -> test(t, i) || other.test(t, i); + } +} diff --git a/function/src/main/java/io/smallrye/common/function/ObjLongFunction.java b/function/src/main/java/io/smallrye/common/function/ObjLongFunction.java new file mode 100644 index 00000000..7ce04cec --- /dev/null +++ b/function/src/main/java/io/smallrye/common/function/ObjLongFunction.java @@ -0,0 +1,16 @@ +package io.smallrye.common.function; + +import java.util.Objects; +import java.util.function.Function; + +/** + * A function which operates on an object and a long integer, yielding an object. + */ +public interface ObjLongFunction { + R apply(T arg1, long arg2); + + default ObjLongFunction andThen(Function after) { + Objects.requireNonNull(after); + return (T t, long u) -> after.apply(apply(t, u)); + } +} diff --git a/function/src/main/java/io/smallrye/common/function/ObjLongPredicate.java b/function/src/main/java/io/smallrye/common/function/ObjLongPredicate.java new file mode 100644 index 00000000..8365940c --- /dev/null +++ b/function/src/main/java/io/smallrye/common/function/ObjLongPredicate.java @@ -0,0 +1,24 @@ +package io.smallrye.common.function; + +import java.util.Objects; + +/** + * A predicate that operates on an object and a long integer. + */ +public interface ObjLongPredicate { + boolean test(T object, long value); + + default ObjLongPredicate and(ObjLongPredicate other) { + Objects.requireNonNull(other); + return (t, i) -> test(t, i) && other.test(t, i); + } + + default ObjLongPredicate negate() { + return (t, i) -> !test(t, i); + } + + default ObjLongPredicate or(ObjLongPredicate other) { + Objects.requireNonNull(other); + return (t, i) -> test(t, i) || other.test(t, i); + } +} diff --git a/pom.xml b/pom.xml index c662b0c0..c14b68d6 100644 --- a/pom.xml +++ b/pom.xml @@ -68,6 +68,7 @@ annotation + binary-search classloader constraint cpu