Make it work on graalvm

This commit is contained in:
Andrea Cavalli 2023-12-06 01:31:02 +01:00
parent 584aed3063
commit 9a360c2440
12 changed files with 238 additions and 119 deletions

11
pom.xml
View File

@ -193,12 +193,19 @@
<enabled>true</enabled> <enabled>true</enabled>
</agent> </agent>
<buildArgs> <buildArgs>
<buildArg>-H:+UnlockExperimentalVMOptions</buildArg>
<buildArg>--strict-image-heap</buildArg> <buildArg>--strict-image-heap</buildArg>
<buildArg>-march=native</buildArg> <buildArg>-march=native</buildArg>
<buildArg>-H:IncludeResourceBundles=net.sourceforge.argparse4j.internal.ArgumentParserImpl-en_US</buildArg> <buildArg>-H:IncludeResourceBundles=net.sourceforge.argparse4j.internal.ArgumentParserImpl</buildArg>
<buildArg>-O1</buildArg> <buildArg>-O1</buildArg>
<buildArg>--enable-preview</buildArg> <buildArg>--enable-preview</buildArg>
<buildArg>--no-fallback</buildArg> <buildArg>-H:+StaticExecutableWithDynamicLibC</buildArg>
<buildArg>-H:+JNI</buildArg>
<buildArg>-H:IncludeResources=librocksdbjni-linux64.so</buildArg>
<buildArg>-H:IncludeResources=it/cavallium/rockserver/core/resources/default.conf</buildArg>
<buildArg>-H:DynamicProxyConfigurationFiles=proxy-config.json</buildArg>
<buildArg>--delay-class-initialization-to-runtime=org.rocksdb.RocksDB,org.rocksdb.RocksObject</buildArg>
<!--<buildArg>_-no-fallback</buildArg>-->
<buildArg>--gc=G1</buildArg> <buildArg>--gc=G1</buildArg>
</buildArgs> </buildArgs>
</configuration> </configuration>

50
proxy-config.json Normal file
View File

@ -0,0 +1,50 @@
[
{
"condition": {
"typeReachable": "org.github.gestalt.config.decoder.ProxyDecoder"
},
"interfaces": [
"it.cavallium.rockserver.core.config.DatabaseConfig"
]
},
{
"condition": {
"typeReachable": "org.github.gestalt.config.decoder.ProxyDecoder"
},
"interfaces": [
"it.cavallium.rockserver.core.config.GlobalDatabaseConfig"
]
},
{
"condition": {
"typeReachable": "org.github.gestalt.config.decoder.ProxyDecoder"
},
"interfaces": [
"it.cavallium.rockserver.core.config.FallbackColumnOptions"
]
},
{
"condition": {
"typeReachable": "org.github.gestalt.config.decoder.ProxyDecoder"
},
"interfaces": [
"it.cavallium.rockserver.core.config.NamedColumnOptions"
]
},
{
"condition": {
"typeReachable": "org.github.gestalt.config.decoder.ProxyDecoder"
},
"interfaces": [
"it.cavallium.rockserver.core.config.BloomFilterConfig"
]
},
{
"condition": {
"typeReachable": "org.github.gestalt.config.decoder.ProxyDecoder"
},
"interfaces": [
"it.cavallium.rockserver.core.config.DatabaseLevel"
]
}
]

View File

@ -6,12 +6,4 @@ public interface BloomFilterConfig {
boolean optimizeForHits(); boolean optimizeForHits();
static String stringify(BloomFilterConfig o) {
return """
{
"bits-per-key": %d,
"optimize-for-hits": %b
}\
""".formatted(o.bitsPerKey(), o.optimizeForHits());
}
} }

View File

@ -0,0 +1,111 @@
package it.cavallium.rockserver.core.config;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class ConfigPrinter {
public static String stringifyBloomFilter(BloomFilterConfig o) {
return """
{
"bits-per-key": %d,
"optimize-for-hits": %b
}\
""".formatted(o.bitsPerKey(), o.optimizeForHits());
}
public static String stringifyDatabase(DatabaseConfig o) {
return """
{
"global": %s
}""".formatted(stringifyGlobalDatabase(o.global()));
}
public static String stringifyLevel(DatabaseLevel o) {
return """
{
"compression": "%s",
"max-dict-bytes": "%s"
}\
""".formatted(o.compression(), o.maxDictBytes());
}
public static String stringifyFallbackColumn(FallbackColumnOptions o) {
return """
{
"levels": %s,
"memtable-memory-budget-bytes": "%s",
"cache-index-and-filter-blocks": %b,
"partition-filters": %s,
"bloom-filter": %s,
"block-size": "%s",
"write-buffer-size": "%s"
}\
""".formatted(Arrays.stream(Objects.requireNonNullElse(o.levels(), new DatabaseLevel[0]))
.map(ConfigPrinter::stringifyLevel).collect(Collectors.joining(",", "[", "]")),
o.memtableMemoryBudgetBytes(),
o.cacheIndexAndFilterBlocks(),
o.partitionFilters(),
stringifyBloomFilter(o.bloomFilter()),
o.blockSize(),
o.writeBufferSize()
);
}
public static String stringifyGlobalDatabase(GlobalDatabaseConfig o) {
return """
{
"spinning": %b,
"checksum": %b,
"use-direct-io": %b,
"allow-rocksdb-memory-mapping": %b,
"maximum-open-files": %d,
"optimistic": %b,
"block-cache": "%s",
"write-buffer-manager": "%s",
"log-path": "%s",
"fallback-column-options": %s,
"column-options": %s
}\
""".formatted(o.spinning(),
o.checksum(),
o.useDirectIo(),
o.allowRocksdbMemoryMapping(),
o.maximumOpenFiles(),
o.optimistic(),
o.blockCache(),
o.writeBufferManager(),
o.logPath(),
stringifyFallbackColumn(o.fallbackColumnOptions()),
Arrays.stream(Objects.requireNonNullElse(o.columnOptions(), new NamedColumnOptions[0]))
.map(ConfigPrinter::stringifyNamedColumn)
.collect(Collectors.joining(",", "[", "]"))
);
}
public static String stringifyNamedColumn(NamedColumnOptions o) {
return """
{
"name": "%s",
"levels": %s,
"memtable-memory-budget-bytes": "%s",
"cache-index-and-filter-blocks": %b,
"partition-filters": %s,
"bloom-filter": %s,
"block-size": "%s",
"write-buffer-size": "%s"
}\
""".formatted(o.name(),
(o.levels() != null ? List.of(o.levels()) : List.<DatabaseLevel>of()).stream()
.map(ConfigPrinter::stringifyLevel).collect(Collectors.joining(",", "[", "]")),
o.memtableMemoryBudgetBytes(),
o.cacheIndexAndFilterBlocks(),
o.partitionFilters(),
stringifyBloomFilter(o.bloomFilter()),
o.blockSize(),
o.writeBufferSize()
);
}
}

View File

@ -1,11 +1,23 @@
package it.cavallium.rockserver.core.config; package it.cavallium.rockserver.core.config;
import org.rocksdb.CompressionType;
public enum DatabaseCompression { public enum DatabaseCompression {
PLAIN, PLAIN(CompressionType.NO_COMPRESSION),
SNAPPY, SNAPPY(CompressionType.SNAPPY_COMPRESSION),
LZ4, LZ4(CompressionType.LZ4_COMPRESSION),
LZ4_HC, LZ4_HC(CompressionType.LZ4HC_COMPRESSION),
ZSTD, ZSTD(CompressionType.ZSTD_COMPRESSION),
ZLIB, ZLIB(CompressionType.ZLIB_COMPRESSION),
BZLIB2 BZLIB2(CompressionType.BZLIB2_COMPRESSION);
private final CompressionType compressionType;
DatabaseCompression(CompressionType compressionType) {
this.compressionType = compressionType;
}
public CompressionType compressionType() {
return compressionType;
}
} }

View File

@ -4,10 +4,4 @@ public interface DatabaseConfig {
GlobalDatabaseConfig global(); GlobalDatabaseConfig global();
static String stringify(DatabaseConfig o) {
return """
{
"global": %s
}""".formatted(GlobalDatabaseConfig.stringify(o.global()));
}
} }

View File

@ -1,17 +1,11 @@
package it.cavallium.rockserver.core.config; package it.cavallium.rockserver.core.config;
import org.rocksdb.CompressionType;
public interface DatabaseLevel { public interface DatabaseLevel {
DatabaseCompression compression(); CompressionType compression();
DataSize maxDictBytes(); DataSize maxDictBytes();
static String stringify(DatabaseLevel o) {
return """
{
"compression": "%s",
"max-dict-bytes": "%s"
}\
""".formatted(o.compression(), o.maxDictBytes());
}
} }

View File

@ -1,9 +1,5 @@
package it.cavallium.rockserver.core.config; package it.cavallium.rockserver.core.config;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;
public interface FallbackColumnOptions { public interface FallbackColumnOptions {
DatabaseLevel[] levels(); DatabaseLevel[] levels();
@ -20,25 +16,4 @@ public interface FallbackColumnOptions {
DataSize writeBufferSize(); DataSize writeBufferSize();
static String stringify(FallbackColumnOptions o) {
return """
{
"levels": %s,
"memtable-memory-budget-bytes": "%s",
"cache-index-and-filter-blocks": %b,
"partition-filters": %s,
"bloom-filter": %s,
"block-size": "%s",
"write-buffer-size": "%s"
}\
""".formatted(Arrays.stream(Objects.requireNonNullElse(o.levels(), new DatabaseLevel[0]))
.map(DatabaseLevel::stringify).collect(Collectors.joining(",", "[", "]")),
o.memtableMemoryBudgetBytes(),
o.cacheIndexAndFilterBlocks(),
o.partitionFilters(),
BloomFilterConfig.stringify(o.bloomFilter()),
o.blockSize(),
o.writeBufferSize()
);
}
} }

View File

@ -1,9 +1,6 @@
package it.cavallium.rockserver.core.config; package it.cavallium.rockserver.core.config;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Collectors;
public interface GlobalDatabaseConfig { public interface GlobalDatabaseConfig {
@ -28,34 +25,4 @@ public interface GlobalDatabaseConfig {
FallbackColumnOptions fallbackColumnOptions(); FallbackColumnOptions fallbackColumnOptions();
NamedColumnOptions[] columnOptions(); NamedColumnOptions[] columnOptions();
static String stringify(GlobalDatabaseConfig o) {
return """
{
"spinning": %b,
"checksum": %b,
"use-direct-io": %b,
"allow-rocksdb-memory-mapping": %b,
"maximum-open-files": %d,
"optimistic": %b,
"block-cache": "%s",
"write-buffer-manager": "%s",
"log-path": "%s",
"fallback-column-options": %s,
"column-options": %s
}\
""".formatted(o.spinning(),
o.checksum(),
o.useDirectIo(),
o.allowRocksdbMemoryMapping(),
o.maximumOpenFiles(),
o.optimistic(),
o.blockCache(),
o.writeBufferManager(),
o.logPath(),
FallbackColumnOptions.stringify(o.fallbackColumnOptions()),
Arrays.stream(Objects.requireNonNullElse(o.columnOptions(), new NamedColumnOptions[0]))
.map(NamedColumnOptions::stringify)
.collect(Collectors.joining(",", "[", "]"))
);
}
} }

View File

@ -1,35 +1,7 @@
package it.cavallium.rockserver.core.config; package it.cavallium.rockserver.core.config;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public interface NamedColumnOptions extends FallbackColumnOptions { public interface NamedColumnOptions extends FallbackColumnOptions {
String name(); String name();
static String stringify(NamedColumnOptions o) {
return """
{
"name": "%s",
"levels": %s,
"memtable-memory-budget-bytes": "%s",
"cache-index-and-filter-blocks": %b,
"partition-filters": %s,
"bloom-filter": %s,
"block-size": "%s",
"write-buffer-size": "%s"
}\
""".formatted(o.name(),
(o.levels() != null ? List.of(o.levels()) : List.<DatabaseLevel>of()).stream()
.map(DatabaseLevel::stringify).collect(Collectors.joining(",", "[", "]")),
o.memtableMemoryBudgetBytes(),
o.cacheIndexAndFilterBlocks(),
o.partitionFilters(),
BloomFilterConfig.stringify(o.bloomFilter()),
o.blockSize(),
o.writeBufferSize()
);
}
} }

View File

@ -0,0 +1,43 @@
package it.cavallium.rockserver.core.impl;
import it.cavallium.rockserver.core.config.DataSize;
import it.cavallium.rockserver.core.config.DatabaseCompression;
import java.util.List;
import org.github.gestalt.config.decoder.Decoder;
import org.github.gestalt.config.decoder.DecoderService;
import org.github.gestalt.config.decoder.Priority;
import org.github.gestalt.config.entity.ValidationError;
import org.github.gestalt.config.node.ConfigNode;
import org.github.gestalt.config.reflect.TypeCapture;
import org.github.gestalt.config.utils.ValidateOf;
import org.rocksdb.CompressionType;
public class DbCompressionDecoder implements Decoder<CompressionType> {
@Override
public Priority priority() {
return Priority.HIGH;
}
@Override
public String name() {
return "DbCompression";
}
@Override
public boolean matches(TypeCapture<?> klass) {
return klass.isAssignableFrom(CompressionType.class);
}
@Override
public ValidateOf<CompressionType> decode(String path,
ConfigNode node,
TypeCapture<?> type,
DecoderService decoderService) {
try {
return ValidateOf.validateOf(DatabaseCompression.valueOf(node.getValue().orElseThrow()).compressionType(), List.of());
} catch (Exception ex) {
return ValidateOf.inValid(new ValidationError.DecodingNumberFormatException(path, node, name()));
}
}
}

View File

@ -16,6 +16,7 @@ import it.cavallium.rockserver.core.common.Delta;
import it.cavallium.rockserver.core.common.RocksDBAPI; import it.cavallium.rockserver.core.common.RocksDBAPI;
import it.cavallium.rockserver.core.common.RocksDBException.RocksDBErrorType; import it.cavallium.rockserver.core.common.RocksDBException.RocksDBErrorType;
import it.cavallium.rockserver.core.common.Utils; import it.cavallium.rockserver.core.common.Utils;
import it.cavallium.rockserver.core.config.ConfigPrinter;
import it.cavallium.rockserver.core.config.DatabaseConfig; import it.cavallium.rockserver.core.config.DatabaseConfig;
import it.cavallium.rockserver.core.impl.rocksdb.REntry; import it.cavallium.rockserver.core.impl.rocksdb.REntry;
import it.cavallium.rockserver.core.impl.rocksdb.RocksDBObjects; import it.cavallium.rockserver.core.impl.rocksdb.RocksDBObjects;
@ -80,13 +81,14 @@ public class EmbeddedDB implements RocksDBAPI, Closeable {
} }
var gestalt = gsb var gestalt = gsb
.addDecoder(new DataSizeDecoder()) .addDecoder(new DataSizeDecoder())
.addDecoder(new DbCompressionDecoder())
.addDefaultConfigLoaders() .addDefaultConfigLoaders()
.addDefaultDecoders() .addDefaultDecoders()
.build(); .build();
gestalt.loadConfigs(); gestalt.loadConfigs();
this.config = gestalt.getConfig("database", DatabaseConfig.class); this.config = gestalt.getConfig("database", DatabaseConfig.class);
logger.log(Level.INFO, "Database configuration: {0}", DatabaseConfig.stringify(this.config)); logger.log(Level.INFO, "Database configuration: {0}", ConfigPrinter.stringifyDatabase(this.config));
} catch (GestaltException e) { } catch (GestaltException e) {
throw new it.cavallium.rockserver.core.common.RocksDBException(RocksDBErrorType.CONFIG_ERROR, e); throw new it.cavallium.rockserver.core.common.RocksDBException(RocksDBErrorType.CONFIG_ERROR, e);
} }