Improve column definition, more tests

This commit is contained in:
Andrea Cavalli 2023-12-08 20:46:40 +01:00
parent 0727be5866
commit 34c7ca4144
16 changed files with 285 additions and 64 deletions

View File

@ -29,6 +29,11 @@
<artifactId>argparse4j</artifactId>
<version>0.9.0</version>
</dependency>
<dependency>
<groupId>it.unimi.dsi</groupId>
<artifactId>fastutil-core</artifactId>
<version>8.5.12</version>
</dependency>
<dependency>
<groupId>com.github.seancfoley</groupId>
<artifactId>ipaddress</artifactId>

View File

@ -81,7 +81,7 @@ public class Main {
switch (url.getScheme()) {
case "unix" -> clientBuilder.setUnixSocket(UnixDomainSocketAddress.of(Path.of(url.getPath())));
case "file" -> clientBuilder.setEmbeddedPath(Path.of(url.getPath()));
case "file" -> clientBuilder.setEmbeddedPath(Path.of((url.getAuthority() != null ? url.getAuthority() : "") + url.getPath()).normalize());
case "memory" -> clientBuilder.setEmbeddedInMemory(true);
case "rocksdb" -> clientBuilder.setAddress(new HostName(url.getHost()).asInetSocketAddress());
default -> throw new IllegalArgumentException("Invalid scheme: " + url.getScheme());

View File

@ -0,0 +1,34 @@
package it.cavallium.rockserver.core.common;
import it.cavallium.rockserver.core.impl.ColumnInstance;
import it.cavallium.rockserver.core.impl.XXHash32;
import java.lang.foreign.MemorySegment;
public enum ColumnHashType implements HashFunction {
XXHASH32(Integer.BYTES, (inputData, hashResult) -> XXHash32.getInstance()
.hash(inputData, 0, Math.toIntExact(inputData.byteSize()), 0, hashResult)),
XXHASH8(Byte.BYTES, (inputData, hashResult) -> {
var xxHash = XXHash32.getInstance().hash(Utils.toByteArray(inputData), 0, Math.toIntExact(inputData.byteSize()), 0);
hashResult.set(ColumnInstance.BIG_ENDIAN_BYTES, 0, (byte) xxHash);
}),
ALLSAME8(Byte.BYTES, (inputData, hashResult) -> {
hashResult.set(ColumnInstance.BIG_ENDIAN_BYTES, 0, (byte) 0);
});
private final int bytes;
private final HashFunction hashFunction;
ColumnHashType(int bytes, HashFunction hashFunction) {
this.bytes = bytes;
this.hashFunction = hashFunction;
}
public int bytesSize() {
return bytes;
}
public void hash(MemorySegment inputData, MemorySegment hashResult) {
hashFunction.hash(inputData, hashResult);
}
}

View File

@ -1,18 +1,43 @@
package it.cavallium.rockserver.core.common;
public record ColumnSchema(int[] keys, int variableLengthKeysCount, boolean hasValue) {
public ColumnSchema {
if (variableLengthKeysCount > keys.length) {
throw new IllegalArgumentException("variable length keys count must be less or equal keysCount");
import it.cavallium.rockserver.core.common.RocksDBException.RocksDBErrorType;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.objects.ObjectList;
import java.lang.foreign.MemorySegment;
public record ColumnSchema(IntList keys, ObjectList<ColumnHashType> variableTailKeys, boolean hasValue) {
public static ColumnSchema of(IntList fixedKeys, ObjectList<ColumnHashType> variableTailKeys, boolean hasValue) {
IntList keys;
if (!variableTailKeys.isEmpty()) {
keys = new IntArrayList(fixedKeys.size() + variableTailKeys.size());
keys.addAll(fixedKeys);
for (ColumnHashType variableTailKey : variableTailKeys) {
keys.add(variableTailKey.bytesSize());
}
} else {
keys = fixedKeys;
}
for (int i = 0; i < keys.length - variableLengthKeysCount; i++) {
if (keys[i] <= 0) {
throw new UnsupportedOperationException("Key length must be > 0");
return new ColumnSchema(keys, variableTailKeys, hasValue);
}
public ColumnSchema {
final int keysSize = keys.size();
final int variableKeysSize = variableTailKeys.size();
if (variableKeysSize > keysSize) {
throw new RocksDBException(RocksDBErrorType.KEYS_COUNT_MISMATCH, "variable length keys count must be less or equal keysCount");
}
for (int i = 0; i < keysSize - variableKeysSize; i++) {
if (keys.getInt(i) <= 0) {
throw new RocksDBException(RocksDBErrorType.KEY_LENGTH_MISMATCH, "Key length must be > 0");
}
}
for (int i = keys.length - variableLengthKeysCount; i < keys.length; i++) {
if (keys[i] <= 1) {
throw new UnsupportedOperationException("Key hash length must be > 1");
for (int i = keysSize - variableKeysSize; i < keysSize; i++) {
var hash = variableTailKeys.get(i - (keysSize - variableKeysSize));
var keySize = keys.getInt(i);
if (keySize != hash.bytesSize()) {
throw new RocksDBException(RocksDBErrorType.KEY_HASH_SIZE_MISMATCH, "Key hash length of type " + hash + " must be " + hash.bytesSize() + ", but it's defined as " + keySize);
}
}
}
@ -22,15 +47,39 @@ public record ColumnSchema(int[] keys, int variableLengthKeysCount, boolean hasV
* @return an array with the length of each key, variable-length keys must have the length of their hash
*/
@Override
public int[] keys() {
public IntList keys() {
return keys;
}
/**
* The last n keys that are variable-length
*/
@Override
public int variableLengthKeysCount() {
return variableLengthKeysCount;
return variableTailKeys.size();
}
/**
* The first n keys that are fixed
*/
public int fixedLengthKeysCount() {
return keys.size() - variableTailKeys.size();
}
/**
* The first n keys that are fixed
*/
public int keysCount() {
return keys.size();
}
public int key(int i) {
return keys.getInt(i);
}
/**
* @param absoluteIndex index from the first fixed key
*/
public ColumnHashType variableTailKey(int absoluteIndex) {
return variableTailKeys.get(absoluteIndex - fixedLengthKeysCount());
}
}

View File

@ -0,0 +1,9 @@
package it.cavallium.rockserver.core.common;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
public interface HashFunction {
void hash(MemorySegment inputData, MemorySegment hashResult);
}

View File

@ -5,7 +5,7 @@ public class RocksDBException extends RuntimeException {
private final RocksDBErrorType errorUniqueId;
public enum RocksDBErrorType {
PUT_UNKNOWN_ERROR, PUT_2, UNEXPECTED_NULL_VALUE, PUT_1, PUT_3, GET_1, COLUMN_EXISTS, COLUMN_CREATE_FAIL, COLUMN_NOT_FOUND, COLUMN_DELETE_FAIL, CONFIG_ERROR, ROCKSDB_CONFIG_ERROR, VALUE_MUST_BE_NULL, DIRECTORY_DELETE, KEY_LENGTH_MISMATCH, UNSUPPORTED_HASH_SIZE, RAW_KEY_LENGTH_MISMATCH, KEYS_COUNT_MISMATCH, COMMIT_FAILED_TRY_AGAIN, COMMIT_FAILED, TX_NOT_FOUND, ROCKSDB_LOAD_ERROR
PUT_UNKNOWN_ERROR, PUT_2, UNEXPECTED_NULL_VALUE, PUT_1, PUT_3, GET_1, COLUMN_EXISTS, COLUMN_CREATE_FAIL, COLUMN_NOT_FOUND, COLUMN_DELETE_FAIL, CONFIG_ERROR, ROCKSDB_CONFIG_ERROR, VALUE_MUST_BE_NULL, DIRECTORY_DELETE, KEY_LENGTH_MISMATCH, UNSUPPORTED_HASH_SIZE, RAW_KEY_LENGTH_MISMATCH, KEYS_COUNT_MISMATCH, COMMIT_FAILED_TRY_AGAIN, COMMIT_FAILED, TX_NOT_FOUND, KEY_HASH_SIZE_MISMATCH, ROCKSDB_LOAD_ERROR
}

View File

@ -51,7 +51,7 @@ public class Utils {
}
@NotNull
public static MemorySegment toMemorySegment(byte @Nullable [] array) {
public static MemorySegment toMemorySegment(byte... array) {
if (array != null) {
return MemorySegment.ofArray(array);
} else {
@ -59,6 +59,19 @@ public class Utils {
}
}
@NotNull
public static MemorySegment toMemorySegmentSimple(int... array) {
if (array != null) {
var newArray = new byte[array.length];
for (int i = 0; i < array.length; i++) {
newArray[i] = (byte) array[i];
}
return MemorySegment.ofArray(newArray);
} else {
return MemorySegment.NULL;
}
}
public static byte[] toByteArray(MemorySegment memorySegment) {
return memorySegment.toArray(BIG_ENDIAN_BYTES);
}

View File

@ -1,6 +1,7 @@
package it.cavallium.rockserver.core.impl;
import static it.cavallium.rockserver.core.impl.ColumnInstance.BIG_ENDIAN_INT;
import static it.cavallium.rockserver.core.impl.ColumnInstance.BIG_ENDIAN_INT_UNALIGNED;
import static java.lang.Math.toIntExact;
import it.cavallium.rockserver.core.common.Utils;
@ -122,15 +123,16 @@ public class Bucket {
}
private int indexOf(MemorySegment[] bucketVariableKeys) {
for (int i = 0; i < elements.size(); i++) {
nextElement: for (int i = 0; i < elements.size(); i++) {
var elem = elements.get(i);
var arrayKeys = elem.getKey();
assert arrayKeys.length == bucketVariableKeys.length;
for (int j = 0; j < arrayKeys.length; j++) {
if (Utils.valueEquals(arrayKeys[j], bucketVariableKeys[j])) {
return i;
if (!Utils.valueEquals(arrayKeys[j], bucketVariableKeys[j])) {
continue nextElement;
}
}
return i;
}
return -1;
}
@ -157,7 +159,7 @@ public class Bucket {
offset += Integer.BYTES;
for (MemorySegment elementAtI : serializedElements) {
var elementSize = elementAtI.byteSize();
segment.set(BIG_ENDIAN_INT, offset, toIntExact(elementSize));
segment.set(BIG_ENDIAN_INT_UNALIGNED, offset, toIntExact(elementSize));
offset += Integer.BYTES;
MemorySegment.copy(elementAtI, 0, segment, offset, elementSize);
offset += elementSize;

View File

@ -69,7 +69,7 @@ public record ColumnInstance(ColumnFamilyHandle cfh, ColumnSchema schema, int fi
} else {
finalKey = arena.allocate(finalKeySizeBytes);
long offsetBytes = 0;
for (int i = 0; i < schema.keys().length; i++) {
for (int i = 0; i < schema.keys().size(); i++) {
var computedKeyAtI = computeKeyAt(arena, i, keys);
var computedKeyAtISize = computedKeyAtI.byteSize();
MemorySegment.copy(computedKeyAtI, 0, finalKey, offsetBytes, computedKeyAtISize);
@ -81,20 +81,18 @@ public record ColumnInstance(ColumnFamilyHandle cfh, ColumnSchema schema, int fi
}
private MemorySegment computeKeyAt(Arena arena, int i, MemorySegment[] keys) {
if (i < schema.keys().length - schema.variableLengthKeysCount()) {
if (keys[i].byteSize() != schema.keys()[i]) {
if (i < schema.keys().size() - schema.variableLengthKeysCount()) {
if (keys[i].byteSize() != schema.key(i)) {
throw new RocksDBException(RocksDBErrorType.KEY_LENGTH_MISMATCH,
"Key at index " + i + " has a different length than expected! Expected: " + schema.keys()[i]
"Key at index " + i + " has a different length than expected! Expected: " + schema.key(i)
+ ", received: " + keys[i].byteSize());
}
return keys[i];
} else {
if (schema.keys()[i] != Integer.BYTES) {
throw new RocksDBException(RocksDBErrorType.UNSUPPORTED_HASH_SIZE,
"Hash size different than 32-bit is currently unsupported");
} else {
return XXHash32.getInstance().hash(arena, keys[i], 0, 0, 0);
}
var tailKey = schema.variableTailKey(i);
var hashResult = arena.allocate(tailKey.bytesSize());
tailKey.hash(keys[i], hashResult);
return hashResult;
}
}
@ -107,9 +105,9 @@ public record ColumnInstance(ColumnFamilyHandle cfh, ColumnSchema schema, int fi
}
private void validateKeyCount(MemorySegment[] keys) {
if (schema.keys().length != keys.length) {
if (schema.keys().size() != keys.length) {
throw new RocksDBException(RocksDBErrorType.KEYS_COUNT_MISMATCH,
"Keys count must be equal to the column keys count. Expected: " + schema.keys().length
"Keys count must be equal to the column keys count. Expected: " + schema.keys().size()
+ ", got: " + keys.length);
}
}
@ -172,9 +170,9 @@ public record ColumnInstance(ColumnFamilyHandle cfh, ColumnSchema schema, int fi
* Get only the variable-length keys
*/
public MemorySegment[] getBucketElementKeys(MemorySegment[] keys) {
assert keys.length == schema.keys().length;
assert keys.length == schema.keys().size();
return Arrays.copyOfRange(keys,
schema.keys().length - schema.variableLengthKeysCount(),
schema.keys().length);
schema.keys().size() - schema.variableLengthKeysCount(),
schema.keys().size());
}
}

View File

@ -7,14 +7,11 @@ import static java.util.Objects.requireNonNullElse;
import static org.rocksdb.KeyMayExist.KeyMayExistEnum.kExistsWithValue;
import static org.rocksdb.KeyMayExist.KeyMayExistEnum.kExistsWithoutValue;
import it.cavallium.rockserver.core.common.Callback.CallbackDelta;
import it.cavallium.rockserver.core.common.Callback.CallbackPrevious;
import it.cavallium.rockserver.core.common.Callback.CallbackVoid;
import it.cavallium.rockserver.core.common.Callback;
import it.cavallium.rockserver.core.common.Callback.GetCallback;
import it.cavallium.rockserver.core.common.Callback.IteratorCallback;
import it.cavallium.rockserver.core.common.Callback.PutCallback;
import it.cavallium.rockserver.core.common.ColumnSchema;
import it.cavallium.rockserver.core.common.Callback;
import it.cavallium.rockserver.core.common.Delta;
import it.cavallium.rockserver.core.common.RocksDBAPI;
import it.cavallium.rockserver.core.common.RocksDBException.RocksDBErrorType;
@ -39,20 +36,18 @@ import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.cliffc.high_scale_lib.NonBlockingHashMapLong;
import org.github.gestalt.config.builder.GestaltBuilder;
import org.github.gestalt.config.exceptions.GestaltException;
import org.github.gestalt.config.source.ClassPathConfigSource;
import org.github.gestalt.config.source.ClassPathConfigSourceBuilder;
import org.github.gestalt.config.source.FileConfigSource;
import org.github.gestalt.config.source.FileConfigSourceBuilder;
import org.github.gestalt.config.source.StringConfigSourceBuilder;
import org.jetbrains.annotations.Nullable;
import org.rocksdb.*;
import org.rocksdb.ColumnFamilyDescriptor;
import org.rocksdb.ReadOptions;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;
import org.rocksdb.RocksIterator;
import org.rocksdb.Status.Code;
import org.rocksdb.Transaction;
import org.rocksdb.WriteOptions;
public class EmbeddedDB implements RocksDBAPI, Closeable {

View File

@ -34,7 +34,7 @@ public abstract class XXHash32 {
* Compute the big-endian 32-bits hash of <code>buf[off:off+len]</code> using seed
* <code>seed</code>.
*/
public abstract MemorySegment hash(Arena arena, MemorySegment buf, int off, int len, int seed);
public abstract void hash(MemorySegment buf, int off, int len, int seed, MemorySegment result);
@Override
public String toString() {

View File

@ -36,8 +36,8 @@ public final class XXHash32JavaSafe extends XXHash32 {
public static final ByteOrder NATIVE_BYTE_ORDER = ByteOrder.nativeOrder();
public static final XXHash32 INSTANCE = new XXHash32JavaSafe();
private static final OfInt INT_LE = ValueLayout.JAVA_INT.withOrder(ByteOrder.LITTLE_ENDIAN);
private static final OfInt INT_BE = ValueLayout.JAVA_INT.withOrder(ByteOrder.BIG_ENDIAN);
private static final OfInt INT_LE = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);
private static final OfInt INT_BE = ValueLayout.JAVA_INT_UNALIGNED.withOrder(ByteOrder.BIG_ENDIAN);
private static final OfByte BYTE_BE = ValueLayout.JAVA_BYTE.withOrder(ByteOrder.BIG_ENDIAN);
@Override
@ -104,7 +104,7 @@ public final class XXHash32JavaSafe extends XXHash32 {
}
@Override
public MemorySegment hash(Arena arena, MemorySegment buf, int off, int len, int seed) {
public void hash(MemorySegment buf, int off, int len, int seed, MemorySegment result) {
checkRange(buf, off, len);
final int end = off + len;
@ -163,7 +163,8 @@ public final class XXHash32JavaSafe extends XXHash32 {
h32 *= PRIME3;
h32 ^= h32 >>> 16;
return arena.allocate(INT_BE, h32);
assert result.byteSize() >= Integer.BYTES;
result.set(INT_BE, 0, h32);
}
private static void checkRange(byte[] buf, int off) {

View File

@ -8,6 +8,7 @@ module rockserver.core {
requires high.scale.lib;
requires org.github.gestalt.core;
requires org.github.gestalt.hocon;
requires it.unimi.dsi.fastutil.core;
exports it.cavallium.rockserver.core.client;
exports it.cavallium.rockserver.core.common;

View File

@ -1,20 +1,23 @@
package it.cavallium.rockserver.core.impl.test;
import static it.cavallium.rockserver.core.common.Utils.toMemorySegmentSimple;
import it.cavallium.rockserver.core.client.EmbeddedConnection;
import it.cavallium.rockserver.core.common.Callback;
import it.cavallium.rockserver.core.common.Callback.CallbackDelta;
import it.cavallium.rockserver.core.common.ColumnHashType;
import it.cavallium.rockserver.core.common.ColumnSchema;
import it.cavallium.rockserver.core.common.Utils;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.objects.ObjectList;
import org.junit.jupiter.api.Assertions;
import java.io.IOException;
import java.lang.foreign.MemorySegment;
import java.util.concurrent.atomic.AtomicInteger;
class EmbeddedDBTest {
private EmbeddedConnection db;
private long colId;
private long colId = 0L;
@org.junit.jupiter.api.BeforeEach
void setUp() throws IOException {
@ -22,7 +25,21 @@ class EmbeddedDBTest {
System.setProperty("rockserver.core.print-config", "false");
}
db = new EmbeddedConnection(null, "test", null);
this.colId = db.createColumn("put-1", new ColumnSchema(new int[]{1, 2, 1, Integer.BYTES, Integer.BYTES}, 2, true));
createStandardColumn();
}
private void createStandardColumn() {
createColumn(ColumnSchema.of(IntList.of(1, 2, 1),
ObjectList.of(ColumnHashType.XXHASH32, ColumnHashType.XXHASH32),
true
));
}
private void createColumn(ColumnSchema schema) {
if (colId != 0L) {
db.deleteColumn(colId);
}
colId = db.createColumn("column-test", schema);
}
@org.junit.jupiter.api.AfterEach
@ -32,13 +49,13 @@ class EmbeddedDBTest {
}
@org.junit.jupiter.api.Test
void put() {
void putSameBucketSameKey() {
var key = new MemorySegment[] {
Utils.toMemorySegment(new byte[] {3}),
Utils.toMemorySegment(new byte[] {4, 6}),
Utils.toMemorySegment(new byte[] {3}),
Utils.toMemorySegment(new byte[] {1, 2, 3}),
Utils.toMemorySegment(new byte[] {0, 0, 3, 6, 7, 8})
toMemorySegmentSimple(3),
toMemorySegmentSimple(4, 6),
toMemorySegmentSimple(3),
toMemorySegmentSimple(1, 2, 3),
toMemorySegmentSimple(0, 0, 3, 6, 7, 8)
};
var value1 = MemorySegment.ofArray(new byte[] {0, 0, 3});
var value2 = MemorySegment.ofArray(new byte[] {0, 0, 5});
@ -52,6 +69,101 @@ class EmbeddedDBTest {
Assertions.assertTrue(Utils.valueEquals(delta.current(), value2));
}
@org.junit.jupiter.api.Test
void putSameBucketDifferentKey() {
createColumn(ColumnSchema.of(IntList.of(1, 2, 1), ObjectList.of(ColumnHashType.XXHASH32, ColumnHashType.ALLSAME8), true));
var lastKey1 = toMemorySegmentSimple(6, 7, 8);
var lastKey2 = toMemorySegmentSimple(6, 7, -48);
var key1 = new MemorySegment[] {
toMemorySegmentSimple(3),
toMemorySegmentSimple(4, 6),
toMemorySegmentSimple(3),
toMemorySegmentSimple(1, 2, 3),
lastKey1
};
var key2 = new MemorySegment[] {
toMemorySegmentSimple(3),
toMemorySegmentSimple(4, 6),
toMemorySegmentSimple(3),
toMemorySegmentSimple(1, 2, 3),
lastKey2
};
var value1 = MemorySegment.ofArray(new byte[] {0, 0, 3});
var value2 = MemorySegment.ofArray(new byte[] {0, 0, 5});
var delta = db.put(0, colId, key1, value1, Callback.delta());
Assertions.assertNull(delta.previous());
Assertions.assertTrue(Utils.valueEquals(delta.current(), value1));
delta = db.put(0, colId, key2, value2, Callback.delta());
Assertions.assertNull(delta.previous());
Assertions.assertTrue(Utils.valueEquals(delta.current(), value2));
delta = db.put(0, colId, key2, value1, Callback.delta());
Assertions.assertTrue(Utils.valueEquals(delta.previous(), value2));
Assertions.assertTrue(Utils.valueEquals(delta.current(), value1));
}
/**
* Some keys have same bucket, some not
*/
@org.junit.jupiter.api.Test
void putMixedBucketMixedKey() {
createColumn(ColumnSchema.of(IntList.of(1, 2, 1), ObjectList.of(ColumnHashType.XXHASH32, ColumnHashType.XXHASH8), true));
var lastKey1 = toMemorySegmentSimple(6, 7, 8);
var collidingLastKey1 = toMemorySegmentSimple(6, 7, -48);
var lastKey2 = toMemorySegmentSimple(6, 7, 7);
var key1 = new MemorySegment[] {
toMemorySegmentSimple(3),
toMemorySegmentSimple(4, 6),
toMemorySegmentSimple(3),
toMemorySegmentSimple(1, 2, 3),
lastKey1
};
var collidingKey1 = new MemorySegment[] {
toMemorySegmentSimple(3),
toMemorySegmentSimple(4, 6),
toMemorySegmentSimple(3),
toMemorySegmentSimple(1, 2, 3),
collidingLastKey1
};
var key2 = new MemorySegment[] {
toMemorySegmentSimple(3),
toMemorySegmentSimple(4, 6),
toMemorySegmentSimple(3),
toMemorySegmentSimple(1, 2, 3),
lastKey2
};
var value1 = MemorySegment.ofArray(new byte[] {0, 0, 3});
var value2 = MemorySegment.ofArray(new byte[] {0, 0, 5});
var delta = db.put(0, colId, key1, value1, Callback.delta());
Assertions.assertNull(delta.previous());
Assertions.assertTrue(Utils.valueEquals(delta.current(), value1));
delta = db.put(0, colId, collidingKey1, value2, Callback.delta());
Assertions.assertNull(delta.previous());
Assertions.assertTrue(Utils.valueEquals(delta.current(), value2));
delta = db.put(0, colId, collidingKey1, value1, Callback.delta());
Assertions.assertTrue(Utils.valueEquals(delta.previous(), value2));
Assertions.assertTrue(Utils.valueEquals(delta.current(), value1));
delta = db.put(0, colId, key2, value1, Callback.delta());
Assertions.assertNull(delta.previous());
Assertions.assertTrue(Utils.valueEquals(delta.current(), value1));
delta = db.put(0, colId, key2, value2, Callback.delta());
Assertions.assertTrue(Utils.valueEquals(delta.previous(), value1));
Assertions.assertTrue(Utils.valueEquals(delta.current(), value2));
}
@org.junit.jupiter.api.Test
void get() {
throw new UnsupportedOperationException();

View File

@ -26,7 +26,8 @@ public class XXHash32Test {
ThreadLocalRandom.current().nextBytes(bytes);
var hash = safeXxhash32.hash(bytes, 0, bytes.length, Integer.MIN_VALUE);
var a = Arena.global();
var result = myXxhash32.hash(a, a.allocateArray(OfByte.JAVA_BYTE, bytes), 0, bytes.length, Integer.MIN_VALUE);
var result = a.allocate(Integer.BYTES);
myXxhash32.hash(a.allocateArray(OfByte.JAVA_BYTE, bytes), 0, bytes.length, Integer.MIN_VALUE, result);
var resultInt = result.get(ColumnInstance.BIG_ENDIAN_INT, 0);
Assertions.assertEquals(hash, resultInt);
}

View File

@ -2,6 +2,7 @@ module rockserver.core.test {
requires org.lz4.java;
requires rockserver.core;
requires org.junit.jupiter.api;
requires it.unimi.dsi.fastutil.core;
opens it.cavallium.rockserver.core.test;
opens it.cavallium.rockserver.core.impl.test;
}