Objects: getting begin/end iterators

This commit is contained in:
2025-04-03 15:05:09 +02:00
parent ea4f041d6e
commit df00584367
19 changed files with 299 additions and 121 deletions

View File

@@ -1,53 +1,47 @@
package com.usatiuk.objects;
import com.usatiuk.dhfs.supportlib.UninitializedByteBuffer;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
public record JObjectKey(String name) implements Serializable, Comparable<JObjectKey> {
public static JObjectKey of(String name) {
return new JObjectKey(name);
public sealed interface JObjectKey extends Serializable, Comparable<JObjectKey> permits JObjectKeyImpl, JObjectKeyMax, JObjectKeyMin {
JObjectKeyMin MIN = new JObjectKeyMin();
JObjectKeyMax MAX = new JObjectKeyMax();
static JObjectKey of(String name) {
return new JObjectKeyImpl(name);
}
public static JObjectKey random() {
return new JObjectKey(UUID.randomUUID().toString());
static JObjectKey random() {
return new JObjectKeyImpl(UUID.randomUUID().toString());
}
public static JObjectKey first() {
return new JObjectKey("");
static JObjectKey first() {
return MIN;
}
public static JObjectKey fromBytes(byte[] bytes) {
return new JObjectKey(new String(bytes, StandardCharsets.UTF_8));
static JObjectKey last() {
return MAX;
}
public static JObjectKey fromByteBuffer(ByteBuffer buff) {
return new JObjectKey(StandardCharsets.UTF_8.decode(buff).toString());
static JObjectKey fromBytes(byte[] bytes) {
return new JObjectKeyImpl(new String(bytes, StandardCharsets.UTF_8));
}
static JObjectKey fromByteBuffer(ByteBuffer buff) {
return new JObjectKeyImpl(StandardCharsets.UTF_8.decode(buff).toString());
}
@Override
public int compareTo(JObjectKey o) {
return name.compareTo(o.name);
}
int compareTo(JObjectKey o);
@Override
public String toString() {
return name;
}
String toString();
public byte[] bytes() {
return name.getBytes(StandardCharsets.UTF_8);
}
byte[] bytes();
public ByteBuffer toByteBuffer() {
var heapBb = StandardCharsets.UTF_8.encode(name);
if (heapBb.isDirect()) return heapBb;
var directBb = UninitializedByteBuffer.allocateUninitialized(heapBb.remaining());
directBb.put(heapBb);
directBb.flip();
return directBb;
}
ByteBuffer toByteBuffer();
String name();
}

View File

@@ -0,0 +1,43 @@
package com.usatiuk.objects;
import com.usatiuk.dhfs.supportlib.UninitializedByteBuffer;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
public record JObjectKeyImpl(String name) implements JObjectKey {
@Override
public int compareTo(JObjectKey o) {
switch (o) {
case JObjectKeyImpl jObjectKeyImpl -> {
return name.compareTo(jObjectKeyImpl.name());
}
case JObjectKeyMax jObjectKeyMax -> {
return -1;
}
case JObjectKeyMin jObjectKeyMin -> {
return 1;
}
}
}
@Override
public String toString() {
return name;
}
@Override
public byte[] bytes() {
return name.getBytes(StandardCharsets.UTF_8);
}
@Override
public ByteBuffer toByteBuffer() {
var heapBb = StandardCharsets.UTF_8.encode(name);
if (heapBb.isDirect()) return heapBb;
var directBb = UninitializedByteBuffer.allocateUninitialized(heapBb.remaining());
directBb.put(heapBb);
directBb.flip();
return directBb;
}
}

View File

@@ -0,0 +1,35 @@
package com.usatiuk.objects;
import java.nio.ByteBuffer;
public record JObjectKeyMax() implements JObjectKey {
@Override
public int compareTo(JObjectKey o) {
switch (o) {
case JObjectKeyImpl jObjectKeyImpl -> {
return 1;
}
case JObjectKeyMax jObjectKeyMax -> {
return 0;
}
case JObjectKeyMin jObjectKeyMin -> {
return 1;
}
}
}
@Override
public byte[] bytes() {
throw new UnsupportedOperationException();
}
@Override
public ByteBuffer toByteBuffer() {
throw new UnsupportedOperationException();
}
@Override
public String name() {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,35 @@
package com.usatiuk.objects;
import java.nio.ByteBuffer;
public record JObjectKeyMin() implements JObjectKey {
@Override
public int compareTo(JObjectKey o) {
switch (o) {
case JObjectKeyImpl jObjectKeyImpl -> {
return -1;
}
case JObjectKeyMax jObjectKeyMax -> {
return -1;
}
case JObjectKeyMin jObjectKeyMin -> {
return 0;
}
}
}
@Override
public byte[] bytes() {
throw new UnsupportedOperationException();
}
@Override
public ByteBuffer toByteBuffer() {
throw new UnsupportedOperationException();
}
@Override
public String name() {
throw new UnsupportedOperationException();
}
}

View File

@@ -5,7 +5,6 @@ import com.usatiuk.objects.JObjectKey;
import com.usatiuk.objects.iterators.*;
import com.usatiuk.objects.snapshot.Snapshot;
import io.quarkus.logging.Log;
import io.quarkus.runtime.Startup;
import io.quarkus.runtime.StartupEvent;
import jakarta.annotation.Priority;
import jakarta.enterprise.context.ApplicationScoped;

View File

@@ -2,6 +2,9 @@ package com.usatiuk.objects.stores;
import com.google.protobuf.ByteString;
import com.usatiuk.objects.JObjectKey;
import com.usatiuk.objects.JObjectKeyImpl;
import com.usatiuk.objects.JObjectKeyMax;
import com.usatiuk.objects.JObjectKeyMin;
import com.usatiuk.objects.iterators.CloseableKvIterator;
import com.usatiuk.objects.iterators.IteratorStart;
import com.usatiuk.objects.iterators.KeyPredicateKvIterator;
@@ -30,9 +33,6 @@ import java.nio.file.Path;
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import static org.lmdbjava.DbiFlags.MDB_CREATE;
import static org.lmdbjava.Env.create;
@@ -229,6 +229,16 @@ public class LmdbObjectPersistentStore implements ObjectPersistentStore {
});
verifyReady();
if (key instanceof JObjectKeyMin) {
_hasNext = _cursor.first();
return;
} else if (key instanceof JObjectKeyMax) {
_hasNext = _cursor.last();
return;
}
if (key.toByteBuffer().remaining() == 0) {
if (!_cursor.first())
return;

View File

@@ -2,6 +2,7 @@ package com.usatiuk.objects.stores;
import com.google.protobuf.ByteString;
import com.usatiuk.objects.JObjectKey;
import com.usatiuk.objects.JObjectKeyImpl;
import com.usatiuk.objects.iterators.CloseableKvIterator;
import com.usatiuk.objects.iterators.IteratorStart;
import com.usatiuk.objects.iterators.NavigableMapKvIterator;
@@ -13,7 +14,6 @@ import org.pcollections.TreePMap;
import javax.annotation.Nonnull;
import java.util.Optional;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
@ApplicationScoped
@IfBuildProperty(name = "dhfs.objects.persistence", stringValue = "memory")

View File

@@ -3,6 +3,7 @@ package com.usatiuk.objects.stores;
import com.google.protobuf.ByteString;
import com.usatiuk.objects.JDataVersionedWrapper;
import com.usatiuk.objects.JObjectKey;
import com.usatiuk.objects.JObjectKeyImpl;
import com.usatiuk.objects.ObjectSerializer;
import com.usatiuk.objects.iterators.CloseableKvIterator;
import com.usatiuk.objects.iterators.IteratorStart;
@@ -14,7 +15,6 @@ import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nonnull;
import java.util.Optional;
import java.util.function.Consumer;
@ApplicationScoped
public class SerializingObjectPersistentStore {

View File

@@ -3,6 +3,7 @@ package com.usatiuk.objects.stores;
import com.usatiuk.objects.JDataVersionedWrapper;
import com.usatiuk.objects.JDataVersionedWrapperImpl;
import com.usatiuk.objects.JObjectKey;
import com.usatiuk.objects.JObjectKeyImpl;
import com.usatiuk.objects.iterators.*;
import com.usatiuk.objects.snapshot.Snapshot;
import com.usatiuk.objects.transaction.TxCommitException;
@@ -26,7 +27,6 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
@ApplicationScoped

View File

@@ -0,0 +1,56 @@
package com.usatiuk.objects;
import com.usatiuk.objects.data.Parent;
import com.usatiuk.objects.transaction.Transaction;
import com.usatiuk.objects.transaction.TransactionManager;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.TestProfile;
import jakarta.inject.Inject;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
class ObjectsIterateAllTestProfiles {
public static class ObjectsIterateAllTestProfile extends TempDataProfile {
}
}
@QuarkusTest
@TestProfile(ObjectsIterateAllTestProfiles.ObjectsIterateAllTestProfile.class)
public class ObjectsIterateAllTest {
@Inject
TransactionManager txm;
@Inject
Transaction curTx;
@Test
void testBegin() {
var newParent = new Parent(JObjectKey.of("IterateAllBegin1"), "John1");
var newParent2 = new Parent(JObjectKey.of("IterateAllBegin2"), "John2");
var newParent3 = new Parent(JObjectKey.of("IterateAllBegin3"), "John3");
txm.run(() -> {
curTx.put(newParent);
curTx.put(newParent2);
curTx.put(newParent3);
});
txm.run(() -> {
try (var it = curTx.getIterator(JObjectKey.first())) {
Just.checkIterator(it, Stream.<JData>of(newParent, newParent2, newParent3).map(p -> Pair.of(p.key(), p)).toList());
}
});
txm.run(() -> {
try (var it = curTx.getIterator(JObjectKey.last()).reversed()) {
Just.checkIterator(it, Stream.<JData>of(newParent3, newParent2, newParent).map(p -> Pair.of(p.key(), p)).toList());
}
});
}
}

View File

@@ -64,7 +64,7 @@ public abstract class ObjectsTestImpl {
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("ParentCreate")).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("ParentCreate")).orElse(null);
Assertions.assertEquals("John", parent.name());
});
}
@@ -84,11 +84,11 @@ public abstract class ObjectsTestImpl {
}));
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("ParentOnCommitHook")).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("ParentOnCommitHook")).orElse(null);
Assertions.assertEquals("John", parent.name());
var parent2 = curTx.get(Parent.class, new JObjectKey("ParentOnCommitHook2")).orElse(null);
var parent2 = curTx.get(Parent.class, new JObjectKeyImpl("ParentOnCommitHook2")).orElse(null);
Assertions.assertEquals("John2", parent2.name());
var parent3 = curTx.get(Parent.class, new JObjectKey("ParentOnCommitHook3")).orElse(null);
var parent3 = curTx.get(Parent.class, new JObjectKeyImpl("ParentOnCommitHook3")).orElse(null);
Assertions.assertEquals("John3", parent3.name());
});
}
@@ -103,7 +103,7 @@ public abstract class ObjectsTestImpl {
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("ParentCreateGet")).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("ParentCreateGet")).orElse(null);
Assertions.assertEquals("John", parent.name());
});
}
@@ -121,11 +121,11 @@ public abstract class ObjectsTestImpl {
});
txm.run(() -> {
curTx.delete(new JObjectKey("ParentCreateDeleteObject"));
curTx.delete(new JObjectKeyImpl("ParentCreateDeleteObject"));
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("ParentCreateDeleteObject")).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("ParentCreateDeleteObject")).orElse(null);
Assertions.assertNull(parent);
});
}
@@ -141,7 +141,7 @@ public abstract class ObjectsTestImpl {
curTx.put(newParent);
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("Parent7")).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("Parent7")).orElse(null);
Assertions.assertEquals("John2", parent.name());
});
}
@@ -154,17 +154,17 @@ public abstract class ObjectsTestImpl {
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("Parent3"), LockingStrategy.OPTIMISTIC).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("Parent3"), LockingStrategy.OPTIMISTIC).orElse(null);
Assertions.assertEquals("John", parent.name());
curTx.put(parent.withName("John2"));
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("Parent3"), LockingStrategy.WRITE).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("Parent3"), LockingStrategy.WRITE).orElse(null);
Assertions.assertEquals("John2", parent.name());
curTx.put(parent.withName("John3"));
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("Parent3")).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("Parent3")).orElse(null);
Assertions.assertEquals("John3", parent.name());
});
}
@@ -187,7 +187,7 @@ public abstract class ObjectsTestImpl {
} catch (Throwable e) {
throw new RuntimeException(e);
}
var got = curTx.get(Parent.class, new JObjectKey("Parent2")).orElse(null);
var got = curTx.get(Parent.class, new JObjectKeyImpl("Parent2")).orElse(null);
var newParent = new Parent(JObjectKey.of("Parent2"), "John");
curTx.put(newParent);
Log.warn("Thread 1 commit");
@@ -207,7 +207,7 @@ public abstract class ObjectsTestImpl {
} catch (Throwable e) {
throw new RuntimeException(e);
}
var got = curTx.get(Parent.class, new JObjectKey("Parent2")).orElse(null);
var got = curTx.get(Parent.class, new JObjectKeyImpl("Parent2")).orElse(null);
var newParent = new Parent(JObjectKey.of("Parent2"), "John2");
curTx.put(newParent);
Log.warn("Thread 2 commit");
@@ -226,7 +226,7 @@ public abstract class ObjectsTestImpl {
}
var got = txm.run(() -> {
return curTx.get(Parent.class, new JObjectKey("Parent2")).orElse(null);
return curTx.get(Parent.class, new JObjectKeyImpl("Parent2")).orElse(null);
});
if (!thread1Failed.get()) {
@@ -263,7 +263,7 @@ public abstract class ObjectsTestImpl {
} catch (Throwable e) {
throw new RuntimeException(e);
}
var parent = curTx.get(Parent.class, new JObjectKey(key), strategy).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl(key), strategy).orElse(null);
curTx.put(parent.withName("John"));
Log.warn("Thread 1 commit");
}, 0);
@@ -279,7 +279,7 @@ public abstract class ObjectsTestImpl {
Log.warn("Thread 2");
barrier.await(); // Ensure thread 2 tx id is larger than thread 1
txm.runTries(() -> {
var parent = curTx.get(Parent.class, new JObjectKey(key), strategy).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl(key), strategy).orElse(null);
curTx.put(parent.withName("John2"));
Log.warn("Thread 2 commit");
}, 0);
@@ -298,7 +298,7 @@ public abstract class ObjectsTestImpl {
}
var got = txm.run(() -> {
return curTx.get(Parent.class, new JObjectKey(key)).orElse(null);
return curTx.get(Parent.class, new JObjectKeyImpl(key)).orElse(null);
});
if (!thread1Failed.get() && !thread2Failed.get()) {
@@ -344,7 +344,7 @@ public abstract class ObjectsTestImpl {
} catch (Throwable e) {
throw new RuntimeException(e);
}
var parent = curTx.get(Parent.class, new JObjectKey(key), strategy).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl(key), strategy).orElse(null);
curTx.put(parent.withName("John"));
Log.warn("Thread 1 commit");
}, 0);
@@ -365,7 +365,7 @@ public abstract class ObjectsTestImpl {
} catch (Throwable e) {
throw new RuntimeException(e);
}
var parent = curTx.get(Parent.class, new JObjectKey(key), strategy).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl(key), strategy).orElse(null);
curTx.put(parent.withName("John2"));
Log.warn("Thread 2 commit");
}, 0);
@@ -384,7 +384,7 @@ public abstract class ObjectsTestImpl {
}
var got = txm.run(() -> {
return curTx.get(Parent.class, new JObjectKey(key)).orElse(null);
return curTx.get(Parent.class, new JObjectKeyImpl(key)).orElse(null);
});
Assertions.assertFalse(!thread1Failed.get() && !thread2Failed.get());
@@ -435,7 +435,7 @@ public abstract class ObjectsTestImpl {
throw new RuntimeException(e);
}
Log.info("Thread 1 reading");
Assertions.assertTrue(curTx.get(Parent.class, new JObjectKey(key)).isEmpty());
Assertions.assertTrue(curTx.get(Parent.class, new JObjectKeyImpl(key)).isEmpty());
Log.info("Thread 1 done reading");
});
Log.info("Thread 1 finished");
@@ -452,9 +452,9 @@ public abstract class ObjectsTestImpl {
throw new RuntimeException(e);
}
txm.run(() -> {
Assertions.assertEquals("John", curTx.get(Parent.class, new JObjectKey(key)).orElseThrow().name());
Assertions.assertEquals("John", curTx.get(Parent.class, new JObjectKeyImpl(key)).orElseThrow().name());
});
deleteAndCheck(new JObjectKey(key));
deleteAndCheck(new JObjectKeyImpl(key));
}
@RepeatedTest(100)
@@ -494,7 +494,7 @@ public abstract class ObjectsTestImpl {
throw new RuntimeException(e);
}
Log.info("Thread 1 reading");
Assertions.assertEquals("John", curTx.get(Parent.class, new JObjectKey(key)).orElseThrow().name());
Assertions.assertEquals("John", curTx.get(Parent.class, new JObjectKeyImpl(key)).orElseThrow().name());
Log.info("Thread 1 done reading");
});
Log.info("Thread 1 finished");
@@ -511,9 +511,9 @@ public abstract class ObjectsTestImpl {
throw new RuntimeException(e);
}
txm.run(() -> {
Assertions.assertEquals("John2", curTx.get(Parent.class, new JObjectKey(key)).orElseThrow().name());
Assertions.assertEquals("John2", curTx.get(Parent.class, new JObjectKeyImpl(key)).orElseThrow().name());
});
deleteAndCheck(new JObjectKey(key));
deleteAndCheck(new JObjectKeyImpl(key));
}
@RepeatedTest(100)
@@ -559,7 +559,7 @@ public abstract class ObjectsTestImpl {
throw new RuntimeException(e);
}
Log.info("Thread 1 reading");
Assertions.assertEquals("John", curTx.get(Parent.class, new JObjectKey(key)).orElseThrow().name());
Assertions.assertEquals("John", curTx.get(Parent.class, new JObjectKeyImpl(key)).orElseThrow().name());
Log.info("Thread 1 done reading");
});
Log.info("Thread 1 finished");
@@ -576,9 +576,9 @@ public abstract class ObjectsTestImpl {
throw new RuntimeException(e);
}
txm.run(() -> {
Assertions.assertEquals("John2", curTx.get(Parent.class, new JObjectKey(key)).orElseThrow().name());
Assertions.assertEquals("John2", curTx.get(Parent.class, new JObjectKeyImpl(key)).orElseThrow().name());
});
deleteAndCheck(new JObjectKey(key));
deleteAndCheck(new JObjectKeyImpl(key));
}
@RepeatedTest(100)
@@ -596,7 +596,7 @@ public abstract class ObjectsTestImpl {
curTx.put(new Parent(JObjectKey.of(key4), "John4"));
});
txm.run(() -> {
var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key));
var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key));
var got = iter.next();
Assertions.assertEquals(key1, got.getKey().name());
got = iter.next();
@@ -624,7 +624,7 @@ public abstract class ObjectsTestImpl {
curTx.put(new Parent(JObjectKey.of(key4), "John4"));
});
txm.run(() -> {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
var got = iter.next();
Assertions.assertEquals(key1, got.getKey().name());
got = iter.next();
@@ -636,7 +636,7 @@ public abstract class ObjectsTestImpl {
}
});
txm.run(() -> {
try (var iter = curTx.getIterator(IteratorStart.LT, new JObjectKey(key + "_5"))) {
try (var iter = curTx.getIterator(IteratorStart.LT, new JObjectKeyImpl(key + "_5"))) {
var got = iter.next();
Assertions.assertEquals(key4, got.getKey().name());
Assertions.assertTrue(iter.hasPrev());
@@ -648,14 +648,14 @@ public abstract class ObjectsTestImpl {
}
});
txm.run(() -> {
curTx.delete(new JObjectKey(key));
curTx.delete(new JObjectKey(key1));
curTx.delete(new JObjectKey(key2));
curTx.delete(new JObjectKey(key3));
curTx.delete(new JObjectKey(key4));
curTx.delete(new JObjectKeyImpl(key));
curTx.delete(new JObjectKeyImpl(key1));
curTx.delete(new JObjectKeyImpl(key2));
curTx.delete(new JObjectKeyImpl(key3));
curTx.delete(new JObjectKeyImpl(key4));
});
txm.run(() -> {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
Assertions.assertTrue(!iter.hasNext() || !iter.next().getKey().name().startsWith(key));
}
});
@@ -696,7 +696,7 @@ public abstract class ObjectsTestImpl {
try {
barrier.await();
barrier2.await();
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
var got = iter.next();
Assertions.assertEquals(key1, got.getKey().name());
got = iter.next();
@@ -711,7 +711,7 @@ public abstract class ObjectsTestImpl {
});
Log.info("All threads finished");
txm.run(() -> {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
var got = iter.next();
Assertions.assertEquals(key1, got.getKey().name());
got = iter.next();
@@ -723,14 +723,14 @@ public abstract class ObjectsTestImpl {
}
});
txm.run(() -> {
curTx.delete(new JObjectKey(key));
curTx.delete(new JObjectKey(key1));
curTx.delete(new JObjectKey(key2));
curTx.delete(new JObjectKey(key3));
curTx.delete(new JObjectKey(key4));
curTx.delete(new JObjectKeyImpl(key));
curTx.delete(new JObjectKeyImpl(key1));
curTx.delete(new JObjectKeyImpl(key2));
curTx.delete(new JObjectKeyImpl(key3));
curTx.delete(new JObjectKeyImpl(key4));
});
txm.run(() -> {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
Assertions.assertTrue(!iter.hasNext() || !iter.next().getKey().name().startsWith(key));
}
});
@@ -772,7 +772,7 @@ public abstract class ObjectsTestImpl {
try {
barrier.await();
barrier2.await();
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
var got = iter.next();
Assertions.assertEquals(key1, got.getKey().name());
got = iter.next();
@@ -790,7 +790,7 @@ public abstract class ObjectsTestImpl {
});
Log.info("All threads finished");
txm.run(() -> {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
var got = iter.next();
Assertions.assertEquals(key1, got.getKey().name());
got = iter.next();
@@ -803,14 +803,14 @@ public abstract class ObjectsTestImpl {
}
});
txm.run(() -> {
curTx.delete(new JObjectKey(key));
curTx.delete(new JObjectKey(key1));
curTx.delete(new JObjectKey(key2));
curTx.delete(new JObjectKey(key3));
curTx.delete(new JObjectKey(key4));
curTx.delete(new JObjectKeyImpl(key));
curTx.delete(new JObjectKeyImpl(key1));
curTx.delete(new JObjectKeyImpl(key2));
curTx.delete(new JObjectKeyImpl(key3));
curTx.delete(new JObjectKeyImpl(key4));
});
txm.run(() -> {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
Assertions.assertTrue(!iter.hasNext() || !iter.next().getKey().name().startsWith(key));
}
});
@@ -841,7 +841,7 @@ public abstract class ObjectsTestImpl {
throw new RuntimeException(e);
}
curTx.put(new Parent(JObjectKey.of(key3), "John3"));
curTx.delete(new JObjectKey(key2));
curTx.delete(new JObjectKeyImpl(key2));
Log.info("Thread 1 committing");
});
Log.info("Thread 1 commited");
@@ -852,7 +852,7 @@ public abstract class ObjectsTestImpl {
try {
barrier.await();
barrier2.await();
try (var iter = curTx.getIterator(IteratorStart.LE, new JObjectKey(key3))) {
try (var iter = curTx.getIterator(IteratorStart.LE, new JObjectKeyImpl(key3))) {
var got = iter.next();
Assertions.assertEquals(key2, got.getKey().name());
Assertions.assertEquals("John2", ((Parent) got.getValue()).name());
@@ -878,7 +878,7 @@ public abstract class ObjectsTestImpl {
got = iter.next();
Assertions.assertEquals(key4, got.getKey().name());
}
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
var got = iter.next();
Assertions.assertEquals(key1, got.getKey().name());
got = iter.next();
@@ -896,7 +896,7 @@ public abstract class ObjectsTestImpl {
});
Log.info("All threads finished");
txm.run(() -> {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
var got = iter.next();
Assertions.assertEquals(key1, got.getKey().name());
got = iter.next();
@@ -906,13 +906,13 @@ public abstract class ObjectsTestImpl {
}
});
txm.run(() -> {
curTx.delete(new JObjectKey(key));
curTx.delete(new JObjectKey(key1));
curTx.delete(new JObjectKey(key3));
curTx.delete(new JObjectKey(key4));
curTx.delete(new JObjectKeyImpl(key));
curTx.delete(new JObjectKeyImpl(key1));
curTx.delete(new JObjectKeyImpl(key3));
curTx.delete(new JObjectKeyImpl(key4));
});
txm.run(() -> {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKey(key))) {
try (var iter = curTx.getIterator(IteratorStart.GT, new JObjectKeyImpl(key))) {
Assertions.assertTrue(!iter.hasNext() || !iter.next().getKey().name().startsWith(key));
}
});

View File

@@ -33,15 +33,15 @@ public class PreCommitTxHookTest {
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("ParentCreate2")).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("ParentCreate2")).orElse(null);
Assertions.assertEquals("John", parent.name());
});
ArgumentCaptor<JData> dataCaptor = ArgumentCaptor.forClass(JData.class);
ArgumentCaptor<JObjectKey> keyCaptor = ArgumentCaptor.forClass(JObjectKey.class);
ArgumentCaptor<JObjectKey> keyCaptor = ArgumentCaptor.forClass(JObjectKeyImpl.class);
Mockito.verify(spyHook, Mockito.times(1)).onCreate(keyCaptor.capture(), dataCaptor.capture());
Assertions.assertEquals("John", ((Parent) dataCaptor.getValue()).name());
Assertions.assertEquals(new JObjectKey("ParentCreate2"), keyCaptor.getValue());
Assertions.assertEquals(new JObjectKeyImpl("ParentCreate2"), keyCaptor.getValue());
}
@Test
@@ -52,19 +52,19 @@ public class PreCommitTxHookTest {
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("ParentDel")).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("ParentDel")).orElse(null);
Assertions.assertEquals("John", parent.name());
});
txm.run(() -> {
curTx.delete(new JObjectKey("ParentDel"));
curTx.delete(new JObjectKeyImpl("ParentDel"));
});
ArgumentCaptor<JData> dataCaptor = ArgumentCaptor.forClass(JData.class);
ArgumentCaptor<JObjectKey> keyCaptor = ArgumentCaptor.forClass(JObjectKey.class);
ArgumentCaptor<JObjectKey> keyCaptor = ArgumentCaptor.forClass(JObjectKeyImpl.class);
Mockito.verify(spyHook, Mockito.times(1)).onDelete(keyCaptor.capture(), dataCaptor.capture());
Assertions.assertEquals("John", ((Parent) dataCaptor.getValue()).name());
Assertions.assertEquals(new JObjectKey("ParentDel"), keyCaptor.getValue());
Assertions.assertEquals(new JObjectKeyImpl("ParentDel"), keyCaptor.getValue());
}
@Test
@@ -81,11 +81,11 @@ public class PreCommitTxHookTest {
ArgumentCaptor<JData> dataCaptorOld = ArgumentCaptor.forClass(JData.class);
ArgumentCaptor<JData> dataCaptorNew = ArgumentCaptor.forClass(JData.class);
ArgumentCaptor<JObjectKey> keyCaptor = ArgumentCaptor.forClass(JObjectKey.class);
ArgumentCaptor<JObjectKey> keyCaptor = ArgumentCaptor.forClass(JObjectKeyImpl.class);
Mockito.verify(spyHook, Mockito.times(1)).onChange(keyCaptor.capture(), dataCaptorOld.capture(), dataCaptorNew.capture());
Assertions.assertEquals("John", ((Parent) dataCaptorOld.getValue()).name());
Assertions.assertEquals("John changed", ((Parent) dataCaptorNew.getValue()).name());
Assertions.assertEquals(new JObjectKey("ParentEdit"), keyCaptor.getValue());
Assertions.assertEquals(new JObjectKeyImpl("ParentEdit"), keyCaptor.getValue());
}
@Test
@@ -96,18 +96,18 @@ public class PreCommitTxHookTest {
});
txm.run(() -> {
var parent = curTx.get(Parent.class, new JObjectKey("ParentEdit2")).orElse(null);
var parent = curTx.get(Parent.class, new JObjectKeyImpl("ParentEdit2")).orElse(null);
Assertions.assertEquals("John", parent.name());
curTx.put(parent.withName("John changed"));
});
ArgumentCaptor<JData> dataCaptorOld = ArgumentCaptor.forClass(JData.class);
ArgumentCaptor<JData> dataCaptorNew = ArgumentCaptor.forClass(JData.class);
ArgumentCaptor<JObjectKey> keyCaptor = ArgumentCaptor.forClass(JObjectKey.class);
ArgumentCaptor<JObjectKey> keyCaptor = ArgumentCaptor.forClass(JObjectKeyImpl.class);
Mockito.verify(spyHook, Mockito.times(1)).onChange(keyCaptor.capture(), dataCaptorOld.capture(), dataCaptorNew.capture());
Assertions.assertEquals("John", ((Parent) dataCaptorOld.getValue()).name());
Assertions.assertEquals("John changed", ((Parent) dataCaptorNew.getValue()).name());
Assertions.assertEquals(new JObjectKey("ParentEdit2"), keyCaptor.getValue());
Assertions.assertEquals(new JObjectKeyImpl("ParentEdit2"), keyCaptor.getValue());
}
@ApplicationScoped

View File

@@ -2,6 +2,7 @@ package com.usatiuk.dhfs;
import com.usatiuk.dhfs.jmap.JMapRef;
import com.usatiuk.objects.JObjectKey;
import com.usatiuk.objects.JObjectKeyImpl;
public record JDataNormalRef(JObjectKey obj) implements JDataRef {
@Override

View File

@@ -1,6 +1,7 @@
package com.usatiuk.dhfs;
import com.usatiuk.objects.JObjectKey;
import com.usatiuk.objects.JObjectKeyImpl;
import java.io.Serializable;

View File

@@ -48,11 +48,11 @@ public class FileSyncHandler implements ObjSyncHandler<File, FileDto> {
DhfsFileService fileService;
private JKleppmannTreeManager.JKleppmannTree getTreeW() {
return jKleppmannTreeManager.getTree(new JObjectKey("fs"));
return jKleppmannTreeManager.getTree(JObjectKey.of("fs"));
}
private JKleppmannTreeManager.JKleppmannTree getTreeR() {
return jKleppmannTreeManager.getTree(new JObjectKey("fs"), LockingStrategy.OPTIMISTIC);
return jKleppmannTreeManager.getTree(JObjectKey.of("fs"), LockingStrategy.OPTIMISTIC);
}
private void resolveConflict(PeerId from, JObjectKey key, PMap<PeerId, Long> receivedChangelog,

View File

@@ -9,6 +9,7 @@ import com.usatiuk.dhfs.files.objects.ChunkData;
import com.usatiuk.dhfs.files.objects.File;
import com.usatiuk.objects.JData;
import com.usatiuk.objects.JObjectKey;
import com.usatiuk.objects.JObjectKeyImpl;
import com.usatiuk.objects.iterators.IteratorStart;
import com.usatiuk.dhfs.jkleppmanntree.JKleppmannTreeManager;
import com.usatiuk.dhfs.jkleppmanntree.structs.JKleppmannTreeNode;
@@ -81,11 +82,11 @@ public class DhfsFileServiceImpl implements DhfsFileService {
JMapHelper jMapHelper;
private JKleppmannTreeManager.JKleppmannTree getTreeW() {
return jKleppmannTreeManager.getTree(new JObjectKey("fs"));
return jKleppmannTreeManager.getTree(JObjectKey.of("fs"));
}
private JKleppmannTreeManager.JKleppmannTree getTreeR() {
return jKleppmannTreeManager.getTree(new JObjectKey("fs"), LockingStrategy.OPTIMISTIC);
return jKleppmannTreeManager.getTree(JObjectKey.of("fs"), LockingStrategy.OPTIMISTIC);
}
private ChunkData createChunk(ByteString bytes) {

View File

@@ -6,6 +6,7 @@ import com.usatiuk.dhfs.jkleppmanntree.structs.*;
import com.usatiuk.dhfs.repository.PersistentPeerDataService;
import com.usatiuk.dhfs.repository.invalidation.Op;
import com.usatiuk.dhfs.repository.peersync.PeerInfoService;
import com.usatiuk.objects.JObjectKeyImpl;
import com.usatiuk.objects.transaction.LockingStrategy;
import com.usatiuk.objects.transaction.Transaction;
import com.usatiuk.objects.transaction.TransactionManager;
@@ -258,22 +259,22 @@ public class JKleppmannTreeManager {
@Override
public JObjectKey getRootId() {
return new JObjectKey(_treeName.name() + "_jt_root");
return JObjectKey.of(_treeName.name() + "_jt_root");
}
@Override
public JObjectKey getTrashId() {
return new JObjectKey(_treeName.name() + "_jt_trash");
return JObjectKey.of(_treeName.name() + "_jt_trash");
}
@Override
public JObjectKey getLostFoundId() {
return new JObjectKey(_treeName.name() + "_jt_lf");
return JObjectKey.of(_treeName.name() + "_jt_lf");
}
@Override
public JObjectKey getNewNodeId() {
return new JObjectKey(UUID.randomUUID().toString());
return JObjectKey.of(UUID.randomUUID().toString());
}
@Override

View File

@@ -7,6 +7,7 @@ import com.usatiuk.dhfs.PeerId;
import com.usatiuk.dhfs.repository.peersync.structs.JKleppmannTreeNodeMetaPeer;
import com.usatiuk.kleppmanntree.OpMove;
import com.usatiuk.kleppmanntree.TreeNode;
import com.usatiuk.objects.JObjectKeyImpl;
import org.pcollections.HashTreePMap;
import org.pcollections.PCollection;
import org.pcollections.PMap;

View File

@@ -7,6 +7,7 @@ import com.usatiuk.dhfs.PeerId;
import com.usatiuk.kleppmanntree.CombinedTimestamp;
import com.usatiuk.kleppmanntree.LogRecord;
import com.usatiuk.kleppmanntree.OpMove;
import com.usatiuk.objects.JObjectKeyImpl;
import org.pcollections.PCollection;
import org.pcollections.PMap;
import org.pcollections.PSortedMap;
@@ -49,6 +50,6 @@ public record JKleppmannTreePersistentData(
@Override
public Collection<JObjectKey> collectRefsTo() {
return List.of(new JObjectKey(key().name() + "_jt_trash"), new JObjectKey(key().name() + "_jt_root"), new JObjectKey(key().name() + "_jt_lf"));
return List.of(JObjectKey.of(key().name() + "_jt_trash"), JObjectKey.of(key().name() + "_jt_root"), JObjectKey.of(key().name() + "_jt_lf"));
}
}