mirror of
https://github.com/usatiuk/dhfs.git
synced 2025-10-28 20:47:49 +01:00
rocksdb
This commit is contained in:
@@ -69,6 +69,11 @@
|
|||||||
<artifactId>lmdbjava</artifactId>
|
<artifactId>lmdbjava</artifactId>
|
||||||
<version>0.9.1</version>
|
<version>0.9.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.rocksdb</groupId>
|
||||||
|
<artifactId>rocksdbjni</artifactId>
|
||||||
|
<version>9.10.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.commons</groupId>
|
<groupId>org.apache.commons</groupId>
|
||||||
<artifactId>commons-collections4</artifactId>
|
<artifactId>commons-collections4</artifactId>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package com.usatiuk.objects.stores;
|
package com.usatiuk.objects.stores;
|
||||||
|
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
|
import com.usatiuk.dhfs.supportlib.UninitializedByteBuffer;
|
||||||
|
import com.usatiuk.dhfs.utils.RefcountedCloseable;
|
||||||
import com.usatiuk.objects.JObjectKey;
|
import com.usatiuk.objects.JObjectKey;
|
||||||
import com.usatiuk.objects.JObjectKeyImpl;
|
|
||||||
import com.usatiuk.objects.JObjectKeyMax;
|
import com.usatiuk.objects.JObjectKeyMax;
|
||||||
import com.usatiuk.objects.JObjectKeyMin;
|
import com.usatiuk.objects.JObjectKeyMin;
|
||||||
import com.usatiuk.objects.iterators.CloseableKvIterator;
|
import com.usatiuk.objects.iterators.CloseableKvIterator;
|
||||||
@@ -10,8 +11,6 @@ import com.usatiuk.objects.iterators.IteratorStart;
|
|||||||
import com.usatiuk.objects.iterators.KeyPredicateKvIterator;
|
import com.usatiuk.objects.iterators.KeyPredicateKvIterator;
|
||||||
import com.usatiuk.objects.iterators.ReversibleKvIterator;
|
import com.usatiuk.objects.iterators.ReversibleKvIterator;
|
||||||
import com.usatiuk.objects.snapshot.Snapshot;
|
import com.usatiuk.objects.snapshot.Snapshot;
|
||||||
import com.usatiuk.dhfs.supportlib.UninitializedByteBuffer;
|
|
||||||
import com.usatiuk.dhfs.utils.RefcountedCloseable;
|
|
||||||
import io.quarkus.arc.properties.IfBuildProperty;
|
import io.quarkus.arc.properties.IfBuildProperty;
|
||||||
import io.quarkus.logging.Log;
|
import io.quarkus.logging.Log;
|
||||||
import io.quarkus.runtime.ShutdownEvent;
|
import io.quarkus.runtime.ShutdownEvent;
|
||||||
|
|||||||
@@ -0,0 +1,280 @@
|
|||||||
|
package com.usatiuk.objects.stores;
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString;
|
||||||
|
import com.usatiuk.objects.JObjectKey;
|
||||||
|
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.ReversibleKvIterator;
|
||||||
|
import com.usatiuk.objects.snapshot.Snapshot;
|
||||||
|
import io.quarkus.arc.properties.IfBuildProperty;
|
||||||
|
import io.quarkus.logging.Log;
|
||||||
|
import io.quarkus.runtime.ShutdownEvent;
|
||||||
|
import io.quarkus.runtime.StartupEvent;
|
||||||
|
import jakarta.annotation.Priority;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
import jakarta.enterprise.event.Observes;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||||
|
import org.rocksdb.*;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
@IfBuildProperty(name = "dhfs.objects.persistence", stringValue = "rocks")
|
||||||
|
public class RocksDbObjectPersistentStore implements ObjectPersistentStore {
|
||||||
|
private static final String DB_NAME = "objects";
|
||||||
|
private static final byte[] DB_VER_OBJ_NAME = "__DB_VER_OBJ".getBytes(StandardCharsets.UTF_8);
|
||||||
|
private final Path _root;
|
||||||
|
private Options _options;
|
||||||
|
private TransactionDBOptions _transactionDBOptions;
|
||||||
|
private TransactionDB _db;
|
||||||
|
private boolean _ready = false;
|
||||||
|
|
||||||
|
public RocksDbObjectPersistentStore(@ConfigProperty(name = "dhfs.objects.persistence.files.root") String root) {
|
||||||
|
_root = Path.of(root).resolve("objects");
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(@Observes @Priority(100) StartupEvent event) throws RocksDBException {
|
||||||
|
if (!_root.toFile().exists()) {
|
||||||
|
Log.info("Initializing with root " + _root);
|
||||||
|
_root.toFile().mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
RocksDB.loadLibrary();
|
||||||
|
|
||||||
|
_options = new Options().setCreateIfMissing(true);
|
||||||
|
_transactionDBOptions = new TransactionDBOptions();
|
||||||
|
_db = TransactionDB.open(_options, _transactionDBOptions, _root.toString());
|
||||||
|
|
||||||
|
try (var txn = _db.beginTransaction(new WriteOptions())) {
|
||||||
|
var read = readTxId(txn);
|
||||||
|
if (read.isPresent()) {
|
||||||
|
Log.infov("Read tx id {0}", read.get());
|
||||||
|
} else {
|
||||||
|
txn.put(DB_VER_OBJ_NAME, ByteBuffer.allocate(8).putLong(0).array());
|
||||||
|
txn.commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Long> readTxId(Transaction txn) throws RocksDBException {
|
||||||
|
var value = txn.get(new ReadOptions(), DB_VER_OBJ_NAME);
|
||||||
|
return Optional.ofNullable(value).map(ByteBuffer::wrap).map(ByteBuffer::getLong);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdown(@Observes @Priority(900) ShutdownEvent event) {
|
||||||
|
_ready = false;
|
||||||
|
_db.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyReady() {
|
||||||
|
if (!_ready) throw new IllegalStateException("Wrong service order!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Optional<ByteString> readObject(JObjectKey name) {
|
||||||
|
verifyReady();
|
||||||
|
byte[] got = null;
|
||||||
|
try {
|
||||||
|
got = _db.get(new ReadOptions(), name.bytes());
|
||||||
|
} catch (RocksDBException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return Optional.ofNullable(got).map(ByteString::copyFrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Snapshot<JObjectKey, ByteString> getSnapshot() {
|
||||||
|
var txn = _db.beginTransaction(new WriteOptions());
|
||||||
|
txn.setSnapshot();
|
||||||
|
var rocksDbSnapshot = txn.getSnapshot();
|
||||||
|
long commitId = 0;
|
||||||
|
try {
|
||||||
|
commitId = readTxId(txn).orElseThrow();
|
||||||
|
} catch (RocksDBException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
long finalCommitId = commitId;
|
||||||
|
return new Snapshot<JObjectKey, ByteString>() {
|
||||||
|
private final Transaction _txn = txn;
|
||||||
|
private final long _id = finalCommitId;
|
||||||
|
private final org.rocksdb.Snapshot _rocksDbSnapshot = rocksDbSnapshot;
|
||||||
|
private boolean _closed = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CloseableKvIterator<JObjectKey, ByteString> getIterator(IteratorStart start, JObjectKey key) {
|
||||||
|
assert !_closed;
|
||||||
|
return new RocksDbKvIterator(_txn, start, key, _rocksDbSnapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public Optional<ByteString> readObject(JObjectKey name) {
|
||||||
|
assert !_closed;
|
||||||
|
try (var readOptions = new ReadOptions().setSnapshot(_rocksDbSnapshot)) {
|
||||||
|
var got = _txn.get(readOptions, name.bytes());
|
||||||
|
return Optional.ofNullable(got).map(ByteString::copyFrom);
|
||||||
|
} catch (RocksDBException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long id() {
|
||||||
|
assert !_closed;
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
assert !_closed;
|
||||||
|
_closed = true;
|
||||||
|
_txn.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Runnable prepareTx(TxManifestRaw names, long txId) {
|
||||||
|
verifyReady();
|
||||||
|
var txn = _db.beginTransaction(new WriteOptions());
|
||||||
|
try {
|
||||||
|
for (var written : names.written()) {
|
||||||
|
txn.put(written.getKey().bytes(), written.getValue().toByteArray());
|
||||||
|
}
|
||||||
|
for (JObjectKey key : names.deleted()) {
|
||||||
|
txn.delete(key.bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert txId > readTxId(txn).orElseThrow();
|
||||||
|
|
||||||
|
txn.put(DB_VER_OBJ_NAME, ByteBuffer.allocate(8).putLong(txId).array());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
txn.close();
|
||||||
|
throw new RuntimeException(t);
|
||||||
|
}
|
||||||
|
return () -> {
|
||||||
|
try {
|
||||||
|
txn.commit();
|
||||||
|
} catch (RocksDBException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
txn.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTotalSpace() {
|
||||||
|
verifyReady();
|
||||||
|
return _root.toFile().getTotalSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getFreeSpace() {
|
||||||
|
verifyReady();
|
||||||
|
return _root.toFile().getFreeSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getUsableSpace() {
|
||||||
|
verifyReady();
|
||||||
|
return _root.toFile().getUsableSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RocksDbKvIterator extends ReversibleKvIterator<JObjectKey, ByteString> {
|
||||||
|
private final RocksIterator _iterator;
|
||||||
|
private final org.rocksdb.Snapshot _rocksDbSnapshot;
|
||||||
|
private final ReadOptions _readOptions;
|
||||||
|
private boolean _hasNext;
|
||||||
|
|
||||||
|
RocksDbKvIterator(Transaction txn, IteratorStart start, JObjectKey key, org.rocksdb.Snapshot rocksDbSnapshot) {
|
||||||
|
_rocksDbSnapshot = rocksDbSnapshot;
|
||||||
|
_readOptions = new ReadOptions().setSnapshot(_rocksDbSnapshot);
|
||||||
|
_iterator = txn.getIterator(_readOptions);
|
||||||
|
verifyReady();
|
||||||
|
|
||||||
|
if (key instanceof JObjectKeyMin) {
|
||||||
|
_iterator.seekToFirst();
|
||||||
|
} else if (key instanceof JObjectKeyMax) {
|
||||||
|
_iterator.seekToLast();
|
||||||
|
} else {
|
||||||
|
_iterator.seek(key.bytes());
|
||||||
|
}
|
||||||
|
_hasNext = _iterator.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
_iterator.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void reverse() {
|
||||||
|
if (_hasNext) {
|
||||||
|
if (_goingForward) {
|
||||||
|
_iterator.prev();
|
||||||
|
} else {
|
||||||
|
_iterator.next();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_goingForward) {
|
||||||
|
_iterator.seekToLast();
|
||||||
|
} else {
|
||||||
|
_iterator.seekToFirst();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_goingForward = !_goingForward;
|
||||||
|
_hasNext = _iterator.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected JObjectKey peekImpl() {
|
||||||
|
if (!_hasNext) {
|
||||||
|
throw new NoSuchElementException("No more elements");
|
||||||
|
}
|
||||||
|
return JObjectKey.fromByteBuffer(ByteBuffer.wrap(_iterator.key()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void skipImpl() {
|
||||||
|
if (_goingForward) {
|
||||||
|
_iterator.next();
|
||||||
|
} else {
|
||||||
|
_iterator.prev();
|
||||||
|
}
|
||||||
|
_hasNext = _iterator.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean hasImpl() {
|
||||||
|
return _hasNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Pair<JObjectKey, ByteString> nextImpl() {
|
||||||
|
if (!_hasNext) {
|
||||||
|
throw new NoSuchElementException("No more elements");
|
||||||
|
}
|
||||||
|
var key = JObjectKey.fromByteBuffer(ByteBuffer.wrap(_iterator.key()));
|
||||||
|
var value = ByteString.copyFrom(_iterator.value());
|
||||||
|
if (_goingForward) {
|
||||||
|
_iterator.next();
|
||||||
|
} else {
|
||||||
|
_iterator.prev();
|
||||||
|
}
|
||||||
|
_hasNext = _iterator.isValid();
|
||||||
|
return Pair.of(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,10 +24,6 @@ public class SerializingObjectPersistentStore {
|
|||||||
@Inject
|
@Inject
|
||||||
ObjectPersistentStore delegateStore;
|
ObjectPersistentStore delegateStore;
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
Optional<JDataVersionedWrapper> readObject(JObjectKey name) {
|
|
||||||
return delegateStore.readObject(name).map(serializer::deserialize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Snapshot<JObjectKey, JDataVersionedWrapper> getSnapshot() {
|
public Snapshot<JObjectKey, JDataVersionedWrapper> getSnapshot() {
|
||||||
return new Snapshot<JObjectKey, JDataVersionedWrapper>() {
|
return new Snapshot<JObjectKey, JDataVersionedWrapper>() {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
dhfs.objects.persistence=lmdb
|
dhfs.objects.persistence=rocks
|
||||||
dhfs.objects.writeback.limit=134217728
|
dhfs.objects.writeback.limit=134217728
|
||||||
dhfs.objects.lru.limit=134217728
|
dhfs.objects.lru.limit=134217728
|
||||||
dhfs.objects.lru.print-stats=true
|
dhfs.objects.lru.print-stats=true
|
||||||
|
|||||||
@@ -1,129 +1,129 @@
|
|||||||
package com.usatiuk.objects.stores;
|
//package com.usatiuk.objects.stores;
|
||||||
|
//
|
||||||
|
//
|
||||||
import com.google.protobuf.ByteString;
|
//import com.google.protobuf.ByteString;
|
||||||
import com.usatiuk.objects.JObjectKey;
|
//import com.usatiuk.objects.JObjectKey;
|
||||||
import com.usatiuk.objects.Just;
|
//import com.usatiuk.objects.Just;
|
||||||
import com.usatiuk.objects.TempDataProfile;
|
//import com.usatiuk.objects.TempDataProfile;
|
||||||
import com.usatiuk.objects.iterators.IteratorStart;
|
//import com.usatiuk.objects.iterators.IteratorStart;
|
||||||
import io.quarkus.test.junit.QuarkusTest;
|
//import io.quarkus.test.junit.QuarkusTest;
|
||||||
import io.quarkus.test.junit.TestProfile;
|
//import io.quarkus.test.junit.TestProfile;
|
||||||
import jakarta.inject.Inject;
|
//import jakarta.inject.Inject;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
//import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.junit.jupiter.api.Assertions;
|
//import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.RepeatedTest;
|
//import org.junit.jupiter.api.RepeatedTest;
|
||||||
|
//
|
||||||
import java.util.List;
|
//import java.util.List;
|
||||||
|
//
|
||||||
class Profiles {
|
//class Profiles {
|
||||||
public static class LmdbKvIteratorTestProfile extends TempDataProfile {
|
// public static class LmdbKvIteratorTestProfile extends TempDataProfile {
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
@QuarkusTest
|
//@QuarkusTest
|
||||||
@TestProfile(Profiles.LmdbKvIteratorTestProfile.class)
|
//@TestProfile(Profiles.LmdbKvIteratorTestProfile.class)
|
||||||
public class LmdbKvIteratorTest {
|
//public class LmdbKvIteratorTest {
|
||||||
|
//
|
||||||
@Inject
|
// @Inject
|
||||||
LmdbObjectPersistentStore store;
|
// LmdbObjectPersistentStore store;
|
||||||
|
//
|
||||||
long getNextTxId() {
|
// long getNextTxId() {
|
||||||
try (var s = store.getSnapshot()) {
|
// try (var s = store.getSnapshot()) {
|
||||||
return s.id() + 1;
|
// return s.id() + 1;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@RepeatedTest(100)
|
// @RepeatedTest(100)
|
||||||
public void iteratorTest1() {
|
// public void iteratorTest1() {
|
||||||
store.prepareTx(
|
// store.prepareTx(
|
||||||
new TxManifestRaw(
|
// new TxManifestRaw(
|
||||||
List.of(Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})),
|
// List.of(Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})),
|
||||||
Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})),
|
// Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})),
|
||||||
Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4}))),
|
// Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4}))),
|
||||||
List.of()
|
// List.of()
|
||||||
), getNextTxId()
|
// ), getNextTxId()
|
||||||
).run();
|
// ).run();
|
||||||
|
//
|
||||||
try (var snapshot = store.getSnapshot()) {
|
// try (var snapshot = store.getSnapshot()) {
|
||||||
var iterator = snapshot.getIterator(IteratorStart.GE, JObjectKey.of(""));
|
// var iterator = snapshot.getIterator(IteratorStart.GE, JObjectKey.of(""));
|
||||||
Just.checkIterator(iterator, List.of(Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})),
|
// Just.checkIterator(iterator, List.of(Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})),
|
||||||
Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})),
|
// Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})),
|
||||||
Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4}))));
|
// Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4}))));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.LE, JObjectKey.of(Long.toString(3)));
|
// iterator = snapshot.getIterator(IteratorStart.LE, JObjectKey.of(Long.toString(3)));
|
||||||
Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
// Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.LE, JObjectKey.of(Long.toString(2)));
|
// iterator = snapshot.getIterator(IteratorStart.LE, JObjectKey.of(Long.toString(2)));
|
||||||
Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
// Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.GE, JObjectKey.of(Long.toString(2)));
|
// iterator = snapshot.getIterator(IteratorStart.GE, JObjectKey.of(Long.toString(2)));
|
||||||
Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
// Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.GT, JObjectKey.of(Long.toString(2)));
|
// iterator = snapshot.getIterator(IteratorStart.GT, JObjectKey.of(Long.toString(2)));
|
||||||
Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
// Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.LT, JObjectKey.of(Long.toString(3)));
|
// iterator = snapshot.getIterator(IteratorStart.LT, JObjectKey.of(Long.toString(3)));
|
||||||
Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
// Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.LT, JObjectKey.of(Long.toString(2)));
|
// iterator = snapshot.getIterator(IteratorStart.LT, JObjectKey.of(Long.toString(2)));
|
||||||
Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})), Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
// Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})), Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.LT, JObjectKey.of(Long.toString(1)));
|
// iterator = snapshot.getIterator(IteratorStart.LT, JObjectKey.of(Long.toString(1)));
|
||||||
Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})), Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
// Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})), Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.LE, JObjectKey.of(Long.toString(1)));
|
// iterator = snapshot.getIterator(IteratorStart.LE, JObjectKey.of(Long.toString(1)));
|
||||||
Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})), Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
// Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})), Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.GT, JObjectKey.of(Long.toString(3)));
|
// iterator = snapshot.getIterator(IteratorStart.GT, JObjectKey.of(Long.toString(3)));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.GT, JObjectKey.of(Long.toString(4)));
|
// iterator = snapshot.getIterator(IteratorStart.GT, JObjectKey.of(Long.toString(4)));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.LE, JObjectKey.of(Long.toString(0)));
|
// iterator = snapshot.getIterator(IteratorStart.LE, JObjectKey.of(Long.toString(0)));
|
||||||
Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})), Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
// Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})), Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
||||||
Assertions.assertFalse(iterator.hasNext());
|
// Assertions.assertFalse(iterator.hasNext());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
|
//
|
||||||
iterator = snapshot.getIterator(IteratorStart.GE, JObjectKey.of(Long.toString(2)));
|
// iterator = snapshot.getIterator(IteratorStart.GE, JObjectKey.of(Long.toString(2)));
|
||||||
Assertions.assertTrue(iterator.hasNext());
|
// Assertions.assertTrue(iterator.hasNext());
|
||||||
Assertions.assertEquals(JObjectKey.of(Long.toString(2)), iterator.peekNextKey());
|
// Assertions.assertEquals(JObjectKey.of(Long.toString(2)), iterator.peekNextKey());
|
||||||
Assertions.assertEquals(JObjectKey.of(Long.toString(1)), iterator.peekPrevKey());
|
// Assertions.assertEquals(JObjectKey.of(Long.toString(1)), iterator.peekPrevKey());
|
||||||
Assertions.assertEquals(JObjectKey.of(Long.toString(2)), iterator.peekNextKey());
|
// Assertions.assertEquals(JObjectKey.of(Long.toString(2)), iterator.peekNextKey());
|
||||||
Assertions.assertEquals(JObjectKey.of(Long.toString(1)), iterator.peekPrevKey());
|
// Assertions.assertEquals(JObjectKey.of(Long.toString(1)), iterator.peekPrevKey());
|
||||||
Just.checkIterator(iterator.reversed(), Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})));
|
// Just.checkIterator(iterator.reversed(), Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})));
|
||||||
Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})), Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
// Just.checkIterator(iterator, Pair.of(JObjectKey.of(Long.toString(1)), ByteString.copyFrom(new byte[]{2})), Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})));
|
||||||
Assertions.assertEquals(Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})), iterator.prev());
|
// Assertions.assertEquals(Pair.of(JObjectKey.of(Long.toString(3)), ByteString.copyFrom(new byte[]{4})), iterator.prev());
|
||||||
Assertions.assertEquals(Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), iterator.prev());
|
// Assertions.assertEquals(Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), iterator.prev());
|
||||||
Assertions.assertEquals(Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), iterator.next());
|
// Assertions.assertEquals(Pair.of(JObjectKey.of(Long.toString(2)), ByteString.copyFrom(new byte[]{3})), iterator.next());
|
||||||
iterator.close();
|
// iterator.close();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
store.prepareTx(new TxManifestRaw(
|
// store.prepareTx(new TxManifestRaw(
|
||||||
List.of(),
|
// List.of(),
|
||||||
List.of(JObjectKey.of(Long.toString(1)), JObjectKey.of(Long.toString(2)), JObjectKey.of(Long.toString(3)))
|
// List.of(JObjectKey.of(Long.toString(1)), JObjectKey.of(Long.toString(2)), JObjectKey.of(Long.toString(3)))
|
||||||
),
|
// ),
|
||||||
getNextTxId()
|
// getNextTxId()
|
||||||
).run();
|
// ).run();
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|||||||
Reference in New Issue
Block a user