From 8b0baaafed30e31e0f85c6a85b6c2253ab6bb446 Mon Sep 17 00:00:00 2001 From: javasabr Date: Fri, 26 Sep 2025 21:17:14 +0200 Subject: [PATCH 1/5] extend api --- README.md | 28 ++--- .../rlib/collections/array/Array.java | 5 + .../rlib/collections/array/LockableArray.java | 3 + .../collections/array/impl/AbstractArray.java | 15 +++ .../array/impl/AbstractLockableArray.java | 7 ++ .../operation/LockableOperations.java | 23 +++- .../impl/DefaultLockableOperations.java | 102 +++++++++++++++++- .../functions/BiObjToBooleanFunction.java | 10 ++ .../rlib/functions/IntObjConsumer.java | 4 +- .../rlib/functions/IntObjFunction.java | 4 +- .../rlib/functions/LongObjConsumer.java | 4 +- .../rlib/functions/ObjIntFunction.java | 10 ++ .../rlib/functions/ObjLongFunction.java | 4 +- .../rlib/functions/ObjLongObjConsumer.java | 4 +- .../rlib/functions/ObjObjLongConsumer.java | 4 +- .../javasabr/rlib/functions/TriConsumer.java | 4 +- .../javasabr/rlib/functions/TriFunction.java | 10 ++ 17 files changed, 209 insertions(+), 32 deletions(-) create mode 100644 rlib-functions/src/main/java/javasabr/rlib/functions/BiObjToBooleanFunction.java create mode 100644 rlib-functions/src/main/java/javasabr/rlib/functions/ObjIntFunction.java create mode 100644 rlib-functions/src/main/java/javasabr/rlib/functions/TriFunction.java diff --git a/README.md b/README.md index 12afdbcf..d32316d0 100644 --- a/README.md +++ b/README.md @@ -18,20 +18,20 @@ ext { } dependencies { - implementation "javasabr:rlib-common:$rlibVersion" - implementation "javasabr:rlib-collections:$rlibVersion" - implementation "javasabr:rlib-compiler:$rlibVersion" - implementation "javasabr:rlib-concurrent:$rlibVersion" - implementation "javasabr:rlib-geometry:$rlibVersion" - implementation "javasabr:rlib-logger-api:$rlibVersion" - implementation "javasabr:rlib-logger-slf4j:$rlibVersion" - implementation "javasabr:rlib-plugin-system:$rlibVersion" - implementation "javasabr:rlib-reference:$rlibVersion" - implementation "javasabr:rlib-reusable:$rlibVersion" - implementation "javasabr:rlib-fx:$rlibVersion" - implementation "javasabr:rlib-network:$rlibVersion" - implementation "javasabr:rlib-mail:$rlibVersion" - implementation "javasabr:rlib-testcontainers:$rlibVersion" + implementation "javasabr.rlib:rlib-common:$rlibVersion" + implementation "javasabr.rlib:rlib-collections:$rlibVersion" + implementation "javasabr.rlib:rlib-compiler:$rlibVersion" + implementation "javasabr.rlib:rlib-concurrent:$rlibVersion" + implementation "javasabr.rlib:rlib-geometry:$rlibVersion" + implementation "javasabr.rlib:rlib-logger-api:$rlibVersion" + implementation "javasabr.rlib:rlib-logger-slf4j:$rlibVersion" + implementation "javasabr.rlib:rlib-plugin-system:$rlibVersion" + implementation "javasabr.rlib:rlib-reference:$rlibVersion" + implementation "javasabr.rlib:rlib-reusable:$rlibVersion" + implementation "javasabr.rlib:rlib-fx:$rlibVersion" + implementation "javasabr.rlib:rlib-network:$rlibVersion" + implementation "javasabr.rlib:rlib-mail:$rlibVersion" + implementation "javasabr.rlib:rlib-testcontainers:$rlibVersion" } ``` ## Most interesting parts: diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java index de066a26..d2d76d59 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java @@ -173,6 +173,11 @@ default Iterator iterator() { */ int indexOf(@Nullable Object object); + /** + * @return the index of the object or -1. + */ + int indexOf(Function getter, @Nullable Object object); + int lastIndexOf(@Nullable Object object); T[] toArray(T[] newArray); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/LockableArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/LockableArray.java index e8a89a40..735d6977 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/LockableArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/LockableArray.java @@ -1,7 +1,10 @@ package javasabr.rlib.collections.array; +import javasabr.rlib.collections.operation.LockableOperations; import javasabr.rlib.collections.operation.LockableSource; import javasabr.rlib.common.ThreadSafe; public interface LockableArray extends MutableArray, LockableSource, ThreadSafe { + + LockableOperations> operations(); } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractArray.java index e73f7b2a..f4003e05 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractArray.java @@ -136,6 +136,21 @@ public int indexOf(@Nullable Object object) { return -1; } + @Override + public int indexOf(Function getter, @Nullable Object object) { + if (object == null) { + return -1; + } + @Nullable E[] wrapped = wrapped(); + for (int i = 0, length = size(); i < length; i++) { + //noinspection DataFlowIssue + if (object.equals(getter.apply(wrapped[i]))) { + return i; + } + } + return -1; + } + @Override public int lastIndexOf(@Nullable Object object) { if (object == null) { diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLockableArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLockableArray.java index bf19132a..1c73349d 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLockableArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/AbstractLockableArray.java @@ -2,6 +2,8 @@ import java.util.concurrent.atomic.AtomicInteger; import javasabr.rlib.collections.array.LockableArray; +import javasabr.rlib.collections.operation.LockableOperations; +import javasabr.rlib.collections.operation.impl.DefaultLockableOperations; import javasabr.rlib.common.util.ArrayUtils; import lombok.AccessLevel; import lombok.Getter; @@ -57,4 +59,9 @@ protected int getAndIncrementSize() { protected int decrementAnGetSize() { return size.decrementAndGet(); } + + @Override + public LockableOperations> operations() { + return new DefaultLockableOperations<>(this); + } } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/operation/LockableOperations.java b/rlib-collections/src/main/java/javasabr/rlib/collections/operation/LockableOperations.java index 29bb5588..371d4984 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/operation/LockableOperations.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/operation/LockableOperations.java @@ -1,11 +1,32 @@ package javasabr.rlib.collections.operation; +import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; +import javasabr.rlib.functions.BiObjToBooleanFunction; +import javasabr.rlib.functions.ObjIntFunction; +import javasabr.rlib.functions.TriConsumer; +import javasabr.rlib.functions.TriFunction; public interface LockableOperations { R getInReadLock(Function function); - R getInReadLock(F arg1, BiFunction function); + R getInReadLock(A arg1, BiFunction function); + + R getInReadLock(int arg1, ObjIntFunction function); + + R getInReadLock(A arg1, B arg2, TriFunction function); + + boolean getBooleanInReadLock(A arg1, BiObjToBooleanFunction function); + + void inReadLock(A arg1, BiConsumer function); + + R getInWriteLock(A arg1, BiFunction function); + + R getInWriteLock(A arg1, B arg2, TriFunction function); + + void inWriteLock(A arg1, B arg2, TriConsumer function); + + void inWriteLock(A arg1, BiConsumer function); } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/operation/impl/DefaultLockableOperations.java b/rlib-collections/src/main/java/javasabr/rlib/collections/operation/impl/DefaultLockableOperations.java index 7c27e6e2..c34df0dd 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/operation/impl/DefaultLockableOperations.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/operation/impl/DefaultLockableOperations.java @@ -1,19 +1,115 @@ package javasabr.rlib.collections.operation.impl; +import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; import javasabr.rlib.collections.operation.LockableOperations; import javasabr.rlib.collections.operation.LockableSource; +import javasabr.rlib.functions.BiObjToBooleanFunction; +import javasabr.rlib.functions.ObjIntFunction; +import javasabr.rlib.functions.TriConsumer; +import javasabr.rlib.functions.TriFunction; -public record DefaultLockableOperations(S source) implements LockableOperations { +public record DefaultLockableOperations(S source) + implements LockableOperations { @Override public R getInReadLock(Function function) { - return function.apply(source); + long stamp = source.readLock(); + try { + return function.apply(source); + } finally { + source.readUnlock(stamp); + } } @Override public R getInReadLock(F arg1, BiFunction function) { - return function.apply(source, arg1); + long stamp = source.readLock(); + try { + return function.apply(source, arg1); + } finally { + source.readUnlock(stamp); + } + } + + @Override + public R getInReadLock(int arg1, ObjIntFunction function) { + long stamp = source.readLock(); + try { + return function.apply(source, arg1); + } finally { + source.readUnlock(stamp); + } + } + + @Override + public R getInReadLock(A arg1, B arg2, TriFunction function) { + long stamp = source.readLock(); + try { + return function.apply(source, arg1, arg2); + } finally { + source.readUnlock(stamp); + } + } + + @Override + public boolean getBooleanInReadLock(A arg1, BiObjToBooleanFunction function) { + long stamp = source.readLock(); + try { + return function.apply(source, arg1); + } finally { + source.readUnlock(stamp); + } + } + + @Override + public void inReadLock(A arg1, BiConsumer function) { + long stamp = source.readLock(); + try { + function.accept(source, arg1); + } finally { + source.readUnlock(stamp); + } + } + + @Override + public R getInWriteLock(F arg1, BiFunction function) { + long stamp = source.writeLock(); + try { + return function.apply(source, arg1); + } finally { + source.writeUnlock(stamp); + } + } + + @Override + public R getInWriteLock(A arg1, B arg2, TriFunction function) { + long stamp = source.writeLock(); + try { + return function.apply(source, arg1, arg2); + } finally { + source.writeUnlock(stamp); + } + } + + @Override + public void inWriteLock(A arg1, BiConsumer function) { + long stamp = source.writeLock(); + try { + function.accept(source, arg1); + } finally { + source.writeUnlock(stamp); + } + } + + @Override + public void inWriteLock(A arg1, B arg2, TriConsumer function) { + long stamp = source.writeLock(); + try { + function.accept(source, arg1, arg2); + } finally { + source.writeUnlock(stamp); + } } } diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/BiObjToBooleanFunction.java b/rlib-functions/src/main/java/javasabr/rlib/functions/BiObjToBooleanFunction.java new file mode 100644 index 00000000..a64a1a02 --- /dev/null +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/BiObjToBooleanFunction.java @@ -0,0 +1,10 @@ +package javasabr.rlib.functions; + +/** + * @author JavaSaBr + */ +@FunctionalInterface +public interface BiObjToBooleanFunction { + + boolean apply(A arg1, B arg2); +} diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/IntObjConsumer.java b/rlib-functions/src/main/java/javasabr/rlib/functions/IntObjConsumer.java index f4ddae74..4030c133 100644 --- a/rlib-functions/src/main/java/javasabr/rlib/functions/IntObjConsumer.java +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/IntObjConsumer.java @@ -4,7 +4,7 @@ * @author JavaSaBr */ @FunctionalInterface -public interface IntObjConsumer { +public interface IntObjConsumer { - void accept(int arg1, T arg2); + void accept(int arg1, B arg2); } diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/IntObjFunction.java b/rlib-functions/src/main/java/javasabr/rlib/functions/IntObjFunction.java index 0b7aab83..f319226e 100644 --- a/rlib-functions/src/main/java/javasabr/rlib/functions/IntObjFunction.java +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/IntObjFunction.java @@ -4,7 +4,7 @@ * @author JavaSaBr */ @FunctionalInterface -public interface IntObjFunction { +public interface IntObjFunction { - R apply(int arg1, T arg2); + R apply(int arg1, B arg2); } diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/LongObjConsumer.java b/rlib-functions/src/main/java/javasabr/rlib/functions/LongObjConsumer.java index d4fc4d11..4c9319f0 100644 --- a/rlib-functions/src/main/java/javasabr/rlib/functions/LongObjConsumer.java +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/LongObjConsumer.java @@ -4,7 +4,7 @@ * @author JavaSaBr */ @FunctionalInterface -public interface LongObjConsumer { +public interface LongObjConsumer { - void accept(long arg1, T arg2); + void accept(long arg1, B arg2); } diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/ObjIntFunction.java b/rlib-functions/src/main/java/javasabr/rlib/functions/ObjIntFunction.java new file mode 100644 index 00000000..5bd18832 --- /dev/null +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/ObjIntFunction.java @@ -0,0 +1,10 @@ +package javasabr.rlib.functions; + +/** + * @author JavaSaBr + */ +@FunctionalInterface +public interface ObjIntFunction { + + R apply(A arg1, int arg2); +} diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/ObjLongFunction.java b/rlib-functions/src/main/java/javasabr/rlib/functions/ObjLongFunction.java index 071eaec6..1633f5ea 100644 --- a/rlib-functions/src/main/java/javasabr/rlib/functions/ObjLongFunction.java +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/ObjLongFunction.java @@ -4,7 +4,7 @@ * @author JavaSaBr */ @FunctionalInterface -public interface ObjLongFunction { +public interface ObjLongFunction { - R apply(T arg1, long arg2); + R apply(A arg1, long arg2); } diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/ObjLongObjConsumer.java b/rlib-functions/src/main/java/javasabr/rlib/functions/ObjLongObjConsumer.java index c901313d..828d56ea 100644 --- a/rlib-functions/src/main/java/javasabr/rlib/functions/ObjLongObjConsumer.java +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/ObjLongObjConsumer.java @@ -1,10 +1,10 @@ package javasabr.rlib.functions; @FunctionalInterface -public interface ObjLongObjConsumer { +public interface ObjLongObjConsumer { /** * Performs this operation on the given arguments. */ - void accept(F arg1, long arg2, T arg3); + void accept(A arg1, long arg2, C arg3); } diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/ObjObjLongConsumer.java b/rlib-functions/src/main/java/javasabr/rlib/functions/ObjObjLongConsumer.java index 6aa1397e..32387b36 100644 --- a/rlib-functions/src/main/java/javasabr/rlib/functions/ObjObjLongConsumer.java +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/ObjObjLongConsumer.java @@ -1,10 +1,10 @@ package javasabr.rlib.functions; @FunctionalInterface -public interface ObjObjLongConsumer { +public interface ObjObjLongConsumer { /** * Performs this operation on the given arguments. */ - void accept(F arg1, S arg2, long arg3); + void accept(A arg1, B arg2, long arg3); } diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/TriConsumer.java b/rlib-functions/src/main/java/javasabr/rlib/functions/TriConsumer.java index 45bc6de8..9bbf4de2 100644 --- a/rlib-functions/src/main/java/javasabr/rlib/functions/TriConsumer.java +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/TriConsumer.java @@ -1,10 +1,10 @@ package javasabr.rlib.functions; @FunctionalInterface -public interface TriConsumer { +public interface TriConsumer { /** * Performs this operation on the given arguments. */ - void accept(F arg1, S arg2, T arg3); + void accept(A arg1, B arg2, C arg3); } diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/TriFunction.java b/rlib-functions/src/main/java/javasabr/rlib/functions/TriFunction.java new file mode 100644 index 00000000..910d1eb5 --- /dev/null +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/TriFunction.java @@ -0,0 +1,10 @@ +package javasabr.rlib.functions; + +/** + * @author JavaSaBr + */ +@FunctionalInterface +public interface TriFunction { + + R apply(A arg1, B arg2, C arg3); +} From 61953dd33e384ec0492a59c791f160e3b8b038e0 Mon Sep 17 00:00:00 2001 From: javasabr Date: Sat, 27 Sep 2025 17:47:57 +0200 Subject: [PATCH 2/5] extend api --- .../array/ArrayIterationFunctions.java | 4 + .../rlib/collections/array/IntArray.java | 4 +- .../rlib/collections/array/LongArray.java | 4 +- .../impl/DefaultArrayIterationFunctions.java | 15 +++ .../operation/LockableOperations.java | 6 +- .../impl/DefaultLockableOperations.java | 11 +++ .../common/function/ObjectIntPredicate.java | 10 -- .../javasabr/rlib/common/util/ArrayUtils.java | 98 ------------------- .../javasabr/rlib/functions/ByteFunction.java | 9 ++ .../rlib/functions/ObjIntPredicate.java | 10 ++ .../packet/impl/AbstractPacketReader.java | 3 +- .../packet/impl/AbstractPacketWriter.java | 18 ++-- 12 files changed, 70 insertions(+), 122 deletions(-) delete mode 100644 rlib-common/src/main/java/javasabr/rlib/common/function/ObjectIntPredicate.java create mode 100644 rlib-functions/src/main/java/javasabr/rlib/functions/ByteFunction.java create mode 100644 rlib-functions/src/main/java/javasabr/rlib/functions/ObjIntPredicate.java diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java index 37bfccce..d4c08bbb 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java @@ -2,6 +2,7 @@ import java.util.function.BiConsumer; import java.util.function.BiPredicate; +import javasabr.rlib.functions.ObjIntPredicate; import javasabr.rlib.functions.ObjObjLongConsumer; import javasabr.rlib.functions.TriConsumer; import org.jspecify.annotations.Nullable; @@ -11,6 +12,9 @@ public interface ArrayIterationFunctions { @Nullable E findAny(T arg1, BiPredicate filter); + @Nullable + E findAny(int arg1, ObjIntPredicate filter); + ArrayIterationFunctions forEach(T arg1, BiConsumer consumer); ArrayIterationFunctions forEach(F arg1, S arg2, TriConsumer consumer); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/IntArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/IntArray.java index eac241ab..9cd085a1 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/IntArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/IntArray.java @@ -10,8 +10,10 @@ */ public interface IntArray extends Iterable, Serializable, Cloneable, RandomAccess { + ImmutableIntArray EMPTY = new ImmutableIntArray(); + static IntArray empty() { - return new ImmutableIntArray(); + return EMPTY; } static IntArray of(int e1) { diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/LongArray.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/LongArray.java index e497f22c..d3c57f50 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/LongArray.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/LongArray.java @@ -10,8 +10,10 @@ */ public interface LongArray extends Iterable, Serializable, Cloneable, RandomAccess { + ImmutableLongArray EMPTY = new ImmutableLongArray(); + static LongArray empty() { - return new ImmutableLongArray(); + return EMPTY; } static LongArray of(long e1) { diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultArrayIterationFunctions.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultArrayIterationFunctions.java index d8a2e793..ffb2d822 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultArrayIterationFunctions.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/impl/DefaultArrayIterationFunctions.java @@ -4,6 +4,7 @@ import java.util.function.BiPredicate; import javasabr.rlib.collections.array.ArrayIterationFunctions; import javasabr.rlib.collections.array.UnsafeArray; +import javasabr.rlib.functions.ObjIntPredicate; import javasabr.rlib.functions.ObjObjLongConsumer; import javasabr.rlib.functions.TriConsumer; import org.jspecify.annotations.Nullable; @@ -12,7 +13,21 @@ public record DefaultArrayIterationFunctions(UnsafeArray array) implements @Override public @Nullable E findAny(T arg1, BiPredicate filter) { + @Nullable E[] wrapped = array.wrapped(); + int size = array.size(); + + for (int i = 0; i < size; i++) { + E element = wrapped[i]; + if (filter.test(element, arg1)) { + return element; + } + } + return null; + } + @Nullable + @Override + public E findAny(int arg1, ObjIntPredicate filter) { @Nullable E[] wrapped = array.wrapped(); int size = array.size(); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/operation/LockableOperations.java b/rlib-collections/src/main/java/javasabr/rlib/collections/operation/LockableOperations.java index 371d4984..ea1b74f1 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/operation/LockableOperations.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/operation/LockableOperations.java @@ -2,6 +2,7 @@ import java.util.function.BiConsumer; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Function; import javasabr.rlib.functions.BiObjToBooleanFunction; import javasabr.rlib.functions.ObjIntFunction; @@ -26,7 +27,10 @@ public interface LockableOperations { R getInWriteLock(A arg1, B arg2, TriFunction function); - void inWriteLock(A arg1, B arg2, TriConsumer function); + void inWriteLock(Consumer function); void inWriteLock(A arg1, BiConsumer function); + + void inWriteLock(A arg1, B arg2, TriConsumer function); + } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/operation/impl/DefaultLockableOperations.java b/rlib-collections/src/main/java/javasabr/rlib/collections/operation/impl/DefaultLockableOperations.java index c34df0dd..02098d71 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/operation/impl/DefaultLockableOperations.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/operation/impl/DefaultLockableOperations.java @@ -2,6 +2,7 @@ import java.util.function.BiConsumer; import java.util.function.BiFunction; +import java.util.function.Consumer; import java.util.function.Function; import javasabr.rlib.collections.operation.LockableOperations; import javasabr.rlib.collections.operation.LockableSource; @@ -93,6 +94,16 @@ public R getInWriteLock(A arg1, B arg2, TriFunction functi } } + @Override + public void inWriteLock(Consumer function) { + long stamp = source.writeLock(); + try { + function.accept(source); + } finally { + source.writeUnlock(stamp); + } + } + @Override public void inWriteLock(A arg1, BiConsumer function) { long stamp = source.writeLock(); diff --git a/rlib-common/src/main/java/javasabr/rlib/common/function/ObjectIntPredicate.java b/rlib-common/src/main/java/javasabr/rlib/common/function/ObjectIntPredicate.java deleted file mode 100644 index a7dfdc1e..00000000 --- a/rlib-common/src/main/java/javasabr/rlib/common/function/ObjectIntPredicate.java +++ /dev/null @@ -1,10 +0,0 @@ -package javasabr.rlib.common.function; - -/** - * @author JavaSaBr - */ -@FunctionalInterface -public interface ObjectIntPredicate { - - boolean test(T first, int second); -} diff --git a/rlib-common/src/main/java/javasabr/rlib/common/util/ArrayUtils.java b/rlib-common/src/main/java/javasabr/rlib/common/util/ArrayUtils.java index 6ccef6d4..2a870f44 100644 --- a/rlib-common/src/main/java/javasabr/rlib/common/util/ArrayUtils.java +++ b/rlib-common/src/main/java/javasabr/rlib/common/util/ArrayUtils.java @@ -13,7 +13,6 @@ import java.util.function.Supplier; import javasabr.rlib.common.function.CharSupplier; import javasabr.rlib.common.function.DoubleObjectConsumer; -import javasabr.rlib.common.function.ObjectIntPredicate; import javasabr.rlib.common.function.ObjectLongPredicate; import javasabr.rlib.common.function.TripleConsumer; import javasabr.rlib.common.function.TripleFunction; @@ -1267,103 +1266,6 @@ public static boolean anyMatchR( return null; } - /** - * Find an element in the array using the condition. - * - * @param the type parameter - * @param array the array. - * @param argument the argument. - * @param condition the condition. - * @return the element or null. - */ - - public static @Nullable T findAny(T @Nullable [] array, int argument, ObjectIntPredicate condition) { - - if (array == null || array.length < 1) { - return null; - } - - for (T element : array) { - if (condition.test(element, argument)) { - return element; - } - } - - return null; - } - - /** - * Find a sub-element in the array using the function to get a sub-element + the condition. - * - * @param the type parameter - * @param the type parameter - * @param array the array. - * @param argument the argument. - * @param getElement the function to get a sub-element. - * @param condition the condition. - * @return the element or null. - */ - - public static @Nullable R findAny( - T @Nullable [] array, - int argument, - Function getElement, - ObjectIntPredicate condition) { - - if (array == null || array.length < 1) { - return null; - } - - for (T element : array) { - R subElement = getElement.apply(element); - if (condition.test(subElement, argument)) { - return subElement; - } - } - - return null; - } - - /** - * Find a sub-element in the array using the function to get a sub-element + conditions. - * - * @param the type parameter - * @param the type parameter - * @param array the array. - * @param argument the argument. - * @param firstCond the first condition. - * @param getElement the function to get a sub-element. - * @param secondCond the second condition. - * @return the element or null. - */ - - public static @Nullable R findAny( - T @Nullable [] array, - int argument, - Predicate firstCond, - Function getElement, - ObjectIntPredicate secondCond) { - - if (array == null || array.length < 1) { - return null; - } - - for (T element : array) { - - if (!firstCond.test(element)) { - continue; - } - - R subElement = getElement.apply(element); - - if (secondCond.test(subElement, argument)) { - return subElement; - } - } - - return null; - } - /** * Find a sub-element in the array using the function to get a sub-element + conditions. * diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/ByteFunction.java b/rlib-functions/src/main/java/javasabr/rlib/functions/ByteFunction.java new file mode 100644 index 00000000..768de8c8 --- /dev/null +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/ByteFunction.java @@ -0,0 +1,9 @@ +package javasabr.rlib.functions; + +/** + * @author JavaSaBr + */ +@FunctionalInterface +public interface ByteFunction { + R apply(byte value); +} diff --git a/rlib-functions/src/main/java/javasabr/rlib/functions/ObjIntPredicate.java b/rlib-functions/src/main/java/javasabr/rlib/functions/ObjIntPredicate.java new file mode 100644 index 00000000..2b6ba817 --- /dev/null +++ b/rlib-functions/src/main/java/javasabr/rlib/functions/ObjIntPredicate.java @@ -0,0 +1,10 @@ +package javasabr.rlib.functions; + +/** + * @author JavaSaBr + */ +@FunctionalInterface +public interface ObjIntPredicate { + + boolean test(A arg1, int arg2); +} diff --git a/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractPacketReader.java b/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractPacketReader.java index 347d095e..502545b8 100644 --- a/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractPacketReader.java +++ b/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractPacketReader.java @@ -9,7 +9,6 @@ import java.nio.channels.CompletionHandler; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; -import javasabr.rlib.common.function.NotNullConsumer; import javasabr.rlib.common.util.BufferUtils; import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerManager; @@ -69,7 +68,7 @@ protected AbstractPacketReader( AsynchronousSocketChannel channel, BufferAllocator bufferAllocator, Runnable updateActivityFunction, - NotNullConsumer readPacketHandler, + Consumer readPacketHandler, int maxPacketsByRead) { this.connection = connection; this.channel = channel; diff --git a/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractPacketWriter.java b/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractPacketWriter.java index 20b59dd5..650b927c 100644 --- a/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractPacketWriter.java +++ b/rlib-network/src/main/java/javasabr/rlib/network/packet/impl/AbstractPacketWriter.java @@ -8,9 +8,9 @@ import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; import java.util.concurrent.atomic.AtomicBoolean; -import javasabr.rlib.common.function.NotNullBiConsumer; -import javasabr.rlib.common.function.NotNullConsumer; -import javasabr.rlib.common.function.NullableSupplier; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; import javasabr.rlib.logger.api.Logger; import javasabr.rlib.logger.api.LoggerManager; import javasabr.rlib.network.BufferAllocator; @@ -57,18 +57,18 @@ public void failed(Throwable exc, WritablePacket packet) { protected volatile ByteBuffer writingBuffer = EMPTY_BUFFER; protected final Runnable updateActivityFunction; - protected final NullableSupplier nextWritePacketSupplier; - protected final NotNullConsumer writtenPacketHandler; - protected final NotNullBiConsumer sentPacketHandler; + protected final Supplier<@Nullable WritablePacket> nextWritePacketSupplier; + protected final Consumer writtenPacketHandler; + protected final BiConsumer sentPacketHandler; public AbstractPacketWriter( C connection, AsynchronousSocketChannel channel, BufferAllocator bufferAllocator, Runnable updateActivityFunction, - NullableSupplier packetProvider, - NotNullConsumer writtenPacketHandler, - NotNullBiConsumer sentPacketHandler) { + Supplier<@Nullable WritablePacket> packetProvider, + Consumer writtenPacketHandler, + BiConsumer sentPacketHandler) { this.connection = connection; this.channel = channel; this.bufferAllocator = bufferAllocator; From 8c1e23db5aef5b16b2ced0b50e71561fd42e5f88 Mon Sep 17 00:00:00 2001 From: javasabr Date: Sat, 27 Sep 2025 17:49:01 +0200 Subject: [PATCH 3/5] add code-style --- JavaSabr-codestyle.xml | 216 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 JavaSabr-codestyle.xml diff --git a/JavaSabr-codestyle.xml b/JavaSabr-codestyle.xml new file mode 100644 index 00000000..c253b3d4 --- /dev/null +++ b/JavaSabr-codestyle.xml @@ -0,0 +1,216 @@ + + \ No newline at end of file From ad17e558535afa399e5335ad143000169087e81a Mon Sep 17 00:00:00 2001 From: javasabr Date: Sat, 27 Sep 2025 18:50:41 +0200 Subject: [PATCH 4/5] add tests --- .../array/ArrayIterationFunctions.java | 10 +- .../ReversedArrayIterationFunctions.java | 8 +- .../array/ArrayIterationsTest.java | 122 +++++++++ .../rlib/collections/array/ArrayTest.java | 18 ++ .../array/ReversedArrayIterationsTest.java | 90 +++++++ .../{array => deque}/DequeTest.java | 4 +- .../MutableRefToRefDictionaryTest.java | 5 +- .../RefToRefDictionaryTest.java | 6 +- .../DefaultLockableOperationsTest.java | 254 ++++++++++++++++++ 9 files changed, 499 insertions(+), 18 deletions(-) create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayIterationsTest.java create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/array/ReversedArrayIterationsTest.java rename rlib-collections/src/test/java/javasabr/rlib/collections/{array => deque}/DequeTest.java (99%) rename rlib-collections/src/test/java/javasabr/rlib/collections/{array => dictionary}/MutableRefToRefDictionaryTest.java (94%) rename rlib-collections/src/test/java/javasabr/rlib/collections/{array => dictionary}/RefToRefDictionaryTest.java (96%) create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/operation/DefaultLockableOperationsTest.java diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java index d4c08bbb..4ab33d9f 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/ArrayIterationFunctions.java @@ -10,16 +10,16 @@ public interface ArrayIterationFunctions { @Nullable - E findAny(T arg1, BiPredicate filter); + E findAny(A arg1, BiPredicate filter); @Nullable E findAny(int arg1, ObjIntPredicate filter); - ArrayIterationFunctions forEach(T arg1, BiConsumer consumer); + ArrayIterationFunctions forEach(A arg1, BiConsumer consumer); - ArrayIterationFunctions forEach(F arg1, S arg2, TriConsumer consumer); + ArrayIterationFunctions forEach(A arg1, B arg2, TriConsumer consumer); - ArrayIterationFunctions forEach(F arg1, long arg2, ObjObjLongConsumer consumer); + ArrayIterationFunctions forEach(A arg1, long arg2, ObjObjLongConsumer consumer); - boolean anyMatch(T arg1, BiPredicate filter); + boolean anyMatch(A arg1, BiPredicate filter); } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/ReversedArrayIterationFunctions.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/ReversedArrayIterationFunctions.java index 676a5780..f056cbe0 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/ReversedArrayIterationFunctions.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/ReversedArrayIterationFunctions.java @@ -8,11 +8,11 @@ public interface ReversedArrayIterationFunctions { @Nullable - E findAny(T arg1, BiPredicate filter); + E findAny(A arg1, BiPredicate filter); - ReversedArrayIterationFunctions forEach(T arg1, BiConsumer consumer); + ReversedArrayIterationFunctions forEach(A arg1, BiConsumer consumer); - ReversedArrayIterationFunctions forEach(F arg1, S arg2, TriConsumer consumer); + ReversedArrayIterationFunctions forEach(A arg1, B arg2, TriConsumer consumer); - boolean anyMatch(T arg1, BiPredicate filter); + boolean anyMatch(A arg1, BiPredicate filter); } diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayIterationsTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayIterationsTest.java new file mode 100644 index 00000000..abb70af5 --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayIterationsTest.java @@ -0,0 +1,122 @@ +package javasabr.rlib.collections.array; + +import java.util.Objects; +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class ArrayIterationsTest { + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldFindAnyCorrectly(Array array) { + // when/then: + Assertions.assertNull(array + .iterations() + .findAny("notexist", Objects::equals)); + Assertions.assertNotNull(array + .iterations() + .findAny("Second", Objects::equals)); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldFindAny2Correctly(Array array) { + // when/then: + Assertions.assertNull(array + .iterations() + .findAny(10, (element, intArg) -> String.valueOf(intArg).equals(element))); + Assertions.assertNotNull(array + .iterations() + .findAny(5, (element, intArg) -> String.valueOf(intArg).equals(element))); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldDoForEachCorrectly(Array array) { + // given: + var result = MutableArray.ofType(String.class); + var expected = Array.typed(String.class, + "First_postfix", + "Second_postfix", + "Third_postfix", + " _postfix", + "5_postfix"); + + // when: + array.iterations() + .forEach("_postfix", (element, arg1) -> result.add(element + arg1)); + + // then: + Assertions.assertEquals(expected, result); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldDoForEach2Correctly(Array array) { + // given: + var result = MutableArray.ofType(String.class); + var expected = Array.typed(String.class, + "prefix_First_postfix", + "prefix_Second_postfix", + "prefix_Third_postfix", + "prefix_ _postfix", + "prefix_5_postfix"); + + // when: + array.iterations() + .forEach("prefix_", "_postfix", (element, arg1, arg2) -> result.add(arg1 + element + arg2)); + + // then: + Assertions.assertEquals(expected, result); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldDoForEach3Correctly(Array array) { + // given: + var result = MutableArray.ofType(String.class); + var expected = Array.typed(String.class, + "prefix_First55", + "prefix_Second55", + "prefix_Third55", + "prefix_ 55", + "prefix_555"); + + // when: + array.iterations() + .forEach("prefix_", 55L, (element, arg1, arg2) -> result.add(arg1 + element + arg2)); + + // then: + Assertions.assertEquals(expected, result); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldAnyMatchCorrectly(Array array) { + // when/then: + Assertions.assertFalse(array + .iterations() + .anyMatch(10, (element, intArg) -> String.valueOf(intArg).equals(element))); + Assertions.assertTrue(array + .iterations() + .anyMatch(5, (element, intArg) -> String.valueOf(intArg).equals(element))); + } + + private static Stream generateArrays() { + Array array = Array.typed(String.class, "First", "Second", "Third", " ", "5"); + MutableArray mutableArray = ArrayFactory.mutableArray(String.class); + mutableArray.addAll(array); + MutableArray copyOnModifyArray = ArrayFactory.copyOnModifyArray(String.class); + copyOnModifyArray.addAll(array); + LockableArray stampedLockBasedArray = ArrayFactory.stampedLockBasedArray(String.class); + stampedLockBasedArray.addAll(array); + return Stream.of( + Arguments.of(array), + Arguments.of(mutableArray), + Arguments.of(copyOnModifyArray), + Arguments.of(stampedLockBasedArray)); + } +} diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java index 90fdbc2f..a52ee00e 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java @@ -68,6 +68,24 @@ void shouldCorrectlyTakeValues(Array array) { Assertions.assertFalse(array.contains("test")); } + @ParameterizedTest + @MethodSource("generateArrays") + void shouldFindElementIndex(Array array) { + // when/then: + Assertions.assertEquals(0, array.indexOf("First")); + Assertions.assertEquals(3, array.indexOf(" ")); + Assertions.assertEquals(-1, array.indexOf("notexist")); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldFindElementIndexWithFunction(Array array) { + // when/then: + Assertions.assertEquals(0, array.indexOf(s -> s + s, "FirstFirst")); + Assertions.assertEquals(3, array.indexOf(s -> s + s, " ")); + Assertions.assertEquals(-1, array.indexOf("notexist")); + } + @ParameterizedTest @MethodSource("generateArrays") void shouldCorrectlyTransformToNativeArray(Array array) { diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ReversedArrayIterationsTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ReversedArrayIterationsTest.java new file mode 100644 index 00000000..c6555f44 --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ReversedArrayIterationsTest.java @@ -0,0 +1,90 @@ +package javasabr.rlib.collections.array; + +import java.util.Objects; +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class ReversedArrayIterationsTest { + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldFindAnyCorrectly(Array array) { + // when/then: + Assertions.assertNull(array + .reversedIterations() + .findAny("notexist", Objects::equals)); + Assertions.assertNotNull(array + .iterations() + .findAny("Second", Objects::equals)); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldDoForEachCorrectly(Array array) { + // given: + var result = MutableArray.ofType(String.class); + var expected = Array.typed(String.class, + "prefix_First", + "prefix_Second", + "prefix_Third", + "prefix_ ", + "prefix_5"); + + // when: + array.reversedIterations() + .forEach("prefix_", (arg1, element) -> result.add(arg1 + element)); + + // then: + Assertions.assertEquals(expected, result); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldDoForEach2Correctly(Array array) { + // given: + var result = MutableArray.ofType(String.class); + var expected = Array.typed(String.class, + "prefix__middle_First", + "prefix__middle_Second", + "prefix__middle_Third", + "prefix__middle_ ", + "prefix__middle_5"); + + // when: + array.reversedIterations() + .forEach("prefix_", "_middle_", (arg1, arg2, element) -> result.add(arg1 + arg2 + element)); + + // then: + Assertions.assertEquals(expected, result); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldAnyMatchCorrectly(Array array) { + // when/then: + Assertions.assertFalse(array + .reversedIterations() + .anyMatch("10", String::equals)); + Assertions.assertTrue(array + .reversedIterations() + .anyMatch("5", String::equals)); + } + + private static Stream generateArrays() { + Array array = Array.typed(String.class, "First", "Second", "Third", " ", "5"); + MutableArray mutableArray = ArrayFactory.mutableArray(String.class); + mutableArray.addAll(array); + MutableArray copyOnModifyArray = ArrayFactory.copyOnModifyArray(String.class); + copyOnModifyArray.addAll(array); + LockableArray stampedLockBasedArray = ArrayFactory.stampedLockBasedArray(String.class); + stampedLockBasedArray.addAll(array); + return Stream.of( + Arguments.of(array), + Arguments.of(mutableArray), + Arguments.of(copyOnModifyArray), + Arguments.of(stampedLockBasedArray)); + } +} diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/DequeTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/deque/DequeTest.java similarity index 99% rename from rlib-collections/src/test/java/javasabr/rlib/collections/array/DequeTest.java rename to rlib-collections/src/test/java/javasabr/rlib/collections/deque/DequeTest.java index 756d4dba..5752a16b 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/DequeTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/deque/DequeTest.java @@ -1,4 +1,4 @@ -package javasabr.rlib.collections.array; +package javasabr.rlib.collections.deque; import static javasabr.rlib.common.util.ArrayUtils.array; import static org.junit.jupiter.api.Assertions.assertArrayEquals; @@ -12,7 +12,7 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.stream.Stream; -import javasabr.rlib.collections.deque.DequeFactory; +import javasabr.rlib.collections.array.MutableArray; import javasabr.rlib.common.util.ReflectionUtils; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableRefToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java similarity index 94% rename from rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableRefToRefDictionaryTest.java rename to rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java index 26f237c3..bdcdbf06 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/MutableRefToRefDictionaryTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java @@ -1,11 +1,8 @@ -package javasabr.rlib.collections.array; +package javasabr.rlib.collections.dictionary; import static javasabr.rlib.collections.dictionary.RefToRefDictionary.entry; import java.util.stream.Stream; -import javasabr.rlib.collections.dictionary.DictionaryFactory; -import javasabr.rlib.collections.dictionary.MutableRefToRefDictionary; -import javasabr.rlib.collections.dictionary.RefToRefDictionary; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/RefToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/RefToRefDictionaryTest.java similarity index 96% rename from rlib-collections/src/test/java/javasabr/rlib/collections/array/RefToRefDictionaryTest.java rename to rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/RefToRefDictionaryTest.java index 1466a4cf..08d99e35 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/RefToRefDictionaryTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/RefToRefDictionaryTest.java @@ -1,12 +1,12 @@ -package javasabr.rlib.collections.array; +package javasabr.rlib.collections.dictionary; import static javasabr.rlib.collections.dictionary.RefToRefDictionary.entry; import java.util.HashSet; import java.util.Set; import java.util.stream.Stream; -import javasabr.rlib.collections.dictionary.DictionaryFactory; -import javasabr.rlib.collections.dictionary.RefToRefDictionary; +import javasabr.rlib.collections.array.Array; +import javasabr.rlib.collections.array.MutableArray; import javasabr.rlib.common.tuple.Tuple; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/operation/DefaultLockableOperationsTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/operation/DefaultLockableOperationsTest.java new file mode 100644 index 00000000..7839d044 --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/operation/DefaultLockableOperationsTest.java @@ -0,0 +1,254 @@ +package javasabr.rlib.collections.operation; + +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Stream; +import javasabr.rlib.collections.operation.impl.DefaultLockableOperations; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class DefaultLockableOperationsTest { + + private static class TestLockableSource implements LockableSource { + + int readLocks; + int writeLocks; + + @Override + public long readLock() { + readLocks++; + return 0; + } + + @Override + public void readUnlock(long stamp) { + readLocks--; + } + + @Override + public long tryOptimisticRead() { + readLocks++; + return 0; + } + + @Override + public boolean validateLock(long stamp) { + return false; + } + + @Override + public long writeLock() { + writeLocks++; + return 0; + } + + @Override + public void writeUnlock(long stamp) { + writeLocks--; + } + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldGetInReadLock(DefaultLockableOperations operations) { + + // when: + var result = operations.getInReadLock(source -> { + Assertions.assertEquals(0, source.writeLocks); + Assertions.assertEquals(1, source.readLocks); + return "test"; + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().readLocks); + Assertions.assertEquals("test", result); + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldGetInReadLock2(DefaultLockableOperations operations) { + + // when: + var result = operations.getInReadLock("_arg", (source, arg1) -> { + Assertions.assertEquals(0, source.writeLocks); + Assertions.assertEquals(1, source.readLocks); + return "test" + arg1; + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().readLocks); + Assertions.assertEquals("test_arg", result); + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldGetInReadLock3(DefaultLockableOperations operations) { + + // when: + var result = operations.getInReadLock(15, (source, arg1) -> { + Assertions.assertEquals(0, source.writeLocks); + Assertions.assertEquals(1, source.readLocks); + return "test" + arg1; + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().readLocks); + Assertions.assertEquals("test15", result); + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldGetInReadLock4(DefaultLockableOperations operations) { + + // when: + var result = operations.getInReadLock("arg1_", "_arg2", (source, arg1, arg2) -> { + Assertions.assertEquals(0, source.writeLocks); + Assertions.assertEquals(1, source.readLocks); + return arg1 + "test" + arg2; + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().readLocks); + Assertions.assertEquals("arg1_test_arg2", result); + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldGetInReadLock5(DefaultLockableOperations operations) { + + // when: + var result = operations.getInReadLock(true, (source, arg1) -> { + Assertions.assertEquals(0, source.writeLocks); + Assertions.assertEquals(1, source.readLocks); + return "test" + arg1; + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().readLocks); + Assertions.assertEquals("testtrue", result); + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldInReadLock(DefaultLockableOperations operations) { + + // given: + var capture = new AtomicReference(); + + // when: + operations.inReadLock("test_arg", (source, arg1) -> { + Assertions.assertEquals(0, source.writeLocks); + Assertions.assertEquals(1, source.readLocks); + capture.set("test_" + arg1); + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().readLocks); + Assertions.assertEquals("test_test_arg", capture.get()); + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldGetWriteLock(DefaultLockableOperations operations) { + + // when: + var result = operations.getInWriteLock("_arg", (source, arg1) -> { + Assertions.assertEquals(1, source.writeLocks); + Assertions.assertEquals(0, source.readLocks); + return "test" + arg1; + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals("test_arg", result); + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldGetWriteLock2(DefaultLockableOperations operations) { + + // when: + var result = operations.getInWriteLock("arg1_", "_arg2", (source, arg1, arg2) -> { + Assertions.assertEquals(1, source.writeLocks); + Assertions.assertEquals(0, source.readLocks); + return arg1 + "test" + arg2; + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals("arg1_test_arg2", result); + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldInWriteLock(DefaultLockableOperations operations) { + + // given: + var capture = new AtomicReference(); + + // when: + operations.inWriteLock(source -> { + Assertions.assertEquals(1, source.writeLocks); + Assertions.assertEquals(0, source.readLocks); + capture.set("test"); + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().readLocks); + Assertions.assertEquals("test", capture.get()); + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldInWriteLock2(DefaultLockableOperations operations) { + + // given: + var capture = new AtomicReference(); + + // when: + operations.inWriteLock("test_arg", (source, arg1) -> { + Assertions.assertEquals(1, source.writeLocks); + Assertions.assertEquals(0, source.readLocks); + capture.set("test_" + arg1); + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().readLocks); + Assertions.assertEquals("test_test_arg", capture.get()); + } + + @ParameterizedTest + @MethodSource("generateOperations") + void shouldInWriteLock3(DefaultLockableOperations operations) { + + // given: + var capture = new AtomicReference(); + + // when: + operations.inWriteLock("arg1_", "_arg2", (source, arg1, arg2) -> { + Assertions.assertEquals(1, source.writeLocks); + Assertions.assertEquals(0, source.readLocks); + capture.set(arg1 + "test" + arg2); + }); + + // then: + Assertions.assertEquals(0, operations.source().writeLocks); + Assertions.assertEquals(0, operations.source().readLocks); + Assertions.assertEquals("arg1_test_arg2", capture.get()); + } + + private static Stream generateOperations() { + return Stream.of(Arguments.of(new DefaultLockableOperations<>(new TestLockableSource()))); + } +} From 8a674cefe47fa2eca0d000ddb5b3c4b79b83a857 Mon Sep 17 00:00:00 2001 From: javasabr Date: Sat, 27 Sep 2025 18:50:56 +0200 Subject: [PATCH 5/5] update version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 112634ac..64da9f2c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -rootProject.version = "10.0.alpha" +rootProject.version = "10.0.alpha1" group = 'javasabr.rlib' subprojects {