CavalliumDBEngine/src/test/java/it/cavallium/dbengine/DbTestUtils.java

163 lines
5.6 KiB
Java
Raw Normal View History

2021-05-02 19:18:15 +02:00
package it.cavallium.dbengine;
2021-05-03 18:07:18 +02:00
import io.netty.buffer.ByteBuf;
2021-05-04 01:21:29 +02:00
import io.netty.buffer.ByteBufAllocator;
2021-05-03 18:07:18 +02:00
import io.netty.buffer.PooledByteBufAllocator;
import it.cavallium.dbengine.database.Column;
import it.cavallium.dbengine.database.LLDictionary;
import it.cavallium.dbengine.database.LLKeyValueDatabase;
import it.cavallium.dbengine.database.UpdateMode;
import it.cavallium.dbengine.database.collections.DatabaseMapDictionary;
import it.cavallium.dbengine.database.collections.DatabaseMapDictionaryDeep;
import it.cavallium.dbengine.database.collections.DatabaseMapDictionaryHashed;
2021-05-03 18:07:18 +02:00
import it.cavallium.dbengine.database.collections.DatabaseStageEntry;
import it.cavallium.dbengine.database.collections.DatabaseStageMap;
import it.cavallium.dbengine.database.collections.SubStageGetterHashMap;
import it.cavallium.dbengine.database.collections.SubStageGetterMap;
import it.cavallium.dbengine.database.disk.LLLocalDatabaseConnection;
import it.cavallium.dbengine.database.serialization.Serializer;
import it.cavallium.dbengine.database.serialization.SerializerFixedBinaryLength;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletionException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
2021-05-03 18:07:18 +02:00
import org.jetbrains.annotations.NotNull;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;
public class DbTestUtils {
2021-05-04 01:21:29 +02:00
public static final ByteBufAllocator ALLOCATOR = new PooledByteBufAllocator(true);
public static final AtomicInteger dbId = new AtomicInteger(0);
public static <U> Flux<U> tempDb(Function<LLKeyValueDatabase, Publisher<U>> action) {
var wrkspcPath = Path.of("/tmp/.cache/tempdb-" + dbId.incrementAndGet() + "/");
return Flux.usingWhen(Mono
.<LLKeyValueDatabase>fromCallable(() -> {
if (Files.exists(wrkspcPath)) {
Files.walk(wrkspcPath).sorted(Comparator.reverseOrder()).forEach(file -> {
try {
Files.delete(file);
} catch (IOException ex) {
throw new CompletionException(ex);
}
});
}
Files.createDirectories(wrkspcPath);
return null;
})
.subscribeOn(Schedulers.boundedElastic())
2021-05-04 01:21:29 +02:00
.then(new LLLocalDatabaseConnection(DbTestUtils.ALLOCATOR, wrkspcPath, true).connect())
.flatMap(conn -> conn.getDatabase("testdb",
List.of(Column.dictionary("testmap"), Column.special("ints"), Column.special("longs")),
false, true
)),
action,
db -> db.close().then(Mono.fromCallable(() -> {
if (Files.exists(wrkspcPath)) {
Files.walk(wrkspcPath).sorted(Comparator.reverseOrder()).forEach(file -> {
try {
Files.delete(file);
} catch (IOException ex) {
throw new CompletionException(ex);
}
});
}
return null;
}).subscribeOn(Schedulers.boundedElastic()))
);
}
2021-05-02 19:18:15 +02:00
public static Mono<? extends LLDictionary> tempDictionary(LLKeyValueDatabase database, UpdateMode updateMode) {
return tempDictionary(database, "testmap", updateMode);
}
public static Mono<? extends LLDictionary> tempDictionary(LLKeyValueDatabase database,
String name,
UpdateMode updateMode) {
return database.getDictionary(name, updateMode);
}
2021-05-03 18:07:18 +02:00
public enum DbType {
MAP,
HASH_MAP
}
public static DatabaseStageMap<String, String, DatabaseStageEntry<String>> tempDatabaseMapDictionaryMap(
LLDictionary dictionary,
2021-05-03 18:07:18 +02:00
DbType dbType,
int keyBytes) {
2021-05-04 01:21:29 +02:00
if (dbType == DbType.MAP) {
2021-05-03 21:41:51 +02:00
return DatabaseMapDictionary.simple(dictionary,
2021-05-04 01:21:29 +02:00
SerializerFixedBinaryLength.utf8(DbTestUtils.ALLOCATOR, keyBytes),
Serializer.utf8(DbTestUtils.ALLOCATOR)
2021-05-03 21:41:51 +02:00
);
2021-05-03 18:07:18 +02:00
} else {
return DatabaseMapDictionaryHashed.simple(dictionary,
2021-05-04 01:21:29 +02:00
SerializerFixedBinaryLength.utf8(DbTestUtils.ALLOCATOR, keyBytes),
Serializer.utf8(DbTestUtils.ALLOCATOR),
2021-05-03 18:07:18 +02:00
String::hashCode,
new SerializerFixedBinaryLength<>() {
@Override
public int getSerializedBinaryLength() {
return keyBytes;
}
@Override
public @NotNull Integer deserialize(@NotNull ByteBuf serialized) {
try {
2021-05-04 01:21:29 +02:00
var prevReaderIdx = serialized.readerIndex();
2021-05-03 18:07:18 +02:00
var val = serialized.readInt();
2021-05-04 01:21:29 +02:00
serialized.readerIndex(prevReaderIdx + keyBytes);
2021-05-03 18:07:18 +02:00
return val;
} finally {
serialized.release();
}
}
@Override
public @NotNull ByteBuf serialize(@NotNull Integer deserialized) {
2021-05-04 01:21:29 +02:00
var out = DbTestUtils.ALLOCATOR.directBuffer(keyBytes);
2021-05-03 18:07:18 +02:00
try {
out.writeInt(deserialized);
out.writerIndex(keyBytes);
return out.retain();
} finally {
out.release();
}
}
}
);
}
}
public static <T, U> DatabaseMapDictionaryDeep<String, Map<String, String>, DatabaseMapDictionary<String, String>> tempDatabaseMapDictionaryDeepMap(
LLDictionary dictionary,
int key1Bytes,
int key2Bytes) {
return DatabaseMapDictionaryDeep.deepTail(dictionary,
2021-05-04 01:21:29 +02:00
SerializerFixedBinaryLength.utf8(DbTestUtils.ALLOCATOR, key1Bytes),
key2Bytes,
2021-05-04 01:21:29 +02:00
new SubStageGetterMap<>(SerializerFixedBinaryLength.utf8(DbTestUtils.ALLOCATOR, key2Bytes), Serializer.utf8(DbTestUtils.ALLOCATOR))
);
}
public static <T, U> DatabaseMapDictionaryHashed<String, String, Integer> tempDatabaseMapDictionaryHashMap(
LLDictionary dictionary) {
return DatabaseMapDictionaryHashed.simple(dictionary,
2021-05-04 01:21:29 +02:00
Serializer.utf8(DbTestUtils.ALLOCATOR),
Serializer.utf8(DbTestUtils.ALLOCATOR),
String::hashCode,
2021-05-04 01:21:29 +02:00
SerializerFixedBinaryLength.intSerializer(DbTestUtils.ALLOCATOR)
);
}
}