BlockComponentsToSave class
Пакет: com.hypixel.hytale.server.core.universe.world.storage.provider
Файл: com/hypixel/hytale/server/core/universe/world/storage/provider/RocksDbChunkStorageProvider.java
Поля (7)
| Модификаторы | Тип | Имя |
|---|---|---|
|
private final ShortArrayList |
deletes |
|
private final ShortSet |
dirty |
|
private final ObjectArrayList<Holder<ChunkStore>> |
putHolders |
|
private final ShortArrayList |
putIndexes |
|
private ShortSet |
removed |
|
private final boolean |
replaceAll |
|
private final BlockComponentSection |
section |
Методы (4)
| Модификаторы | Возврат | Сигнатура |
|---|---|---|
|
private void |
deleteDirtyIndexprivate void deleteDirtyIndex(short var1) |
|
|
if if(this.removed == null) |
|
|
if if(this.section != null) |
|
private void |
restoreprivate void restore() |
Исходный код
Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.universe.world.storage.provider;
class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.component.ComponentRegistry;
class="kw">import com.hypixel.hytale.component.Holder;
class="kw">import com.hypixel.hytale.component.Ref;
class="kw">import com.hypixel.hytale.component.Store;
class="kw">import com.hypixel.hytale.lib.rocksdb.RocksDbNative;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.math.util.ChunkUtil;
class="kw">import com.hypixel.hytale.metrics.BucketedOpStats;
class="kw">import com.hypixel.hytale.metrics.MetricProvider;
class="kw">import com.hypixel.hytale.metrics.MetricResults;
class="kw">import com.hypixel.hytale.metrics.MetricsRegistry;
class="kw">import com.hypixel.hytale.server.core.entity.Dirty;
class="kw">import com.hypixel.hytale.server.core.entity.UUIDComponent;
class="kw">import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.BlockComponentChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.ChunkColumn;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.ChunkFlag;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.EntityChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.WorldChunk;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockComponentSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.ChunkSection;
class="kw">import com.hypixel.hytale.server.core.universe.world.chunk.section.EntitySection;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.IChunkLoader;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.IChunkSaver;
class="kw">import com.hypixel.hytale.server.core.universe.world.storage.component.ChunkSavingSystems;
class="kw">import com.hypixel.hytale.server.core.util.BsonUtil;
class="kw">import com.hypixel.hytale.server.core.util.io.FileUtil;
class="kw">import com.hypixel.hytale.server.core.util.io.MemorySegmentUtil;
class="kw">import com.hypixel.hytale.sneakythrow.SneakyThrow;
class="kw">import it.unimi.dsi.fastutil.longs.LongArrayList;
class="kw">import it.unimi.dsi.fastutil.longs.LongList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectArrayList;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectIterator;
class="kw">import it.unimi.dsi.fastutil.objects.ObjectListIterator;
class="kw">import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
class="kw">import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.shorts.ShortArrayList;
class="kw">import it.unimi.dsi.fastutil.shorts.ShortIterator;
class="kw">import it.unimi.dsi.fastutil.shorts.ShortOpenHashSet;
class="kw">import it.unimi.dsi.fastutil.shorts.ShortSet;
class="kw">import it.unimi.dsi.fastutil.shorts.Short2ObjectMap.Entry;
class="kw">import java.io.IOException;
class="kw">import java.lang.foreign.Arena;
class="kw">import java.lang.foreign.MemorySegment;
class="kw">import java.lang.foreign.ValueLayout;
class="kw">import java.nio.ByteBuffer;
class="kw">import java.util.Arrays;
class="kw">import java.util.Iterator;
class="kw">import java.util.List;
class="kw">import java.util.Set;
class="kw">import java.util.UUID;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.ConcurrentHashMap;
class="kw">import java.util.concurrent.Executor;
class="kw">import java.util.concurrent.ExecutorService;
class="kw">import java.util.concurrent.Executors;
class="kw">import java.util.concurrent.ForkJoinPool;
class="kw">import java.util.concurrent.RejectedExecutionException;
class="kw">import java.util.concurrent.TimeUnit;
class="kw">import java.util.concurrent.atomic.AtomicInteger;
class="kw">import java.util.concurrent.atomic.AtomicLong;
class="kw">import java.util.function.BiConsumer;
class="kw">import java.util.function.IntFunction;
class="kw">import java.util.function.Supplier;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;
class="kw">import org.bson.BsonDocument;
class="kw">import org.bson.io.BasicOutputBuffer;
class="kw">import org.checkerframework.checker.nullness.compatqual.NonNullDecl;
class="kw">public class RocksDbChunkStorageProvider class="kw">implements IChunkStorageProvider<RocksDbChunkStorageProvider.RocksDbResource> {
@Nonnull
class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
class="kw">public class="kw">static class="kw">final String ID = "RocksDb";
class="kw">public class="kw">static class="kw">final BuilderCodec<RocksDbChunkStorageProvider> CODEC = BuilderCodec.builder(
RocksDbChunkStorageProvider.class, RocksDbChunkStorageProvider::new
)
.build();
class="kw">public class="kw">static class="kw">final String STATISTICS_PROPERTY = "hytale.rocksdb.stats";
class="kw">public class="kw">static class="kw">final String BLOB_GC_AGE_CUTOFF_PROPERTY = "hytale.rocksdb.blob_gc_age_cutoff";
class="kw">public class="kw">static class="kw">final String BLOB_GC_FORCE_THRESHOLD_PROPERTY = "hytale.rocksdb.blob_gc_force_threshold";
class="kw">public class="kw">static class="kw">final String BLOB_COMPACTION_READAHEAD_SIZE_PROPERTY = "hytale.rocksdb.blob_compaction_readahead_size";
class="kw">public class="kw">static class="kw">final String MIN_BLOB_SIZE_PROPERTY = "hytale.rocksdb.min_blob_size";
class="kw">public class="kw">static class="kw">final String BLOB_CACHE_SIZE_PROPERTY = "hytale.rocksdb.blob_cache_size";
class="kw">public class="kw">static class="kw">final String IO_THREADS_PROPERTY = "hytale.rocksdb.io_threads";
class="kw">private class="kw">static class="kw">final double BLOB_GC_AGE_CUTOFF = parseDoubleProperty("hytale.rocksdb.blob_gc_age_cutoff", 0.25);
class="kw">private class="kw">static class="kw">final double BLOB_GC_FORCE_THRESHOLD = parseDoubleProperty("hytale.rocksdb.blob_gc_force_threshold", 0.75);
class="kw">private class="kw">static class="kw">final long BLOB_COMPACTION_READAHEAD_BYTES = parseLongProperty("hytale.rocksdb.blob_compaction_readahead_size", 2097152L);
class="kw">private class="kw">static class="kw">final long MIN_BLOB_SIZE_BYTES = parseLongProperty("hytale.rocksdb.min_blob_size", 4096L);
class="kw">private class="kw">static class="kw">final long BLOCK_CACHE_BYTES = 134217728L;
class="kw">private class="kw">static class="kw">final long BLOB_CACHE_BYTES = parseLongProperty("hytale.rocksdb.blob_cache_size", 0L);
class="kw">private class="kw">static class="kw">final long CHUNK_LEVEL_COMPACTION_BUDGET = 33554432L;
class="kw">private class="kw">static class="kw">final long SECTION_LEVEL_COMPACTION_BUDGET = 67108864L;
class="kw">private class="kw">static class="kw">final long ENTITY_SECTION_LEVEL_COMPACTION_BUDGET = 8388608L;
class="kw">private class="kw">static class="kw">final long ENTITY_LEVEL_COMPACTION_BUDGET = 16777216L;
class="kw">private class="kw">static class="kw">final long BLOCK_COMPONENT_LEVEL_COMPACTION_BUDGET = 8388608L;
class="kw">private class="kw">static class="kw">final double BLOOM_BITS_PER_KEY = 9.9;
class="kw">private class="kw">static class="kw">final int IO_THREADS = Math.max(1, parseIntProperty("hytale.rocksdb.io_threads", 4));
class="kw">private class="kw">static class="kw">final AtomicInteger IO_THREAD_COUNTER = new AtomicInteger();
class="kw">private class="kw">static class="kw">final int CHUNK_KEY_BYTES = 8;
class="kw">private class="kw">static class="kw">final int SECTION_KEY_BYTES = 12;
class="kw">private class="kw">static class="kw">final int ENTITY_KEY_BYTES = 16;
class="kw">private class="kw">static class="kw">final int BLOCK_COMPONENT_KEY_BYTES = 14;
class="kw">private class="kw">static class="kw">final long MAX_ENTITIES_PER_SECTION = 65536L;
class="kw">private class="kw">static class="kw">final long MAX_ROW_BYTES = 268435456L;
class="kw">private class="kw">static class="kw">final ThreadLocal<RocksDbChunkStorageProvider.Scratch> SCRATCH = ThreadLocal.withInitial(RocksDbChunkStorageProvider.Scratch::new);
class="kw">public RocksDbChunkStorageProvider() {
}
@Nullable
class="kw">private class="kw">static String rawProperty(@Nonnull String var0) {
String var1 = System.getProperty(var0);
class="kw">return var1 != null && !var1.isBlank() ? var1.trim() : null;
}
class="kw">private class="kw">static double parseDoubleProperty(@Nonnull String var0, double var1) {
String var3 = rawProperty(var0);
class="kw">return var3 == null ? var1 : Double.parseDouble(var3);
}
class="kw">private class="kw">static long parseLongProperty(@Nonnull String var0, long var1) {
String var3 = rawProperty(var0);
class="kw">return var3 == null ? var1 : Long.parseLong(var3);
}
class="kw">private class="kw">static int parseIntProperty(@Nonnull String var0, int var1) {
String var2 = rawProperty(var0);
class="kw">return var2 == null ? var1 : Integer.parseInt(var2);
}
class="kw">public RocksDbChunkStorageProvider.RocksDbResource initialize(@NonNullDecl Store<ChunkStore> var1) class="kw">throws IOException {
RocksDbChunkStorageProvider.RocksDbResource var2 = new RocksDbChunkStorageProvider.RocksDbResource();
var2.statisticsEnabled = Boolean.getBoolean("hytale.rocksdb.stats");
MemorySegment var3 = RocksDbNative.cacheCreateLru(134217728L);
var2.blockCache = var3;
MemorySegment var4 = BLOB_CACHE_BYTES > 0L ? RocksDbNative.cacheCreateLru(BLOB_CACHE_BYTES) : MemorySegment.NULL;
var2.blobCache = var4;
MemorySegment var5 = RocksDbNative.optionsCreate();
var2.options = var5;
RocksDbNative.optionsSetCreateIfMissing(var5, true);
RocksDbNative.optionsSetCreateMissingColumnFamilies(var5, true);
RocksDbNative.optionsIncreaseParallelism(var5, ForkJoinPool.getCommonPoolParallelism());
RocksDbNative.optionsSetMaxTotalWalSize(var5, 536870912L);
if (var2.statisticsEnabled) {
RocksDbNative.optionsEnableStatistics(var5);
}
MemorySegment var6 = buildDefaultColumnOptions(var3);
MemorySegment var7 = buildColumnOptions(var3, var4, 33554432L, 8, true);
MemorySegment var8 = buildColumnOptions(var3, var4, 67108864L, 12, true);
MemorySegment var9 = buildColumnOptions(var3, var4, 8388608L, 12, false);
MemorySegment var10 = buildColumnOptions(var3, var4, 16777216L, 16, true);
MemorySegment var11 = buildColumnOptions(var3, var4, 8388608L, 12, true);
try (Arena var12 = Arena.ofConfined()) {
String[] var13 = new String[]{"class="kw">default", "chunks", "sections", "entity_sections", "entities", "block_components"};
MemorySegment[] var14 = new MemorySegment[]{var6, var7, var8, var9, var10, var11};
int var15 = var13.length;
MemorySegment var16 = var12.allocate(RocksDbNative.C_POINTER, var15);
MemorySegment var17 = var12.allocate(RocksDbNative.C_POINTER, var15);
MemorySegment var18 = var12.allocate(RocksDbNative.C_POINTER, var15);
for (int var19 = 0; var19 < var15; var19++) {
var16.setAtIndex(RocksDbNative.C_POINTER, var19, var12.allocateFrom(var13[var19]));
var17.setAtIndex(RocksDbNative.C_POINTER, var19, var14[var19]);
}
MemorySegment var30 = var12.allocate(RocksDbNative.C_POINTER);
var30.set(RocksDbNative.C_POINTER, 0L, MemorySegment.NULL);
MemorySegment var20 = var12.allocateFrom(String.valueOf(var1.getExternalData().getWorld().getSavePath().resolve("db")));
MemorySegment var21 = RocksDbNative.openColumnFamilies(var5, var20, var15, var16, var17, var18, var30);
String var22 = RocksDbNative.consumeError(var30);
if (var22 != null) {
RocksDbNative.optionsDestroy(var5);
RocksDbNative.cacheDestroy(var3);
if (!var4.equals(MemorySegment.NULL)) {
RocksDbNative.cacheDestroy(var4);
}
throw new RocksDbChunkStorageProvider.RocksDbException("Failed to open RocksDB: " + var22);
}
var2.db = var21;
var2.chunkColumn = var18.getAtIndex(RocksDbNative.C_POINTER, 1L);
var2.sectionColumn = var18.getAtIndex(RocksDbNative.C_POINTER, 2L);
var2.entitySectionColumn = var18.getAtIndex(RocksDbNative.C_POINTER, 3L);
var2.entityColumn = var18.getAtIndex(RocksDbNative.C_POINTER, 4L);
var2.blockComponentColumn = var18.getAtIndex(RocksDbNative.C_POINTER, 5L);
RocksDbNative.columnFamilyHandleDestroy(var18.getAtIndex(RocksDbNative.C_POINTER, 0L));
} class="kw">finally {
RocksDbNative.optionsDestroy(var6);
RocksDbNative.optionsDestroy(var7);
RocksDbNative.optionsDestroy(var8);
RocksDbNative.optionsDestroy(var9);
RocksDbNative.optionsDestroy(var10);
RocksDbNative.optionsDestroy(var11);
}
var2.writeOptions = RocksDbNative.writeoptionsCreate();
var2.readOptions = RocksDbNative.readoptionsCreate();
var2.flushOptions = RocksDbNative.flushoptionsCreate();
RocksDbNative.flushoptionsSetWait(var2.flushOptions, true);
var2.ioExecutor = Executors.newFixedThreadPool(IO_THREADS, var0 -> {
Runnable var1 = () -> {
try {
var0.run();
} class="kw">finally {
SCRATCH.get().destroy();
SCRATCH.remove();
}
};
Thread var2 = new Thread(var1, "rocksdb-io-" + IO_THREAD_COUNTER.getAndIncrement());
var2.setDaemon(true);
class="kw">return var2;
});
class="kw">return var2;
}
@Nonnull
class="kw">private class="kw">static MemorySegment buildColumnOptions(@Nonnull MemorySegment var0, @Nonnull MemorySegment var1, long var2, int var4, boolean var5) {
MemorySegment var6 = RocksDbNative.blockBasedOptionsCreate();
RocksDbNative.blockBasedOptionsSetBlockCache(var6, var0);
RocksDbNative.blockBasedOptionsSetIndexType(var6, 1);
RocksDbNative.blockBasedOptionsSetFilterPolicy(var6, RocksDbNative.filterpolicyCreateBloomFull(9.9));
RocksDbNative.blockBasedOptionsSetOptimizeFiltersForMemory(var6, true);
MemorySegment var7 = RocksDbNative.optionsCreate();
RocksDbNative.optionsSetCompression(var7, 4);
RocksDbNative.optionsSetBottommostCompression(var7, 7);
RocksDbNative.optionsSetBlockBasedTableFactory(var7, var6);
RocksDbNative.blockBasedOptionsDestroy(var6);
RocksDbNative.optionsSetCompactionStyle(var7, 0);
RocksDbNative.optionsOptimizeLevelStyleCompaction(var7, var2);
RocksDbNative.optionsSetLevelCompactionDynamicLevelBytes(var7, true);
RocksDbNative.optionsSetCompactionPri(var7, 3);
RocksDbNative.optionsSetPrefixExtractor(var7, RocksDbNative.slicetransformCreateFixedPrefix(var4));
if (var5) {
RocksDbNative.optionsSetEnableBlobFiles(var7, true);
RocksDbNative.optionsSetEnableBlobGc(var7, true);
RocksDbNative.optionsSetBlobCompactionReadaheadSize(var7, BLOB_COMPACTION_READAHEAD_BYTES);
RocksDbNative.optionsSetMinBlobSize(var7, MIN_BLOB_SIZE_BYTES);
RocksDbNative.optionsSetBlobGcAgeCutoff(var7, BLOB_GC_AGE_CUTOFF);
RocksDbNative.optionsSetBlobGcForceThreshold(var7, BLOB_GC_FORCE_THRESHOLD);
RocksDbNative.optionsSetBlobCompressionType(var7, 7);
if (!var1.equals(MemorySegment.NULL)) {
RocksDbNative.optionsSetBlobCache(var7, var1);
}
}
class="kw">return var7;
}
@Nonnull
class="kw">private class="kw">static MemorySegment buildDefaultColumnOptions(@Nonnull MemorySegment var0) {
MemorySegment var1 = RocksDbNative.blockBasedOptionsCreate();
RocksDbNative.blockBasedOptionsSetBlockCache(var1, var0);
MemorySegment var2 = RocksDbNative.optionsCreate();
RocksDbNative.optionsSetBlockBasedTableFactory(var2, var1);
RocksDbNative.blockBasedOptionsDestroy(var1);
class="kw">return var2;
}
class="kw">private class="kw">static void checkError(@Nonnull MemorySegment var0) {
String var1 = RocksDbNative.consumeError(var0);
if (var1 != null) {
throw new RocksDbChunkStorageProvider.RocksDbException(var1);
}
}
class="kw">public void delete(@Nonnull RocksDbChunkStorageProvider.RocksDbResource var1, @Nonnull Store<ChunkStore> var2) class="kw">throws IOException {
if (!this.closeInternal(var1)) {
LOGGER.at(Level.WARNING).log("RocksDB teardown was abandoned; skipping db directory removal to avoid a use-after-free");
} else {
FileUtil.deleteDirectory(var2.getExternalData().getWorld().getSavePath().resolve("db"));
}
}
class="kw">private class="kw">static boolean drainIoExecutor(@Nonnull ExecutorService var0) {
try {
if (var0.awaitTermination(30L, TimeUnit.SECONDS)) {
class="kw">return true;
}
var0.shutdownNow();
class="kw">return var0.awaitTermination(30L, TimeUnit.SECONDS);
} catch (InterruptedException var5) {
var0.shutdownNow();
boolean var2 = false;
try {
var2 = var0.awaitTermination(30L, TimeUnit.SECONDS);
} catch (InterruptedException var4) {
}
Thread.currentThread().interrupt();
class="kw">return var2;
}
}
class="kw">private class="kw">static void failPendingIo(@Nonnull RocksDbChunkStorageProvider.RocksDbResource var0) {
List var1 = List.copyOf(var0.inFlightIo);
if (!var1.isEmpty()) {
LOGGER.at(Level.WARNING)
.log("Completing %d in-flight RocksDB I/O future(s) exceptionally during teardown so joiners fail fast instead of hanging", var1.size());
IOException var2 = new IOException("RocksDB storage closed before this I/O task completed");
for (CompletableFuture var4 : var1) {
var4.completeExceptionally(var2);
}
}
}
class="kw">public void close(@NonNullDecl RocksDbChunkStorageProvider.RocksDbResource var1, @NonNullDecl Store<ChunkStore> var2) class="kw">throws IOException {
this.closeInternal(var1);
}
class="kw">private boolean closeInternal(@Nonnull RocksDbChunkStorageProvider.RocksDbResource var1) {
if (var1.db == null) {
class="kw">return true;
}
if (var1.ioExecutor != null) {
RocksDbNative.disableManualCompaction(var1.db);
var1.ioExecutor.shutdown();
boolean var2 = drainIoExecutor(var1.ioExecutor);
failPendingIo(var1);
if (!var2) {
LOGGER.at(Level.WARNING).log("RocksDB I/O executor did not terminate; leaking class="kw">native handles to avoid a use-after-free during teardown");
class="kw">return false;
}
}
try (Arena var12 = Arena.ofConfined()) {
MemorySegment var3 = var12.allocate(RocksDbNative.C_POINTER);
var3.set(RocksDbNative.C_POINTER, 0L, MemorySegment.NULL);
RocksDbNative.flushWal(var1.db, true, var3);
checkError(var3);
} class="kw">finally {
RocksDbNative.columnFamilyHandleDestroy(var1.chunkColumn);
RocksDbNative.columnFamilyHandleDestroy(var1.sectionColumn);
RocksDbNative.columnFamilyHandleDestroy(var1.entitySectionColumn);
RocksDbNative.columnFamilyHandleDestroy(var1.entityColumn);
RocksDbNative.columnFamilyHandleDestroy(var1.blockComponentColumn);
RocksDbNative.close(var1.db);
var1.db = null;
if (var1.writeOptions != null) {
RocksDbNative.writeoptionsDestroy(var1.writeOptions);
var1.writeOptions = null;
}
if (var1.readOptions != null) {
RocksDbNative.readoptionsDestroy(var1.readOptions);
var1.readOptions = null;
}
if (var1.flushOptions != null) {
RocksDbNative.flushoptionsDestroy(var1.flushOptions);
var1.flushOptions = null;
}
if (var1.blockCache != null) {
RocksDbNative.cacheDestroy(var1.blockCache);
var1.blockCache = null;
}
if (var1.blobCache != null && !var1.blobCache.equals(MemorySegment.NULL)) {
RocksDbNative.cacheDestroy(var1.blobCache);
var1.blobCache = null;
}
if (var1.options != null) {
RocksDbNative.optionsDestroy(var1.options);
var1.options = null;
}
}
class="kw">return true;
}
@Nonnull
class="kw">public IChunkLoader getLoader(@Nonnull RocksDbChunkStorageProvider.RocksDbResource var1, @Nonnull Store<ChunkStore> var2) class="kw">throws IOException {
class="kw">return new RocksDbChunkStorageProvider.Loader(var2, var1);
}
@Nonnull
class="kw">public IChunkSaver getSaver(@Nonnull RocksDbChunkStorageProvider.RocksDbResource var1, @Nonnull Store<ChunkStore> var2) class="kw">throws IOException {
class="kw">return new RocksDbChunkStorageProvider.Saver(var1);
}
class="kw">private class="kw">static byte[] toKey(int var0, int var1) {
class="kw">return new byte[]{
(byte)(var0 >>> 24), (byte)(var0 >>> 16), (byte)(var0 >>> 8), (byte)var0, (byte)(var1 >>> 24), (byte)(var1 >>> 16), (byte)(var1 >>> 8), (byte)var1
};
}
class="kw">private class="kw">static int chunkKeyX(@Nonnull MemorySegment var0) {
class="kw">return var0.get(MemorySegmentUtil.INT_BE, 0L);
}
class="kw">private class="kw">static int chunkKeyZ(@Nonnull MemorySegment var0) {
class="kw">return var0.get(MemorySegmentUtil.INT_BE, 4L);
}
@Nonnull
class="kw">private class="kw">static LongList chunkIndexesFromColumn(@Nonnull RocksDbChunkStorageProvider.RocksDbResource var0) {
LongArrayList var1 = new LongArrayList();
try (Arena var2 = Arena.ofConfined()) {
MemorySegment var3 = var2.allocate(RocksDbNative.C_SIZE_T);
MemorySegment var4 = RocksDbNative.createIteratorCf(var0.db, var0.readOptions, var0.chunkColumn);
try {
RocksDbNative.iterSeekToFirst(var4);
while (RocksDbNative.iterValid(var4)) {
MemorySegment var5 = RocksDbNative.iterKey(var4, var3);
long var6 = RocksDbNative.getSizeT(var3, 0L);
if (var6 < 8L) {
LOGGER.at(Level.WARNING).log("Skipping corrupted chunk key in chunk column: %d bytes (expected %d)", var6, 8);
RocksDbNative.iterNext(var4);
} else {
MemorySegment var8 = var5.reinterpret(var6);
var1.add(ChunkUtil.indexChunk(chunkKeyX(var8), chunkKeyZ(var8)));
RocksDbNative.iterNext(var4);
}
}
MemorySegment var16 = var2.allocate(RocksDbNative.C_POINTER);
RocksDbNative.iterGetError(var4, var16);
checkError(var16);
} class="kw">finally {
RocksDbNative.iterDestroy(var4);
}
}
class="kw">return var1;
}
class="kw">private class="kw">static void putChunkKey(@Nonnull MemorySegment var0, long var1, int var3, int var4) {
var0.set(MemorySegmentUtil.INT_BE, var1, var3);
var0.set(MemorySegmentUtil.INT_BE, var1 + 4L, var4);
}
class="kw">private class="kw">static void putSectionKey(@Nonnull MemorySegment var0, long var1, int var3, int var4, int var5) {
var0.set(MemorySegmentUtil.INT_BE, var1, var3);
var0.set(MemorySegmentUtil.INT_BE, var1 + 4L, var5);
var0.set(MemorySegmentUtil.INT_BE, var1 + 8L, var4);
}
class="kw">private class="kw">static void putBlockComponentKey(@Nonnull MemorySegment var0, long var1, int var3, int var4, int var5, short var6) {
putSectionKey(var0, var1, var3, var4, var5);
var0.set(MemorySegmentUtil.SHORT_BE, var1 + 12L, var6);
}
class="kw">private class="kw">static void putUuidKey(@Nonnull MemorySegment var0, long var1, long var3, long var5) {
var0.set(MemorySegmentUtil.LONG_BE, var1, var3);
var0.set(MemorySegmentUtil.LONG_BE, var1 + 8L, var5);
}
class="kw">private class="kw">static void multiGet(@Nonnull MemorySegment var0, @Nonnull MemorySegment var1, @Nonnull RocksDbChunkStorageProvider.Scratch var2, int var3) {
RocksDbNative.multiGetCf(var0, var1, var2.cfPtrs, var3, var2.keyPtrs, var2.keyLens, var2.valuePtrs, var2.valueLens, var2.errs);
for (int var4 = 0; var4 < var3; var4++) {
if (!var2.errs.getAtIndex(RocksDbNative.C_POINTER, var4).equals(MemorySegment.NULL)) {
String var5 = null;
for (int var6 = 0; var6 < var3; var6++) {
MemorySegment var7 = var2.errs.getAtIndex(RocksDbNative.C_POINTER, var6);
if (!var7.equals(MemorySegment.NULL)) {
if (var5 == null) {
var5 = var7.reinterpret(Long.MAX_VALUE).getString(0L);
}
RocksDbNative.free(var7);
var2.errs.setAtIndex(RocksDbNative.C_POINTER, var6, MemorySegment.NULL);
}
MemorySegment var8 = var2.valuePtrs.getAtIndex(RocksDbNative.C_POINTER, var6);
if (!var8.equals(MemorySegment.NULL)) {
RocksDbNative.free(var8);
var2.valuePtrs.setAtIndex(RocksDbNative.C_POINTER, var6, MemorySegment.NULL);
}
}
throw new RocksDbChunkStorageProvider.RocksDbException("multiGet failed: " + var5);
}
}
}
class="kw">private class="kw">static void freeValues(@Nonnull RocksDbChunkStorageProvider.Scratch var0, int var1) {
for (int var2 = 0; var2 < var1; var2++) {
MemorySegment var3 = var0.valuePtrs.getAtIndex(RocksDbNative.C_POINTER, var2);
if (!var3.equals(MemorySegment.NULL)) {
RocksDbNative.free(var3);
var0.valuePtrs.setAtIndex(RocksDbNative.C_POINTER, var2, MemorySegment.NULL);
}
}
}
class="kw">private class="kw">static long valueLen(@Nonnull RocksDbChunkStorageProvider.Scratch var0, int var1) {
class="kw">return RocksDbNative.getSizeT(var0.valueLens, var1 * RocksDbNative.C_SIZE_T.byteSize());
}
class="kw">private class="kw">static void setKeyLen(@Nonnull RocksDbChunkStorageProvider.Scratch var0, int var1, long var2) {
RocksDbNative.setSizeT(var0.keyLens, var1 * RocksDbNative.C_SIZE_T.byteSize(), var2);
}
@Nonnull
class="kw">private class="kw">static MemorySegment toNativeKey(@Nonnull Arena var0, @Nullable byte[] var1) {
if (var1 == null) {
class="kw">return MemorySegment.NULL;
}
MemorySegment var2 = var0.allocate(var1.length);
MemorySegment.copy(var1, 0, var2, ValueLayout.JAVA_BYTE, 0L, var1.length);
class="kw">return var2;
}
@Nullable
class="kw">private class="kw">static ByteBuffer valueBuffer(@Nonnull RocksDbChunkStorageProvider.Scratch var0, int var1) {
MemorySegment var2 = var0.valuePtrs.getAtIndex(RocksDbNative.C_POINTER, var1);
if (var2.equals(MemorySegment.NULL)) {
class="kw">return null;
} else {
long var3 = valueLen(var0, var1);
if (var3 > 268435456L) {
LOGGER.at(Level.WARNING).log("Skipping oversized row: %d bytes (max %d)", var3, 268435456L);
class="kw">return null;
} else {
class="kw">return var2.reinterpret(var3).asByteBuffer();
}
}
}
class="kw">private class="kw">static int stageValue(@Nonnull RocksDbChunkStorageProvider.Scratch var0, @Nullable BsonDocument var1) {
int var2 = BsonUtil.encodeInto(var1, var0.bson);
MemorySegment.copy(var0.bson.getInternalBuffer(), 0, var0.value(var2), ValueLayout.JAVA_BYTE, 0L, var2);
class="kw">return var2;
}
class="kw">public class="kw">static class Loader class="kw">implements IChunkLoader, IChunkLoader.Cubic, MetricProvider {
@Nonnull
class="kw">public class="kw">static class="kw">final MetricsRegistry<RocksDbChunkStorageProvider.Loader> METRICS_REGISTRY = new MetricsRegistry<RocksDbChunkStorageProvider.Loader>()
.register("LoadCount", var0 -> var0.loadCount.get(), Codec.LONG)
.register("LoadHitCount", var0 -> var0.loadHitCount.get(), Codec.LONG)
.register("LoadMissCount", var0 -> var0.loadMissCount.get(), Codec.LONG)
.register("LoadFailureCount", var0 -> var0.loadFailureCount.get(), Codec.LONG)
.register("TotalBytesLoaded", var0 -> var0.totalBytesLoaded.get(), Codec.LONG)
.register("ReadStats", var0 -> var0.readStats)
.register("DeserializeStats", var0 -> var0.deserializeStats);
class="kw">private class="kw">final Store<ChunkStore> store;
class="kw">private class="kw">final RocksDbChunkStorageProvider.RocksDbResource db;
class="kw">private class="kw">final AtomicLong loadCount = new AtomicLong();
class="kw">private class="kw">final AtomicLong loadHitCount = new AtomicLong();
class="kw">private class="kw">final AtomicLong loadMissCount = new AtomicLong();
class="kw">private class="kw">final AtomicLong loadFailureCount = new AtomicLong();
class="kw">private class="kw">final AtomicLong totalBytesLoaded = new AtomicLong();
class="kw">private class="kw">final BucketedOpStats readStats = new BucketedOpStats();
class="kw">private class="kw">final BucketedOpStats deserializeStats = new BucketedOpStats();
class="kw">public Loader(Store<ChunkStore> var1, RocksDbChunkStorageProvider.RocksDbResource var2) {
this.store = var1;
this.db = var2;
}
@Nonnull
@Override
class="kw">public CompletableFuture<Holder<ChunkStore>> loadHolder(int var1, int var2) {
class="kw">return this.db
.supplyIo(
SneakyThrow.sneakySupplier(
() -> {
RocksDbChunkStorageProvider.Scratch var3 = RocksDbChunkStorageProvider.SCRATCH.get();
int var4 = 21;
var3.ensureArrays(21);
int var5 = 248;
MemorySegment var6 = var3.keys(248);
int var7 = 0;
RocksDbChunkStorageProvider.putChunkKey(var6, var7, var1, var2);
var3.cfPtrs.setAtIndex(RocksDbNative.C_POINTER, 0L, this.db.chunkColumn);
var3.keyPtrs.setAtIndex(RocksDbNative.C_POINTER, 0L, var6.asSlice(var7, 8L));
RocksDbChunkStorageProvider.setKeyLen(var3, 0, 8L);
var7 += 8;
for (int var8 = 0; var8 < 10; var8++) {
int var9 = 1 + var8;
RocksDbChunkStorageProvider.putSectionKey(var6, var7, var1, var8, var2);
var3.cfPtrs.setAtIndex(RocksDbNative.C_POINTER, var9, this.db.sectionColumn);
var3.keyPtrs.setAtIndex(RocksDbNative.C_POINTER, var9, var6.asSlice(var7, 12L));
RocksDbChunkStorageProvider.setKeyLen(var3, var9, 12L);
var7 += 12;
}
for (int var32 = 0; var32 < 10; var32++) {
int var34 = 11 + var32;
RocksDbChunkStorageProvider.putSectionKey(var6, var7, var1, var32, var2);
var3.cfPtrs.setAtIndex(RocksDbNative.C_POINTER, var34, this.db.entitySectionColumn);
var3.keyPtrs.setAtIndex(RocksDbNative.C_POINTER, var34, var6.asSlice(var7, 12L));
RocksDbChunkStorageProvider.setKeyLen(var3, var34, 12L);
var7 += 12;
}
long var33 = System.nanoTime();
try {
RocksDbChunkStorageProvider.multiGet(this.db.db, this.db.readOptions, var3, 21);
} catch (RocksDbChunkStorageProvider.RocksDbException var29) {
this.loadFailureCount.getAndIncrement();
throw var29;
}
long var10 = System.nanoTime();
UUID[][] var14 = new UUID[10][];
int var15 = 0;
boolean var16 = false;
Holder var12;
Holder[] var13;
int var17;
try {
for (int var18 = 0; var18 < 21; var18++) {
if (!var3.valuePtrs.getAtIndex(RocksDbNative.C_POINTER, var18).equals(MemorySegment.NULL)) {
var15 += (int)RocksDbChunkStorageProvider.valueLen(var3, var18);
}
}
this.loadCount.getAndIncrement();
this.readStats.record(var10 - var33, var15);
ByteBuffer var36 = RocksDbChunkStorageProvider.valueBuffer(var3, 0);
if (var36 == null) {
this.loadMissCount.getAndIncrement();
class="kw">return null;
}
this.loadHitCount.getAndIncrement();
this.totalBytesLoaded.getAndAdd(var15);
BsonDocument var19 = BsonUtil.readFromBuffer(var36);
var12 = ChunkStore.REGISTRY.deserialize(var19);
if (var12 == null) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping column (%d, %d): column payload failed to deserialize", var1, var2);
class="kw">return null;
}
ChunkColumn var20 = var12.ensureAndGetComponent(ChunkColumn.getComponentType());
var16 = var20.getSectionHolders() != null
|| var12.getComponent(EntityChunk.getComponentType()) != null
|| var12.getComponent(BlockComponentChunk.getComponentType()) != null;
if (var20.getSectionHolders() != null) {
Holder[] var40 = var20.getSectionHolders();
if (var40.length < 10) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Padding truncated Sections array at chunk (%d, %d): %d sections (expected %d)", var1, var2, var40.length, 10);
var40 = Arrays.copyOf(var40, 10);
var20.putSectionHolders(var40);
}
for (int var41 = 0; var41 < var40.length; var41++) {
Holder var42 = var40[var41];
if (var42 != null) {
var42.putComponent(ChunkSection.getComponentType(), new ChunkSection(null, var1, var41, var2, false));
markEmbeddedBlockComponentsForRewrite(var42);
}
}
} else {
Holder[] var21 = new Holder[10];
for (int var22 = 0; var22 < 10; var22++) {
ByteBuffer var23 = RocksDbChunkStorageProvider.valueBuffer(var3, 1 + var22);
if (var23 != null) {
BsonDocument var24 = BsonUtil.readFromBuffer(var23);
Holder var25 = ChunkStore.REGISTRY.deserialize(var24);
if (var25 == null) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping section (%d, %d, %d): section payload failed to deserialize", var1, var22, var2);
} else {
var25.putComponent(ChunkSection.getComponentType(), new ChunkSection(null, var1, var22, var2, false));
if (markEmbeddedBlockComponentsForRewrite(var25)) {
var16 = true;
}
var21[var22] = var25;
}
}
}
var20.putSectionHolders(var21);
}
var13 = var20.getSectionHolders();
var17 = decodeEntitySectionUuids(var3, var14, var1, var2);
} class="kw">finally {
RocksDbChunkStorageProvider.freeValues(var3, 21);
}
this.loadEntitySections(var13, var14, var17, var1, var2);
if (var13 != null) {
Holder[] var37 = var13;
this.loadBlockComponentRows(var1, var2, 0, 10, var1x -> var37[var1x]);
}
WorldChunk var38 = var12.getComponent(WorldChunk.getComponentType());
assert var38 != null;
var38.loadFromHolder(this.store.getExternalData().getWorld(), var1, var2, var12);
if (var16) {
var38.setFlag(ChunkFlag.NEEDS_FORMAT_REWRITE, true);
}
long var39 = System.nanoTime();
this.deserializeStats.record(var39 - var10, var15);
class="kw">return var12;
}
)
);
}
class="kw">private class="kw">static int decodeEntitySectionUuids(@Nonnull RocksDbChunkStorageProvider.Scratch var0, @Nonnull UUID[][] var1, int var2, int var3) {
int var4 = 0;
for (int var5 = 0; var5 < 10; var5++) {
int var6 = 11 + var5;
MemorySegment var7 = var0.valuePtrs.getAtIndex(RocksDbNative.C_POINTER, var6);
if (!var7.equals(MemorySegment.NULL)) {
long var8 = RocksDbChunkStorageProvider.valueLen(var0, var6);
if (var8 % 16L != 0L) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping corrupted entity_sections row at chunk (%d, %d) section %d: %d bytes (expected multiple of 16)", var2, var3, var5, var8);
} else if (var8 / 16L > 65536L) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log(
"Skipping corrupted entity_sections row at chunk (%d, %d) section %d: %d entities exceeds the %d cap",
var2,
var3,
var5,
var8 / 16L,
65536L
);
} else {
int var10 = (int)(var8 / 16L);
UUID[] var11 = new UUID[var10];
MemorySegment var12 = var7.reinterpret(var8);
for (int var13 = 0; var13 < var10; var13++) {
long var14 = var12.get(MemorySegmentUtil.LONG_BE, var13 * 16L);
long var16 = var12.get(MemorySegmentUtil.LONG_BE, var13 * 16L + 8L);
var11[var13] = new UUID(var14, var16);
}
var1[var5] = var11;
var4 += var10;
}
}
}
class="kw">return var4;
}
class="kw">private void loadEntitySections(@Nullable Holder<ChunkStore>[] var1, @Nonnull UUID[][] var2, int var3, int var4, int var5) {
if (var1 != null) {
RocksDbChunkStorageProvider.Scratch var6 = RocksDbChunkStorageProvider.SCRATCH.get();
if (var3 > 0) {
var6.ensureArrays(var3);
MemorySegment var7 = var6.keys(var3 * 16);
int var8 = 0;
for (int var9 = 0; var9 < 10; var9++) {
UUID[] var10 = var2[var9];
if (var10 != null) {
for (UUID var14 : var10) {
long var15 = var8 * 16L;
RocksDbChunkStorageProvider.putUuidKey(var7, var15, var14.getMostSignificantBits(), var14.getLeastSignificantBits());
var6.cfPtrs.setAtIndex(RocksDbNative.C_POINTER, var8, this.db.entityColumn);
var6.keyPtrs.setAtIndex(RocksDbNative.C_POINTER, var8, var7.asSlice(var15, 16L));
RocksDbChunkStorageProvider.setKeyLen(var6, var8, 16L);
var8++;
}
}
}
RocksDbChunkStorageProvider.multiGet(this.db.db, this.db.readOptions, var6, var3);
}
try {
int var22 = 0;
for (int var23 = 0; var23 < 10; var23++) {
UUID[] var24 = var2[var23];
if (var24 != null) {
Holder var25 = var1[var23];
if (var25 == null) {
var22 += var24.length;
} else {
ObjectArrayList var26 = new ObjectArrayList(var24.length);
for (int var27 = 0; var27 < var24.length; var27++) {
ByteBuffer var28 = RocksDbChunkStorageProvider.valueBuffer(var6, var22 + var27);
if (var28 != null) {
try {
BsonDocument var29 = BsonUtil.readFromBuffer(var28);
if (var29 == null) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping corrupted entity %s at chunk (%d, %d) section %d: empty body row", var24[var27], var4, var5, var23);
} else {
Holder var30 = EntityStore.REGISTRY.deserialize(var29);
if (var30 != null) {
TransformComponent var16 = var30.getComponent(TransformComponent.getComponentType());
if (var16 != null) {
var16.seedLastSavedPosition();
}
var26.add(var30);
}
}
} catch (Exception var20) {
((HytaleLogger.Api)RocksDbChunkStorageProvider.LOGGER.at(Level.WARNING).withCause(var20))
.log("Skipping corrupted entity %s at chunk (%d, %d) section %d: body failed to decode", var24[var27], var4, var5, var23);
}
}
}
var22 += var24.length;
var25.putComponent(EntitySection.getComponentType(), new EntitySection(var26, new ReferenceOpenHashSet()));
}
}
}
} class="kw">finally {
if (var3 > 0) {
RocksDbChunkStorageProvider.freeValues(var6, var3);
}
}
}
}
@Nonnull
@Override
class="kw">public LongList getIndexes() class="kw">throws IOException {
class="kw">return RocksDbChunkStorageProvider.chunkIndexesFromColumn(this.db);
}
@Override
class="kw">public void close() class="kw">throws IOException {
}
@Nonnull
@Override
class="kw">public MetricResults toMetricResults() {
class="kw">return METRICS_REGISTRY.toMetricResults(this);
}
@Override
class="kw">public CompletableFuture<Holder<ChunkStore>> loadSectionHolder(int var1, int var2, int var3) {
class="kw">return this.db
.supplyIo(
SneakyThrow.sneakySupplier(
() -> {
RocksDbChunkStorageProvider.Scratch var4 = RocksDbChunkStorageProvider.SCRATCH.get();
var4.ensureArrays(2);
MemorySegment var5 = var4.keys(24);
RocksDbChunkStorageProvider.putSectionKey(var5, 0L, var1, var2, var3);
var4.cfPtrs.setAtIndex(RocksDbNative.C_POINTER, 0L, this.db.sectionColumn);
var4.keyPtrs.setAtIndex(RocksDbNative.C_POINTER, 0L, var5.asSlice(0L, 12L));
RocksDbChunkStorageProvider.setKeyLen(var4, 0, 12L);
RocksDbChunkStorageProvider.putSectionKey(var5, 12L, var1, var2, var3);
var4.cfPtrs.setAtIndex(RocksDbNative.C_POINTER, 1L, this.db.entitySectionColumn);
var4.keyPtrs.setAtIndex(RocksDbNative.C_POINTER, 1L, var5.asSlice(12L, 12L));
RocksDbChunkStorageProvider.setKeyLen(var4, 1, 12L);
long var6 = 0L;
long var8 = 0L;
long var10 = System.nanoTime();
try {
RocksDbChunkStorageProvider.multiGet(this.db.db, this.db.readOptions, var4, 2);
} catch (RocksDbChunkStorageProvider.RocksDbException var37) {
this.loadFailureCount.getAndIncrement();
throw var37;
}
var6 += System.nanoTime() - var10;
UUID[] var13 = null;
Holder var12;
int var14;
try {
boolean var15 = !var4.valuePtrs.getAtIndex(RocksDbNative.C_POINTER, 0L).equals(MemorySegment.NULL);
boolean var16 = !var4.valuePtrs.getAtIndex(RocksDbNative.C_POINTER, 1L).equals(MemorySegment.NULL);
long var17 = var16 ? RocksDbChunkStorageProvider.valueLen(var4, 1) : 0L;
this.loadCount.getAndIncrement();
if (!var15) {
this.loadMissCount.getAndIncrement();
this.readStats.record(var6, (int)var17);
class="kw">return null;
}
this.loadHitCount.getAndIncrement();
var14 = (int)(RocksDbChunkStorageProvider.valueLen(var4, 0) + var17);
if (var16) {
if (var17 % 16L != 0L) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log(
"Skipping corrupted entity_sections row at section (%d, %d, %d): %d bytes (expected multiple of 16)",
var1,
var2,
var3,
var17
);
} else if (var17 / 16L > 65536L) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log(
"Skipping corrupted entity_sections row at section (%d, %d, %d): %d entities exceeds the %d cap",
var1,
var2,
var3,
var17 / 16L,
65536L
);
} else {
int var19 = (int)(var17 / 16L);
var13 = new UUID[var19];
MemorySegment var20 = var4.valuePtrs.getAtIndex(RocksDbNative.C_POINTER, 1L).reinterpret(var17);
for (int var21 = 0; var21 < var19; var21++) {
long var22 = var20.get(MemorySegmentUtil.LONG_BE, var21 * 16L);
long var24 = var20.get(MemorySegmentUtil.LONG_BE, var21 * 16L + 8L);
var13[var21] = new UUID(var22, var24);
}
}
}
long var48 = System.nanoTime();
BsonDocument var50 = BsonUtil.readFromBuffer(RocksDbChunkStorageProvider.valueBuffer(var4, 0));
var12 = ChunkStore.REGISTRY.deserialize(var50);
if (var12 == null) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping section (%d, %d, %d): section payload failed to deserialize", var1, var2, var3);
class="kw">return null;
}
var12.putComponent(ChunkSection.getComponentType(), new ChunkSection(null, var1, var2, var3, false));
var8 += System.nanoTime() - var48;
} class="kw">finally {
RocksDbChunkStorageProvider.freeValues(var4, 2);
}
this.totalBytesLoaded.getAndAdd(var14);
if (var13 != null) {
ObjectArrayList var43 = new ObjectArrayList(var13.length);
if (var13.length > 0) {
var4.ensureArrays(var13.length);
MemorySegment var45 = var4.keys(var13.length * 16);
for (int var46 = 0; var46 < var13.length; var46++) {
long var18 = var46 * 16L;
RocksDbChunkStorageProvider.putUuidKey(
var45, var18, var13[var46].getMostSignificantBits(), var13[var46].getLeastSignificantBits()
);
var4.cfPtrs.setAtIndex(RocksDbNative.C_POINTER, var46, this.db.entityColumn);
var4.keyPtrs.setAtIndex(RocksDbNative.C_POINTER, var46, var45.asSlice(var18, 16L));
RocksDbChunkStorageProvider.setKeyLen(var4, var46, 16L);
}
var10 = System.nanoTime();
RocksDbChunkStorageProvider.multiGet(this.db.db, this.db.readOptions, var4, var13.length);
var6 += System.nanoTime() - var10;
try {
long var47 = System.nanoTime();
long var49 = 0L;
for (int var51 = 0; var51 < var13.length; var51++) {
ByteBuffer var52 = RocksDbChunkStorageProvider.valueBuffer(var4, var51);
if (var52 != null) {
var49 += RocksDbChunkStorageProvider.valueLen(var4, var51);
try {
BsonDocument var23 = BsonUtil.readFromBuffer(var52);
if (var23 == null) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping corrupted entity %s at section (%d, %d, %d): empty body row", var13[var51], var1, var2, var3);
} else {
Holder var53 = EntityStore.REGISTRY.deserialize(var23);
if (var53 != null) {
TransformComponent var25 = var53.getComponent(TransformComponent.getComponentType());
if (var25 != null) {
var25.seedLastSavedPosition();
}
var43.add(var53);
}
}
} catch (Exception var36) {
((HytaleLogger.Api)RocksDbChunkStorageProvider.LOGGER.at(Level.WARNING).withCause(var36))
.log("Skipping corrupted entity %s at section (%d, %d, %d): body failed to decode", var13[var51], var1, var2, var3);
}
}
}
var8 += System.nanoTime() - var47;
var14 += (int)var49;
this.totalBytesLoaded.getAndAdd(var49);
} class="kw">finally {
RocksDbChunkStorageProvider.freeValues(var4, var13.length);
}
}
var12.putComponent(EntitySection.getComponentType(), new EntitySection(var43, new ReferenceOpenHashSet()));
}
if (markEmbeddedBlockComponentsForRewrite(var12)) {
ChunkSection var44 = var12.getComponent(ChunkSection.getComponentType());
assert var44 != null;
var44.markNeedsSaving();
}
this.loadBlockComponentRows(var1, var3, var2, var2 + 1, var1x -> var12);
this.readStats.record(var6, var14);
this.deserializeStats.record(var8, var14);
class="kw">return var12;
}
)
);
}
class="kw">private class="kw">static boolean markEmbeddedBlockComponentsForRewrite(@Nonnull Holder<ChunkStore> var0) {
BlockComponentSection var1 = var0.getComponent(BlockComponentSection.getComponentType());
if (var1 != null && !var1.getBlockHolders().isEmpty()) {
var1.markAllBlocksNeedsSaving();
class="kw">return true;
} else {
class="kw">return false;
}
}
class="kw">private void loadBlockComponentRows(int var1, int var2, int var3, int var4, @Nonnull IntFunction<Holder<ChunkStore>> var5) {
try (Arena var6 = Arena.ofConfined()) {
MemorySegment var7 = var6.allocate(12L);
MemorySegment var8 = var6.allocate(RocksDbNative.C_SIZE_T);
MemorySegment var9 = var6.allocate(RocksDbNative.C_POINTER);
MemorySegment var10 = RocksDbNative.createIteratorCf(this.db.db, this.db.readOptions, this.db.blockComponentColumn);
try {
long var11 = 0L;
for (int var13 = var3; var13 < var4; var13++) {
BlockComponentSection var14 = null;
BlockSection var15 = null;
boolean var16 = false;
RocksDbChunkStorageProvider.putSectionKey(var7, 0L, var1, var13, var2);
RocksDbNative.iterSeek(var10, var7, 12L);
while (RocksDbNative.iterValid(var10)) {
MemorySegment var17 = RocksDbNative.iterKey(var10, var8);
long var18 = RocksDbNative.getSizeT(var8, 0L);
if (var18 < 12L) {
break;
}
MemorySegment var20 = var17.reinterpret(var18);
if (var20.get(MemorySegmentUtil.INT_BE, 0L) != var1
|| var20.get(MemorySegmentUtil.INT_BE, 4L) != var2
|| var20.get(MemorySegmentUtil.INT_BE, 8L) != var13) {
break;
}
if (var18 != 14L) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping corrupted block_components key at section (%d, %d, %d): %d bytes (expected %d)", var1, var13, var2, var18, 14);
RocksDbNative.iterNext(var10);
} else {
int var21 = Short.toUnsignedInt(var20.get(MemorySegmentUtil.SHORT_BE, 12L));
if (var21 >= 32768) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping block component row at section (%d, %d, %d): index %d out of range (max %d)", var1, var13, var2, var21, 32767);
RocksDbNative.iterNext(var10);
} else {
if (!var16) {
var16 = true;
Holder var22 = var5.apply(var13);
if (var22 != null) {
var14 = var22.ensureAndGetComponent(BlockComponentSection.getComponentType());
var15 = var22.getComponent(BlockSection.getComponentType());
}
}
if (var14 == null) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping block component row at section (%d, %d, %d) index %d: no section payload", var1, var13, var2, var21);
RocksDbNative.iterNext(var10);
} else {
MemorySegment var36 = RocksDbNative.iterValue(var10, var8);
long var23 = RocksDbNative.getSizeT(var8, 0L);
if (var23 > 268435456L) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log(
"Skipping oversized block component row at section (%d, %d, %d) index %d: %d bytes (max %d)",
var1,
var13,
var2,
var21,
var23,
268435456L
);
RocksDbNative.iterNext(var10);
} else {
var11 += var23;
Holder var25 = null;
try {
BsonDocument var26 = BsonUtil.readFromBuffer(var36.reinterpret(var23).asByteBuffer());
if (var26 != null) {
var25 = ChunkStore.REGISTRY.deserialize(var26);
}
} catch (Exception var33) {
((HytaleLogger.Api)RocksDbChunkStorageProvider.LOGGER.at(Level.WARNING).withCause(var33))
.log("Skipping corrupted block component row at section (%d, %d, %d) index %d", var1, var13, var2, var21);
}
if (var25 == null) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log(
"Skipping block component row at section (%d, %d, %d) index %d: payload failed to deserialize",
var1,
var13,
var2,
var21
);
RocksDbNative.iterNext(var10);
} else {
if (var15 != null && var15.get(ChunkUtil.xFromIndex(var21), ChunkUtil.yFromIndex(var21), ChunkUtil.zFromIndex(var21)) == 0) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Dropping orphaned block component row at section (%d, %d, %d) index %d: block is air", var1, var13, var2, var21);
var14.removeBlockHolder((short)var21);
var14.tombstoneBlock((short)var21);
} else {
var14.loadBlockHolder((short)var21, var25);
}
RocksDbNative.iterNext(var10);
}
}
}
}
}
}
RocksDbNative.iterGetError(var10, var9);
RocksDbChunkStorageProvider.checkError(var9);
}
this.totalBytesLoaded.getAndAdd(var11);
} class="kw">finally {
RocksDbNative.iterDestroy(var10);
}
}
}
}
class="kw">public class="kw">static class RocksDbException class="kw">extends RuntimeException {
class="kw">public RocksDbException(@Nonnull String var1) {
super(var1);
}
}
class="kw">public class="kw">static class RocksDbResource {
class="kw">public MemorySegment db;
class="kw">public MemorySegment chunkColumn;
class="kw">public MemorySegment sectionColumn;
class="kw">public MemorySegment entitySectionColumn;
class="kw">public MemorySegment entityColumn;
class="kw">public MemorySegment blockComponentColumn;
class="kw">public MemorySegment options;
@Nullable
class="kw">public MemorySegment blockCache;
@Nullable
class="kw">public MemorySegment blobCache;
class="kw">public MemorySegment writeOptions;
class="kw">public MemorySegment readOptions;
class="kw">public MemorySegment flushOptions;
class="kw">public boolean statisticsEnabled;
class="kw">public ExecutorService ioExecutor;
class="kw">private class="kw">final Set<CompletableFuture<?>> inFlightIo = ConcurrentHashMap.newKeySet();
class="kw">public RocksDbResource() {
}
@Nonnull
class="kw">public <T> CompletableFuture<T> supplyIo(@Nonnull Supplier<T> var1) {
CompletableFuture var2 = new CompletableFuture<>();
this.inFlightIo.add(var2);
var2.whenComplete((var2x, var3) -> this.inFlightIo.remove(var2));
try {
this.ioExecutor.execute(() -> {
try {
var2.complete(var1.get());
} catch (Throwable var3) {
var2.completeExceptionally(var3);
}
});
} catch (RejectedExecutionException var4) {
var2.completeExceptionally(var4);
}
class="kw">return var2;
}
@Nonnull
class="kw">public CompletableFuture<Void> runIo(@Nonnull Runnable var1) {
class="kw">return this.supplyIo(() -> {
var1.run();
class="kw">return null;
});
}
}
class="kw">public class="kw">static class RocksDbStatistics class="kw">implements MetricProvider {
@Nonnull
class="kw">public class="kw">static class="kw">final MetricsRegistry<RocksDbChunkStorageProvider.RocksDbStatistics> METRICS_REGISTRY = buildRegistry();
@Nonnull
class="kw">public class="kw">final long[] tickers;
@Nonnull
class="kw">public class="kw">final RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot[] histograms;
class="kw">private RocksDbStatistics(@Nonnull long[] var1, @Nonnull RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot[] var2) {
this.tickers = var1;
this.histograms = var2;
}
@Nonnull
class="kw">public class="kw">static RocksDbChunkStorageProvider.RocksDbStatistics snapshot(@Nonnull MemorySegment var0) {
long[] var1 = new long[RocksDbNative.STATISTICS_TICKERS.length];
for (int var2 = 0; var2 < RocksDbNative.STATISTICS_TICKERS.length; var2++) {
var1[var2] = RocksDbNative.optionsStatisticsGetTickerCount(var0, RocksDbNative.STATISTICS_TICKERS[var2].type());
}
RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot[] var8 = new RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot[RocksDbNative.STATISTICS_HISTOGRAMS.length];
MemorySegment var3 = RocksDbNative.statisticsHistogramDataCreate();
try {
for (int var4 = 0; var4 < RocksDbNative.STATISTICS_HISTOGRAMS.length; var4++) {
RocksDbNative.optionsStatisticsGetHistogramData(var0, RocksDbNative.STATISTICS_HISTOGRAMS[var4].type(), var3);
var8[var4] = RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot.from(var3);
}
} class="kw">finally {
RocksDbNative.statisticsHistogramDataDestroy(var3);
}
class="kw">return new RocksDbChunkStorageProvider.RocksDbStatistics(var1, var8);
}
@Nonnull
@Override
class="kw">public MetricResults toMetricResults() {
class="kw">return METRICS_REGISTRY.toMetricResults(this);
}
@Nonnull
class="kw">private class="kw">static MetricsRegistry<RocksDbChunkStorageProvider.RocksDbStatistics> buildRegistry() {
MetricsRegistry var0 = new MetricsRegistry<>();
for (int var1 = 0; var1 < RocksDbNative.STATISTICS_TICKERS.length; var1++) {
int var2 = var1;
var0 = var0.register(RocksDbNative.STATISTICS_TICKERS[var1].name(), var1x -> var1x.tickers[var2], Codec.LONG);
}
for (int var3 = 0; var3 < RocksDbNative.STATISTICS_HISTOGRAMS.length; var3++) {
int var4 = var3;
var0 = var0.register(RocksDbNative.STATISTICS_HISTOGRAMS[var3].name(), var1x -> var1x.histograms[var4]);
}
class="kw">return var0;
}
class="kw">public record HistogramSnapshot(long count, long sum, double average, double median, double p95, double p99, double max, double stdDev)
class="kw">implements MetricProvider {
@Nonnull
class="kw">public class="kw">static class="kw">final MetricsRegistry<RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot> METRICS_REGISTRY = new MetricsRegistry<RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot>()
.register("Count", RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot::count, Codec.LONG)
.register("Sum", RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot::sum, Codec.LONG)
.register("Average", RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot::average, Codec.DOUBLE)
.register("Median", RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot::median, Codec.DOUBLE)
.register("P95", RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot::p95, Codec.DOUBLE)
.register("P99", RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot::p99, Codec.DOUBLE)
.register("Max", RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot::max, Codec.DOUBLE)
.register("StdDev", RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot::stdDev, Codec.DOUBLE);
class="kw">public HistogramSnapshot {
}
@Nonnull
class="kw">public class="kw">static RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot from(@Nonnull MemorySegment var0) {
class="kw">return new RocksDbChunkStorageProvider.RocksDbStatistics.HistogramSnapshot(
RocksDbNative.statisticsHistogramDataGetCount(var0),
RocksDbNative.statisticsHistogramDataGetSum(var0),
RocksDbNative.statisticsHistogramDataGetAverage(var0),
RocksDbNative.statisticsHistogramDataGetMedian(var0),
RocksDbNative.statisticsHistogramDataGetP95(var0),
RocksDbNative.statisticsHistogramDataGetP99(var0),
RocksDbNative.statisticsHistogramDataGetMax(var0),
RocksDbNative.statisticsHistogramDataGetStdDev(var0)
);
}
@Nonnull
@Override
class="kw">public MetricResults toMetricResults() {
class="kw">return METRICS_REGISTRY.toMetricResults(this);
}
}
}
class="kw">public record RocksDbStats(
long blockCacheBytes,
long blockCachePinnedBytes,
long blockCacheCapacityBytes,
long blobCacheBytes,
long blobCachePinnedBytes,
long blobCacheCapacityBytes,
long backgroundErrors,
long memTableFlushPending,
long numRunningFlushes,
long numSnapshots,
long numLiveVersions,
long isWriteStopped,
long actualDelayedWriteRate,
@Nonnull RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats chunks,
@Nonnull RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats sections,
@Nonnull RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats entitySections,
@Nonnull RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats entities
) class="kw">implements MetricProvider {
class="kw">public class="kw">static class="kw">final int LEVEL_COUNT = 7;
@Nonnull
class="kw">public class="kw">static class="kw">final MetricsRegistry<RocksDbChunkStorageProvider.RocksDbStats> METRICS_REGISTRY = new MetricsRegistry<RocksDbChunkStorageProvider.RocksDbStats>()
.register("BlockCacheBytes", RocksDbChunkStorageProvider.RocksDbStats::blockCacheBytes, Codec.LONG)
.register("BlockCachePinnedBytes", RocksDbChunkStorageProvider.RocksDbStats::blockCachePinnedBytes, Codec.LONG)
.register("BlockCacheCapacityBytes", RocksDbChunkStorageProvider.RocksDbStats::blockCacheCapacityBytes, Codec.LONG)
.register("BlobCacheBytes", RocksDbChunkStorageProvider.RocksDbStats::blobCacheBytes, Codec.LONG)
.register("BlobCachePinnedBytes", RocksDbChunkStorageProvider.RocksDbStats::blobCachePinnedBytes, Codec.LONG)
.register("BlobCacheCapacityBytes", RocksDbChunkStorageProvider.RocksDbStats::blobCacheCapacityBytes, Codec.LONG)
.register("BackgroundErrors", RocksDbChunkStorageProvider.RocksDbStats::backgroundErrors, Codec.LONG)
.register("MemTableFlushPending", RocksDbChunkStorageProvider.RocksDbStats::memTableFlushPending, Codec.LONG)
.register("NumRunningFlushes", RocksDbChunkStorageProvider.RocksDbStats::numRunningFlushes, Codec.LONG)
.register("NumSnapshots", RocksDbChunkStorageProvider.RocksDbStats::numSnapshots, Codec.LONG)
.register("NumLiveVersions", RocksDbChunkStorageProvider.RocksDbStats::numLiveVersions, Codec.LONG)
.register("IsWriteStopped", RocksDbChunkStorageProvider.RocksDbStats::isWriteStopped, Codec.LONG)
.register("ActualDelayedWriteRate", RocksDbChunkStorageProvider.RocksDbStats::actualDelayedWriteRate, Codec.LONG)
.register("Chunks", RocksDbChunkStorageProvider.RocksDbStats::chunks)
.register("Sections", RocksDbChunkStorageProvider.RocksDbStats::sections)
.register("EntitySections", RocksDbChunkStorageProvider.RocksDbStats::entitySections)
.register("Entities", RocksDbChunkStorageProvider.RocksDbStats::entities);
class="kw">public RocksDbStats {
}
@Nonnull
class="kw">public class="kw">static RocksDbChunkStorageProvider.RocksDbStats snapshot(@Nonnull RocksDbChunkStorageProvider.RocksDbResource var0) {
MemorySegment var1 = var0.db;
try (Arena var2 = Arena.ofConfined()) {
class="kw">return new RocksDbChunkStorageProvider.RocksDbStats(
getLongDb(var2, var1, "rocksdb.block-cache-usage"),
getLongDb(var2, var1, "rocksdb.block-cache-pinned-usage"),
getLongDb(var2, var1, "rocksdb.block-cache-capacity"),
RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats.getLongCf(var2, var1, var0.chunkColumn, "rocksdb.blob-cache-usage"),
RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats.getLongCf(var2, var1, var0.chunkColumn, "rocksdb.blob-cache-pinned-usage"),
RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats.getLongCf(var2, var1, var0.chunkColumn, "rocksdb.blob-cache-capacity"),
getLongDb(var2, var1, "rocksdb.background-errors"),
getLongDb(var2, var1, "rocksdb.mem-table-flush-pending"),
getLongDb(var2, var1, "rocksdb.num-running-flushes"),
getLongDb(var2, var1, "rocksdb.num-snapshots"),
getLongDb(var2, var1, "rocksdb.num-live-versions"),
getLongDb(var2, var1, "rocksdb.is-write-stopped"),
getLongDb(var2, var1, "rocksdb.actual-delayed-write-rate"),
RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats.snapshot(var2, var1, var0.chunkColumn),
RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats.snapshot(var2, var1, var0.sectionColumn),
RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats.snapshot(var2, var1, var0.entitySectionColumn),
RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats.snapshot(var2, var1, var0.entityColumn)
);
}
}
@Nonnull
@Override
class="kw">public MetricResults toMetricResults() {
class="kw">return METRICS_REGISTRY.toMetricResults(this);
}
class="kw">private class="kw">static long getLongDb(@Nonnull Arena var0, @Nonnull MemorySegment var1, @Nonnull String var2) {
MemorySegment var3 = var0.allocateFrom(var2);
MemorySegment var4 = var0.allocate(ValueLayout.JAVA_LONG);
class="kw">return RocksDbNative.propertyInt(var1, var3, var4) == 0 ? var4.get(ValueLayout.JAVA_LONG, 0L) : -1L;
}
class="kw">public record ColumnFamilyStats(
long estimateNumKeys,
long estimateLiveDataBytes,
long totalSstFilesBytes,
long liveSstFilesBytes,
long numBlobFiles,
long totalBlobFilesBytes,
long liveBlobFilesBytes,
long memTableBytes,
long allMemTableBytes,
long numImmutableMemTable,
long compactionPending,
long numRunningCompactions,
long pendingCompactionBytes,
@Nonnull long[] filesPerLevel
) class="kw">implements MetricProvider {
@Nonnull
class="kw">public class="kw">static class="kw">final MetricsRegistry<RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats> METRICS_REGISTRY = new MetricsRegistry<RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats>()
.register("EstimateNumKeys", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::estimateNumKeys, Codec.LONG)
.register("EstimateLiveDataBytes", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::estimateLiveDataBytes, Codec.LONG)
.register("TotalSstFilesBytes", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::totalSstFilesBytes, Codec.LONG)
.register("LiveSstFilesBytes", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::liveSstFilesBytes, Codec.LONG)
.register("NumBlobFiles", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::numBlobFiles, Codec.LONG)
.register("TotalBlobFilesBytes", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::totalBlobFilesBytes, Codec.LONG)
.register("LiveBlobFilesBytes", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::liveBlobFilesBytes, Codec.LONG)
.register("MemTableBytes", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::memTableBytes, Codec.LONG)
.register("AllMemTableBytes", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::allMemTableBytes, Codec.LONG)
.register("NumImmutableMemTable", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::numImmutableMemTable, Codec.LONG)
.register("CompactionPending", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::compactionPending, Codec.LONG)
.register("NumRunningCompactions", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::numRunningCompactions, Codec.LONG)
.register("PendingCompactionBytes", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::pendingCompactionBytes, Codec.LONG)
.register("FilesPerLevel", RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats::filesPerLevel, Codec.LONG_ARRAY);
class="kw">public ColumnFamilyStats {
}
@Nonnull
class="kw">public class="kw">static RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats snapshot(
@Nonnull Arena var0, @Nonnull MemorySegment var1, @Nonnull MemorySegment var2
) {
long[] var3 = new long[7];
for (int var4 = 0; var4 < var3.length; var4++) {
var3[var4] = getStringLongCf(var0, var1, var2, "rocksdb.num-files-at-level" + var4);
}
class="kw">return new RocksDbChunkStorageProvider.RocksDbStats.ColumnFamilyStats(
getLongCf(var0, var1, var2, "rocksdb.estimate-num-keys"),
getLongCf(var0, var1, var2, "rocksdb.estimate-live-data-size"),
getLongCf(var0, var1, var2, "rocksdb.total-sst-files-size"),
getLongCf(var0, var1, var2, "rocksdb.live-sst-files-size"),
getLongCf(var0, var1, var2, "rocksdb.num-blob-files"),
getLongCf(var0, var1, var2, "rocksdb.total-blob-file-size"),
getLongCf(var0, var1, var2, "rocksdb.live-blob-file-size"),
getLongCf(var0, var1, var2, "rocksdb.cur-size-all-mem-tables"),
getLongCf(var0, var1, var2, "rocksdb.size-all-mem-tables"),
getLongCf(var0, var1, var2, "rocksdb.num-immutable-mem-table"),
getLongCf(var0, var1, var2, "rocksdb.compaction-pending"),
getLongCf(var0, var1, var2, "rocksdb.num-running-compactions"),
getLongCf(var0, var1, var2, "rocksdb.estimate-pending-compaction-bytes"),
var3
);
}
@Nonnull
@Override
class="kw">public MetricResults toMetricResults() {
class="kw">return METRICS_REGISTRY.toMetricResults(this);
}
class="kw">private class="kw">static long getLongCf(@Nonnull Arena var0, @Nonnull MemorySegment var1, @Nonnull MemorySegment var2, @Nonnull String var3) {
MemorySegment var4 = var0.allocateFrom(var3);
MemorySegment var5 = var0.allocate(ValueLayout.JAVA_LONG);
class="kw">return RocksDbNative.propertyIntCf(var1, var2, var4, var5) == 0 ? var5.get(ValueLayout.JAVA_LONG, 0L) : -1L;
}
class="kw">private class="kw">static long getStringLongCf(@Nonnull Arena var0, @Nonnull MemorySegment var1, @Nonnull MemorySegment var2, @Nonnull String var3) {
MemorySegment var4 = var0.allocateFrom(var3);
MemorySegment var5 = RocksDbNative.propertyValueCf(var1, var2, var4);
if (var5.equals(MemorySegment.NULL)) {
class="kw">return -1L;
}
try {
class="kw">return Long.parseLong(var5.reinterpret(Long.MAX_VALUE).getString(0L).trim());
} catch (NumberFormatException var12) {
class="kw">return -1L;
} class="kw">finally {
RocksDbNative.free(var5);
}
}
}
}
class="kw">public class="kw">static class Saver class="kw">implements IChunkSaver, IChunkSaver.Cubic, MetricProvider {
@Nonnull
class="kw">public class="kw">static class="kw">final MetricsRegistry<RocksDbChunkStorageProvider.Saver> METRICS_REGISTRY = new MetricsRegistry<RocksDbChunkStorageProvider.Saver>()
.register("SaveCount", var0 -> var0.saveCount.get(), Codec.LONG)
.register("SaveFailureCount", var0 -> var0.saveFailureCount.get(), Codec.LONG)
.register("RemoveCount", var0 -> var0.removeCount.get(), Codec.LONG)
.register("RemoveFailureCount", var0 -> var0.removeFailureCount.get(), Codec.LONG)
.register("TotalBytesSaved", var0 -> var0.totalBytesSaved.get(), Codec.LONG)
.register("FlushCount", var0 -> var0.flushCount.get(), Codec.LONG)
.register("CompactCount", var0 -> var0.compactCount.get(), Codec.LONG)
.register("SerializeStats", var0 -> var0.serializeStats)
.register("WriteStats", var0 -> var0.writeStats)
.register("RemoveStats", var0 -> var0.removeStats)
.register("DbStats", var0 -> RocksDbChunkStorageProvider.RocksDbStats.snapshot(var0.db))
.register("DbStatistics", var0 -> var0.db.statisticsEnabled ? RocksDbChunkStorageProvider.RocksDbStatistics.snapshot(var0.db.options) : null);
class="kw">private class="kw">final RocksDbChunkStorageProvider.RocksDbResource db;
class="kw">private class="kw">final AtomicLong saveCount = new AtomicLong();
class="kw">private class="kw">final AtomicLong saveFailureCount = new AtomicLong();
class="kw">private class="kw">final AtomicLong removeCount = new AtomicLong();
class="kw">private class="kw">final AtomicLong removeFailureCount = new AtomicLong();
class="kw">private class="kw">final AtomicLong totalBytesSaved = new AtomicLong();
class="kw">private class="kw">final AtomicLong flushCount = new AtomicLong();
class="kw">private class="kw">final AtomicLong compactCount = new AtomicLong();
class="kw">private class="kw">final BucketedOpStats serializeStats = new BucketedOpStats();
class="kw">private class="kw">final BucketedOpStats writeStats = new BucketedOpStats();
class="kw">private class="kw">final BucketedOpStats removeStats = new BucketedOpStats();
class="kw">public Saver(RocksDbChunkStorageProvider.RocksDbResource var1) {
this.db = var1;
}
@Override
class="kw">public CompletableFuture<Void> saveSection(
int var1, int var2, int var3, @Nonnull Store<ChunkStore> var4, @Nonnull Ref<ChunkStore> var5, @Nullable Executor var6, @Nullable Runnable var7
) {
Holder var8 = var4.copySerializableEntity(
var5,
ChunkStore.REGISTRY.newHolder(),
var0 -> !var0.equals(EntitySection.getComponentType()) && !var0.equals(BlockComponentSection.getComponentType())
);
CompletableFuture var9 = this.db.runIo(SneakyThrow.sneakyRunnable(() -> {
RocksDbChunkStorageProvider.Scratch var5 = RocksDbChunkStorageProvider.SCRATCH.get();
long var6 = System.nanoTime();
try {
MemorySegment var8 = var5.keys(12);
RocksDbChunkStorageProvider.putSectionKey(var8, 0L, var1, var2, var3);
BsonDocument var9 = ChunkStore.REGISTRY.serialize(var8);
int var10 = RocksDbChunkStorageProvider.stageValue(var5, var9);
long var11 = System.nanoTime();
RocksDbNative.putCf(this.db.db, this.db.writeOptions, this.db.sectionColumn, var8, 12L, var5.value, var10, var5.clearErrPtr());
RocksDbChunkStorageProvider.checkError(var5.errPtr);
long var13 = System.nanoTime();
this.saveCount.getAndIncrement();
this.totalBytesSaved.getAndAdd(var10);
this.serializeStats.record(var11 - var6, var10);
this.writeStats.record(var13 - var11, var10);
} catch (RocksDbChunkStorageProvider.RocksDbException var15) {
this.saveFailureCount.getAndIncrement();
throw var15;
}
}));
if (var7 != null) {
var9.whenComplete((var1x, var2x) -> var7.run());
}
class="kw">return var9;
}
@Override
class="kw">public CompletableFuture<Void> saveEntitySection(
int var1, int var2, int var3, @Nonnull Store<ChunkStore> var4, @Nonnull EntitySection var5, @Nullable Executor var6, @Nullable Runnable var7
) {
ComponentRegistry.Data var8 = EntityStore.REGISTRY.getData();
List var9 = var5.getEntityHolders();
Set var10 = var5.getEntityReferences();
ObjectArrayList var11 = new ObjectArrayList(var9.size() + var10.size());
collectEntityUuidsFromHolders(var9, var8, var11);
collectEntityUuidsFromReferences(var10, var8, var11);
ObjectArrayList var12 = new ObjectArrayList(var9.size() + var10.size());
ReferenceArrayList var13 = new ReferenceArrayList();
boolean var15 = false;
CompletableFuture var14;
try {
snapshotDirtyEntityHolders(var9, var8, var12, var13);
snapshotDirtyEntityReferences(var10, var8, var12, var13);
var14 = this.db
.runIo(
SneakyThrow.sneakyRunnable(
() -> {
RocksDbChunkStorageProvider.Scratch var6 = RocksDbChunkStorageProvider.SCRATCH.get();
MemorySegment var7 = var6.writeBatch();
long var8 = System.nanoTime();
try {
int var10 = var11.size();
int var11 = 16 * var10;
MemorySegment var12 = var6.keys(12);
RocksDbChunkStorageProvider.putSectionKey(var12, 0L, var1, var2, var3);
MemorySegment var13 = var6.value(var11);
for (int var14 = 0; var14 < var10; var14++) {
UUID var15 = (UUID)var11.get(var14);
RocksDbChunkStorageProvider.putUuidKey(var13, var14 * 16L, var15.getMostSignificantBits(), var15.getLeastSignificantBits());
}
RocksDbNative.writebatchPutCf(var7, this.db.entitySectionColumn, var12, 12L, var13, var11);
int var27 = var11;
for (int var28 = 0; var28 < var12.size(); var28++) {
Holder var16 = (Holder<EntityStore>)var12.get(var28);
UUIDComponent var17 = var16.getComponent(UUIDComponent.getComponentType());
if (var17 == null) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping entity with no UUID component while saving entity section (%d, %d, %d)", var1, var2, var3);
} else {
UUID var18 = var17.getUuid();
MemorySegment var19 = var6.keys(16);
RocksDbChunkStorageProvider.putUuidKey(var19, 0L, var18.getMostSignificantBits(), var18.getLeastSignificantBits());
BsonDocument var20 = EntityStore.REGISTRY.serialize(var16);
int var21 = RocksDbChunkStorageProvider.stageValue(var6, var20);
RocksDbNative.writebatchPutCf(var7, this.db.entityColumn, var19, 16L, var6.value, var21);
var27 += var21;
}
}
long var29 = System.nanoTime();
RocksDbNative.write(this.db.db, this.db.writeOptions, var7, var6.clearErrPtr());
RocksDbChunkStorageProvider.checkError(var6.errPtr);
long var30 = System.nanoTime();
this.saveCount.getAndIncrement();
this.totalBytesSaved.getAndAdd(var27);
this.serializeStats.record(var29 - var8, var27);
this.writeStats.record(var30 - var29, var27);
} catch (RocksDbChunkStorageProvider.RocksDbException var25) {
this.saveFailureCount.getAndIncrement();
throw var25;
} class="kw">finally {
RocksDbNative.writebatchClear(var7);
}
}
)
);
ObjectListIterator var16 = var13.iterator();
while (var16.hasNext()) {
Dirty var17 = (Dirty)var16.next();
var17.setSaving(var14);
}
var15 = true;
} class="kw">finally {
if (!var15) {
ObjectListIterator var19 = var13.iterator();
while (var19.hasNext()) {
Dirty var20 = (Dirty)var19.next();
var20.markDirty();
}
}
}
if (var7 != null) {
var14.whenComplete((var1x, var2x) -> var7.run());
}
if (var13.isEmpty()) {
class="kw">return var14;
}
ReferenceArrayList var23 = var13;
CompletableFuture var24 = var14;
BiConsumer var18 = (var2x, var3x) -> {
if (var3x != null) {
Iterator var4 = var23.iterator();
while (var4.hasNext()) {
Dirty var5 = (Dirty)var4.next();
var5.markDirty();
}
}
Iterator var6 = var23.iterator();
while (var6.hasNext()) {
Dirty var7 = (Dirty)var6.next();
var7.clearSaving(var24);
}
};
class="kw">return var6 != null ? var14.whenCompleteAsync(var18, var6) : var14.whenComplete(var18);
}
@Override
class="kw">public CompletableFuture<Void> saveEntity(UUID var1, @Nonnull Store<EntityStore> var2, @Nonnull Ref<EntityStore> var3) {
Holder var4 = var2.copySerializableEntity(var3);
class="kw">return this.db.runIo(SneakyThrow.sneakyRunnable(() -> {
RocksDbChunkStorageProvider.Scratch var3 = RocksDbChunkStorageProvider.SCRATCH.get();
long var4 = System.nanoTime();
try {
MemorySegment var6 = var3.keys(16);
RocksDbChunkStorageProvider.putUuidKey(var6, 0L, var1.getMostSignificantBits(), var1.getLeastSignificantBits());
BsonDocument var7 = EntityStore.REGISTRY.serialize(var4);
int var8 = RocksDbChunkStorageProvider.stageValue(var3, var7);
long var9 = System.nanoTime();
RocksDbNative.putCf(this.db.db, this.db.writeOptions, this.db.entityColumn, var6, 16L, var3.value, var8, var3.clearErrPtr());
RocksDbChunkStorageProvider.checkError(var3.errPtr);
long var11 = System.nanoTime();
this.saveCount.getAndIncrement();
this.totalBytesSaved.getAndAdd(var8);
this.serializeStats.record(var9 - var4, var8);
this.writeStats.record(var11 - var9, var8);
} catch (RocksDbChunkStorageProvider.RocksDbException var13) {
this.saveFailureCount.getAndIncrement();
throw var13;
}
}));
}
@Nonnull
@Override
class="kw">public CompletableFuture<Void> removeEntity(@Nonnull UUID var1) {
class="kw">return this.db.runIo(SneakyThrow.sneakyRunnable(() -> {
RocksDbChunkStorageProvider.Scratch var2 = RocksDbChunkStorageProvider.SCRATCH.get();
MemorySegment var3 = var2.keys(16);
RocksDbChunkStorageProvider.putUuidKey(var3, 0L, var1.getMostSignificantBits(), var1.getLeastSignificantBits());
long var4 = System.nanoTime();
try {
RocksDbNative.deleteCf(this.db.db, this.db.writeOptions, this.db.entityColumn, var3, 16L, var2.clearErrPtr());
RocksDbChunkStorageProvider.checkError(var2.errPtr);
} catch (RocksDbChunkStorageProvider.RocksDbException var8) {
this.removeFailureCount.getAndIncrement();
throw var8;
}
long var6 = System.nanoTime() - var4;
this.removeCount.getAndIncrement();
this.removeStats.record(var6, 0L);
}));
}
@Nullable
class="kw">private class="kw">static RocksDbChunkStorageProvider.Saver.BlockComponentsToSave prepareBlockComponentsToSave(
@Nullable BlockComponentSection var0,
boolean var1,
@Nonnull ReferenceArrayList<BlockComponentSection> var2,
@Nonnull ReferenceArrayList<RocksDbChunkStorageProvider.Saver.BlockComponentsToSave> var3
) {
if (var0 == null) {
class="kw">return null;
}
if (var1) {
var0.markAllBlocksNeedsSaving();
}
if (!var0.isSaving() && var0.consumeNeedsSaving()) {
var0.setSaving(true);
var2.add(var0);
RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var4 = snapshotBlockComponents(var0);
if (var4 != null) {
var3.add(var4);
}
class="kw">return var4;
} else {
class="kw">return null;
}
}
@Nullable
class="kw">private class="kw">static RocksDbChunkStorageProvider.Saver.BlockComponentsToSave snapshotBlockComponents(@Nonnull BlockComponentSection var0) {
ShortSet var1 = var0.takeRemovedBlocks();
ShortSet var2 = var0.takeDirtyBlocks();
if (var1 == null && var2 == null) {
class="kw">return null;
}
RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var3 = new RocksDbChunkStorageProvider.Saver.BlockComponentsToSave(var0, var2, var1, false);
try {
if (var1 != null) {
var3.deletes.addAll(var1);
}
if (var2 != null) {
ComponentRegistry.Data var4 = ChunkStore.REGISTRY.getData();
ShortIterator var5 = var2.iterator();
while (var5.hasNext()) {
short var6 = var5.nextShort();
Ref var7 = var0.getBlockReference(var6);
if (var7 != null && var7.isValid()) {
Store var10 = var7.getStore();
if (var10.getArchetype(var7).hasSerializableComponents(var4)) {
var3.putIndexes.add(var6);
var3.putHolders.add(var10.copySerializableEntity(var7));
} else {
var3.deleteDirtyIndex(var6);
}
} else {
Holder var8 = var0.getBlockHolder(var6);
if (var8 != null && var8.hasSerializableComponents(var4)) {
var3.putIndexes.add(var6);
var3.putHolders.add(var8.cloneSerializable(var4));
} else {
var3.deleteDirtyIndex(var6);
}
}
}
}
class="kw">return var3;
} catch (Throwable var9) {
var3.restore();
throw var9;
}
}
class="kw">private class="kw">static int writeBlockComponentRows(
@Nonnull RocksDbChunkStorageProvider.Scratch var0,
@Nonnull MemorySegment var1,
@Nonnull MemorySegment var2,
int var3,
int var4,
int var5,
@Nonnull RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var6
) {
MemorySegment var7 = var0.keys(38);
long var8 = 24L;
if (var6.replaceAll) {
RocksDbChunkStorageProvider.putSectionKey(var7, 0L, var3, var4, var5);
RocksDbChunkStorageProvider.putSectionKey(var7, 12L, var3, var4 + 1, var5);
RocksDbNative.writebatchDeleteRangeCf(var1, var2, var7.asSlice(0L, 12L), 12L, var7.asSlice(12L, 12L), 12L);
}
for (int var10 = 0; var10 < var6.deletes.size(); var10++) {
RocksDbChunkStorageProvider.putBlockComponentKey(var7, 24L, var3, var4, var5, var6.deletes.getShort(var10));
RocksDbNative.writebatchDeleteCf(var1, var2, var7.asSlice(24L, 14L), 14L);
}
int var14 = 0;
for (int var11 = 0; var11 < var6.putIndexes.size(); var11++) {
RocksDbChunkStorageProvider.putBlockComponentKey(var7, 24L, var3, var4, var5, var6.putIndexes.getShort(var11));
BsonDocument var12 = ChunkStore.REGISTRY.serialize((Holder<ChunkStore>)var6.putHolders.get(var11));
int var13 = RocksDbChunkStorageProvider.stageValue(var0, var12);
RocksDbNative.writebatchPutCf(var1, var2, var7.asSlice(24L, 14L), 14L, var0.value, var13);
var14 += var13;
}
class="kw">return var14;
}
@Override
class="kw">public CompletableFuture<Void> saveBlockComponentSection(
int var1, int var2, int var3, @Nonnull Store<ChunkStore> var4, @Nonnull BlockComponentSection var5, @Nullable Executor var6, @Nullable Runnable var7
) {
RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var8 = null;
boolean var10 = false;
CompletableFuture var9;
try {
var8 = snapshotBlockComponents(var5);
if (var8 == null) {
var9 = CompletableFuture.completedFuture(null);
} else {
RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var11 = var8;
var9 = this.db.runIo(SneakyThrow.sneakyRunnable(() -> {
RocksDbChunkStorageProvider.Scratch var5 = RocksDbChunkStorageProvider.SCRATCH.get();
MemorySegment var6 = var5.writeBatch();
long var7 = System.nanoTime();
try {
int var9 = writeBlockComponentRows(var5, var6, this.db.blockComponentColumn, var1, var2, var3, var11);
long var10 = System.nanoTime();
RocksDbNative.write(this.db.db, this.db.writeOptions, var6, var5.clearErrPtr());
RocksDbChunkStorageProvider.checkError(var5.errPtr);
long var12 = System.nanoTime();
this.saveCount.getAndIncrement();
this.totalBytesSaved.getAndAdd(var9);
this.serializeStats.record(var10 - var7, var9);
this.writeStats.record(var12 - var10, var9);
} catch (RocksDbChunkStorageProvider.RocksDbException var17) {
this.saveFailureCount.getAndIncrement();
throw var17;
} class="kw">finally {
RocksDbNative.writebatchClear(var6);
}
}));
}
var10 = true;
} class="kw">finally {
if (!var10 && var8 != null) {
var8.restore();
}
}
if (var7 != null) {
var9.whenComplete((var1x, var2x) -> var7.run());
}
if (var8 == null) {
class="kw">return var9;
}
RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var15 = var8;
BiConsumer var12 = (var1x, var2x) -> {
if (var2x != null) {
var15.restore();
}
};
class="kw">return var6 != null ? var9.whenCompleteAsync(var12, var6) : var9.whenComplete(var12);
}
@Nonnull
@Override
class="kw">public CompletableFuture<Void> saveChunkColumn(
int var1, int var2, @Nonnull Store<ChunkStore> var3, @Nonnull Ref<ChunkStore> var4, @Nullable Executor var5, @Nullable Runnable var6
) {
ReferenceArrayList var7 = new ReferenceArrayList(10);
ReferenceArrayList var8 = new ReferenceArrayList(10);
ReferenceArrayList var9 = new ReferenceArrayList(10);
ReferenceArrayList var10 = new ReferenceArrayList(10);
ReferenceArrayList var11 = new ReferenceArrayList(10);
boolean var13 = false;
CompletableFuture var12;
try {
ReferenceArrayList var14 = new ReferenceArrayList();
ChunkColumn var15 = var3.getComponent(var4, ChunkColumn.getComponentType());
assert var15 != null;
Holder[] var16 = var15.getSectionHolders();
WorldChunk var17 = var3.getComponent(var4, WorldChunk.getComponentType());
assert var17 != null;
boolean var18 = !var17.is(ChunkFlag.ON_DISK);
ReferenceArrayList var19 = new ReferenceArrayList();
ComponentRegistry.Data var20 = EntityStore.REGISTRY.getData();
ComponentRegistry.Data var21 = ChunkStore.REGISTRY.getData();
if (var16 != null) {
for (int var37 = 0; var37 < var16.length; var37++) {
Holder var39 = var16[var37];
if (var39 != null) {
Holder var41 = null;
ChunkSection var43 = var39.getComponent(ChunkSection.getComponentType());
if (!var43.isSaving() && (var43.consumeNeedsSaving() || var18)) {
var43.setSaving(true);
var7.add(var43);
var41 = var39.cloneSerializable(
var21, var0 -> !var0.equals(EntitySection.getComponentType()) && !var0.equals(BlockComponentSection.getComponentType())
);
}
List var44 = null;
EntitySection var45 = var39.getComponent(EntitySection.getComponentType());
if (var45 != null) {
List var46 = var45.getEntityHolders();
if (!var45.isSaving() && var45.consumeNeedsSaving()) {
var45.setSaving(true);
var8.add(var45);
var44 = new ObjectArrayList(var46.size());
collectEntityUuidsFromHolders(var46, var20, var44);
}
snapshotDirtyEntityHolders(var46, var20, var19, var11);
}
RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var47 = prepareBlockComponentsToSave(
var39.getComponent(BlockComponentSection.getComponentType()), var18, var9, var10
);
if (var41 != null || var44 != null || var47 != null) {
var14.add(new RocksDbChunkStorageProvider.Saver.SectionToSave(var1, var37, var2, var41, var44, var47));
}
}
}
} else {
Ref[] var22 = var15.getSections();
for (int var23 = 0; var23 < var22.length; var23++) {
Ref var24 = var22[var23];
if (var24 != null && var24.isValid()) {
Holder var25 = null;
ChunkSection var26 = var3.getComponent(var24, ChunkSection.getComponentType());
if (!var26.isSaving() && (var26.consumeNeedsSaving() || var18)) {
var26.setSaving(true);
var7.add(var26);
var25 = var3.copySerializableEntity(
var24,
ChunkStore.REGISTRY.newHolder(),
var0 -> !var0.equals(EntitySection.getComponentType()) && !var0.equals(BlockComponentSection.getComponentType())
);
}
List var27 = null;
EntitySection var28 = var3.getComponent(var24, EntitySection.getComponentType());
if (var28 != null) {
List var29 = var28.getEntityHolders();
Set var30 = var28.getEntityReferences();
if (!var28.isSaving() && var28.consumeNeedsSaving()) {
var28.setSaving(true);
var8.add(var28);
var27 = new ObjectArrayList(var29.size() + var30.size());
collectEntityUuidsFromHolders(var29, var20, var27);
collectEntityUuidsFromReferences(var30, var20, var27);
}
snapshotDirtyEntityHolders(var29, var20, var19, var11);
snapshotDirtyEntityReferences(var30, var20, var19, var11);
}
RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var48 = prepareBlockComponentsToSave(
var3.getComponent(var24, BlockComponentSection.getComponentType()), var18, var9, var10
);
if (var25 != null || var27 != null || var48 != null) {
var14.add(new RocksDbChunkStorageProvider.Saver.SectionToSave(var1, var23, var2, var25, var27, var48));
}
}
}
}
Holder var38 = var3.copySerializableEntity(var4, ChunkStore.REGISTRY.newHolder(), var0 -> !var0.equals(ChunkColumn.getComponentType()));
var12 = this.submitChunkColumnBatch(var1, var2, var38, var14, var19);
ObjectListIterator var40 = var11.iterator();
while (var40.hasNext()) {
Dirty var42 = (Dirty)var40.next();
var42.setSaving(var12);
}
var13 = true;
} class="kw">finally {
if (!var13) {
ObjectListIterator var32 = var7.iterator();
while (var32.hasNext()) {
ChunkSection var33 = (ChunkSection)var32.next();
var33.markNeedsSaving();
var33.setSaving(false);
}
var32 = var8.iterator();
while (var32.hasNext()) {
EntitySection var53 = (EntitySection)var32.next();
var53.markNeedsSaving();
var53.setSaving(false);
}
var32 = var9.iterator();
while (var32.hasNext()) {
BlockComponentSection var54 = (BlockComponentSection)var32.next();
var54.markNeedsSaving();
var54.setSaving(false);
}
var32 = var10.iterator();
while (var32.hasNext()) {
RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var55 = (RocksDbChunkStorageProvider.Saver.BlockComponentsToSave)var32.next();
var55.restore();
}
var32 = var11.iterator();
while (var32.hasNext()) {
Dirty var56 = (Dirty)var32.next();
var56.markDirty();
}
}
}
if (var6 != null) {
var12.whenComplete((var1x, var2x) -> var6.run());
}
if (var7.isEmpty() && var8.isEmpty() && var9.isEmpty() && var11.isEmpty()) {
class="kw">return var12;
}
BiConsumer var36 = (var6x, var7x) -> {
if (var7x != null) {
Iterator var8 = var7.iterator();
while (var8.hasNext()) {
ChunkSection var9 = (ChunkSection)var8.next();
var9.markNeedsSaving();
}
var8 = var8.iterator();
while (var8.hasNext()) {
EntitySection var18 = (EntitySection)var8.next();
var18.markNeedsSaving();
}
var8 = var9.iterator();
while (var8.hasNext()) {
BlockComponentSection var19 = (BlockComponentSection)var8.next();
var19.markNeedsSaving();
}
var8 = var10.iterator();
while (var8.hasNext()) {
RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var20 = (RocksDbChunkStorageProvider.Saver.BlockComponentsToSave)var8.next();
var20.restore();
}
var8 = var11.iterator();
while (var8.hasNext()) {
Dirty var21 = (Dirty)var8.next();
var21.markDirty();
}
}
Iterator var14 = var7.iterator();
while (var14.hasNext()) {
ChunkSection var22 = (ChunkSection)var14.next();
var22.setSaving(false);
}
var14 = var8.iterator();
while (var14.hasNext()) {
EntitySection var23 = (EntitySection)var14.next();
var23.setSaving(false);
}
var14 = var9.iterator();
while (var14.hasNext()) {
BlockComponentSection var24 = (BlockComponentSection)var14.next();
var24.setSaving(false);
}
var14 = var11.iterator();
while (var14.hasNext()) {
Dirty var25 = (Dirty)var14.next();
var25.clearSaving(var12);
}
};
class="kw">return var5 != null ? var12.whenCompleteAsync(var36, var5) : var12.whenComplete(var36);
}
class="kw">private class="kw">static void collectEntityUuidsFromHolders(
@Nonnull List<Holder<EntityStore>> var0, @Nonnull ComponentRegistry.Data<EntityStore> var1, @Nonnull List<UUID> var2
) {
for (int var3 = 0; var3 < var0.size(); var3++) {
Holder var4 = var0.get(var3);
if (var4.hasSerializableComponents(var1)) {
UUIDComponent var5 = var4.ensureAndGetComponent(UUIDComponent.getComponentType());
var2.add(var5.getUuid());
}
}
}
class="kw">private class="kw">static void snapshotDirtyEntityHolders(
@Nonnull List<Holder<EntityStore>> var0,
@Nonnull ComponentRegistry.Data<EntityStore> var1,
@Nonnull List<Holder<EntityStore>> var2,
@Nonnull List<Dirty> var3
) {
for (int var4 = 0; var4 < var0.size(); var4++) {
Holder var5 = var0.get(var4);
if (var5.hasSerializableComponents(var1)) {
Dirty var6 = var5.getComponent(Dirty.getComponentType());
if (var6 != null) {
if (var6.isSaving() || !var6.isDirty()) {
class="kw">continue;
}
var3.add(var6);
var6.consumeDirty();
}
var2.add(var5.cloneSerializable(var1));
}
}
}
class="kw">private class="kw">static void collectEntityUuidsFromReferences(
@Nonnull Iterable<Ref<EntityStore>> var0, @Nonnull ComponentRegistry.Data<EntityStore> var1, @Nonnull List<UUID> var2
) {
for (Ref var4 : var0) {
Store var5 = var4.getStore();
if (var5.getArchetype(var4).hasSerializableComponents(var1)) {
UUIDComponent var6 = var5.getComponent(var4, UUIDComponent.getComponentType());
assert var6 != null;
var2.add(var6.getUuid());
}
}
}
class="kw">private class="kw">static void snapshotDirtyEntityReferences(
@Nonnull Iterable<Ref<EntityStore>> var0,
@Nonnull ComponentRegistry.Data<EntityStore> var1,
@Nonnull List<Holder<EntityStore>> var2,
@Nonnull List<Dirty> var3
) {
for (Ref var5 : var0) {
Store var6 = var5.getStore();
if (var6.getArchetype(var5).hasSerializableComponents(var1)) {
Dirty var7 = var6.getComponent(var5, Dirty.getComponentType());
if (var7 != null) {
if (var7.isSaving() || !var7.isDirty()) {
class="kw">continue;
}
var3.add(var7);
var7.consumeDirty();
}
var2.add(var6.copySerializableEntity(var5));
}
}
}
@Nonnull
@Override
class="kw">public CompletableFuture<Void> saveHolder(int var1, int var2, @Nonnull Holder<ChunkStore> var3) {
ReferenceArrayList var4 = new ReferenceArrayList();
ChunkColumn var5 = var3.getComponent(ChunkColumn.getComponentType());
var3.removeComponent(ChunkColumn.getComponentType());
ReferenceArrayList var6 = new ReferenceArrayList();
if (var5 != null) {
Holder[] var7 = var5.getSectionHolders();
if (var7 != null) {
for (int var8 = 0; var8 < var7.length; var8++) {
Holder var9 = var7[var8];
if (var9 != null) {
List var10 = null;
EntitySection var11 = var9.getComponent(EntitySection.getComponentType());
if (var11 != null) {
List var12 = var11.getEntityHolders();
var10 = new ObjectArrayList(var12.size());
for (int var13 = 0; var13 < var12.size(); var13++) {
Holder var14 = var12.get(var13);
UUIDComponent var15 = var14.ensureAndGetComponent(UUIDComponent.getComponentType());
var10.add(var15.getUuid());
var6.add(var14);
}
}
RocksDbChunkStorageProvider.Saver.BlockComponentsToSave var16 = null;
BlockComponentSection var17 = var9.getComponent(BlockComponentSection.getComponentType());
if (var17 != null) {
var16 = new RocksDbChunkStorageProvider.Saver.BlockComponentsToSave(null, null, null, true);
ObjectIterator var18 = var17.getBlockHolders().short2ObjectEntrySet().iterator();
while (var18.hasNext()) {
Entry var19 = (Entry<Holder<ChunkStore>>)var18.next();
var16.putIndexes.add(var19.getShortKey());
var16.putHolders.add((Holder)var19.getValue());
}
}
var9.tryRemoveComponent(EntitySection.getComponentType());
var9.tryRemoveComponent(BlockComponentSection.getComponentType());
var4.add(new RocksDbChunkStorageProvider.Saver.SectionToSave(var1, var8, var2, var9, var10, var16));
}
}
}
}
class="kw">return this.submitChunkColumnBatch(var1, var2, var3, var4, var6);
}
class="kw">private CompletableFuture<Void> submitChunkColumnBatch(
int var1,
int var2,
@Nonnull Holder<ChunkStore> var3,
@Nonnull List<RocksDbChunkStorageProvider.Saver.SectionToSave> var4,
@Nonnull List<Holder<EntityStore>> var5
) {
class="kw">return this.db
.runIo(
SneakyThrow.sneakyRunnable(
() -> {
RocksDbChunkStorageProvider.Scratch var6 = RocksDbChunkStorageProvider.SCRATCH.get();
MemorySegment var7 = var6.writeBatch();
long var8 = System.nanoTime();
try {
BsonDocument var10 = ChunkStore.REGISTRY.serialize(var3);
MemorySegment var11 = var6.keys(8);
RocksDbChunkStorageProvider.putChunkKey(var11, 0L, var1, var2);
int var12 = RocksDbChunkStorageProvider.stageValue(var6, var10);
RocksDbNative.writebatchPutCf(var7, this.db.chunkColumn, var11, 8L, var6.value, var12);
int var13 = var12;
for (int var14 = 0; var14 < var4.size(); var14++) {
RocksDbChunkStorageProvider.Saver.SectionToSave var15 = var4.get(var14);
Holder var16 = var15.section;
if (var16 != null) {
BsonDocument var17 = ChunkStore.REGISTRY.serialize(var16);
MemorySegment var18 = var6.keys(12);
RocksDbChunkStorageProvider.putSectionKey(var18, 0L, var15.x, var15.y, var15.z);
int var19 = RocksDbChunkStorageProvider.stageValue(var6, var17);
RocksDbNative.writebatchPutCf(var7, this.db.sectionColumn, var18, 12L, var6.value, var19);
var13 += var19;
}
if (var15.entities != null) {
int var33 = var15.entities.size();
int var35 = 16 * var33;
MemorySegment var37 = var6.keys(12);
RocksDbChunkStorageProvider.putSectionKey(var37, 0L, var15.x, var15.y, var15.z);
MemorySegment var20 = var6.value(var35);
for (int var21 = 0; var21 < var33; var21++) {
UUID var22 = var15.entities.get(var21);
RocksDbChunkStorageProvider.putUuidKey(var20, var21 * 16L, var22.getMostSignificantBits(), var22.getLeastSignificantBits());
}
RocksDbNative.writebatchPutCf(var7, this.db.entitySectionColumn, var37, 12L, var20, var35);
var13 += var35;
}
if (var15.blockComponents != null) {
var13 += writeBlockComponentRows(var6, var7, this.db.blockComponentColumn, var15.x, var15.y, var15.z, var15.blockComponents);
}
}
for (int var28 = 0; var28 < var5.size(); var28++) {
Holder var30 = var5.get(var28);
UUIDComponent var31 = var30.getComponent(UUIDComponent.getComponentType());
if (var31 == null) {
RocksDbChunkStorageProvider.LOGGER
.at(Level.WARNING)
.log("Skipping entity with no UUID component while saving chunk column (%d, %d)", var1, var2);
} else {
UUID var34 = var31.getUuid();
MemorySegment var36 = var6.keys(16);
RocksDbChunkStorageProvider.putUuidKey(var36, 0L, var34.getMostSignificantBits(), var34.getLeastSignificantBits());
BsonDocument var38 = EntityStore.REGISTRY.serialize(var30);
int var39 = RocksDbChunkStorageProvider.stageValue(var6, var38);
RocksDbNative.writebatchPutCf(var7, this.db.entityColumn, var36, 16L, var6.value, var39);
var13 += var39;
}
}
long var29 = System.nanoTime();
RocksDbNative.write(this.db.db, this.db.writeOptions, var7, var6.clearErrPtr());
RocksDbChunkStorageProvider.checkError(var6.errPtr);
long var32 = System.nanoTime();
this.saveCount.getAndIncrement();
this.totalBytesSaved.getAndAdd(var13);
this.serializeStats.record(var29 - var8, var13);
this.writeStats.record(var32 - var29, var13);
} catch (RocksDbChunkStorageProvider.RocksDbException var26) {
this.saveFailureCount.getAndIncrement();
throw var26;
} class="kw">finally {
RocksDbNative.writebatchClear(var7);
}
}
)
);
}
@Nonnull
@Override
class="kw">public CompletableFuture<Void> removeHolder(int var1, int var2) {
class="kw">return this.db.runIo(SneakyThrow.sneakyRunnable(() -> {
RocksDbChunkStorageProvider.Scratch var3 = RocksDbChunkStorageProvider.SCRATCH.get();
MemorySegment var4 = var3.keys(32);
long var5 = 8L;
long var7 = 20L;
RocksDbChunkStorageProvider.putChunkKey(var4, 0L, var1, var2);
RocksDbChunkStorageProvider.putSectionKey(var4, 8L, var1, 0, var2);
RocksDbChunkStorageProvider.putSectionKey(var4, 20L, var1, 10, var2);
long var9 = System.nanoTime();
MemorySegment var11 = var3.writeBatch();
try {
RocksDbNative.writebatchDeleteCf(var11, this.db.chunkColumn, var4.asSlice(0L, 8L), 8L);
MemorySegment var12 = var4.asSlice(8L, 12L);
MemorySegment var13 = var4.asSlice(20L, 12L);
RocksDbNative.writebatchDeleteRangeCf(var11, this.db.sectionColumn, var12, 12L, var13, 12L);
RocksDbNative.writebatchDeleteRangeCf(var11, this.db.entitySectionColumn, var12, 12L, var13, 12L);
RocksDbNative.writebatchDeleteRangeCf(var11, this.db.blockComponentColumn, var12, 12L, var13, 12L);
RocksDbNative.write(this.db.db, this.db.writeOptions, var11, var3.clearErrPtr());
RocksDbChunkStorageProvider.checkError(var3.errPtr);
} catch (RocksDbChunkStorageProvider.RocksDbException var17) {
this.removeFailureCount.getAndIncrement();
throw var17;
} class="kw">finally {
RocksDbNative.writebatchClear(var11);
}
long var19 = System.nanoTime() - var9;
this.removeCount.getAndIncrement();
this.removeStats.record(var19, 0L);
}));
}
@Nonnull
@Override
class="kw">public LongList getIndexes() class="kw">throws IOException {
class="kw">return RocksDbChunkStorageProvider.chunkIndexesFromColumn(this.db);
}
@Override
class="kw">public void flush() class="kw">throws IOException {
try (Arena var1 = Arena.ofConfined()) {
MemorySegment var2 = var1.allocate(RocksDbNative.C_POINTER);
var2.set(RocksDbNative.C_POINTER, 0L, MemorySegment.NULL);
RocksDbNative.flush(this.db.db, this.db.flushOptions, var2);
try {
RocksDbChunkStorageProvider.checkError(var2);
} catch (RocksDbChunkStorageProvider.RocksDbException var5) {
throw new IOException(var5);
}
this.flushCount.getAndIncrement();
}
}
@Nonnull
@Override
class="kw">public CompletableFuture<Void> compact(@Nullable long[] var1) {
class="kw">return this.db.runIo(SneakyThrow.sneakyRunnable(() -> {
byte[] var2 = null;
byte[] var3 = null;
if (var1 != null && var1.length > 0) {
byte[] var4 = null;
byte[] var5 = null;
for (long var9 : var1) {
byte[] var11 = RocksDbChunkStorageProvider.toKey(ChunkUtil.xOfChunkIndex(var9), ChunkUtil.zOfChunkIndex(var9));
if (var4 == null || Arrays.compareUnsigned(var11, var4) < 0) {
var4 = var11;
}
if (var5 == null || Arrays.compareUnsigned(var11, var5) > 0) {
var5 = var11;
}
}
var2 = var4;
var3 = new byte[var5.length + 1];
System.arraycopy(var5, 0, var3, 0, var5.length);
}
try (Arena var19 = Arena.ofConfined()) {
MemorySegment var20 = RocksDbNative.compactoptionsCreate();
try {
RocksDbNative.compactoptionsSetBottommostLevelCompaction(var20, (byte)3);
MemorySegment var21 = RocksDbChunkStorageProvider.toNativeKey(var19, var2);
long var22 = var2 == null ? 0L : var2.length;
MemorySegment var23 = RocksDbChunkStorageProvider.toNativeKey(var19, var3);
long var10 = var3 == null ? 0L : var3.length;
RocksDbNative.compactRangeCfOpt(this.db.db, this.db.chunkColumn, var20, var21, var22, var23, var10);
RocksDbNative.compactRangeCfOpt(this.db.db, this.db.sectionColumn, var20, var21, var22, var23, var10);
RocksDbNative.compactRangeCfOpt(this.db.db, this.db.entitySectionColumn, var20, var21, var22, var23, var10);
RocksDbNative.compactRangeCfOpt(this.db.db, this.db.blockComponentColumn, var20, var21, var22, var23, var10);
if (var2 == null) {
RocksDbNative.compactRangeCfOpt(this.db.db, this.db.entityColumn, var20, MemorySegment.NULL, 0L, MemorySegment.NULL, 0L);
}
this.compactCount.getAndIncrement();
} class="kw">finally {
RocksDbNative.compactoptionsDestroy(var20);
}
}
}));
}
@Override
class="kw">public void close() class="kw">throws IOException {
}
@Override
class="kw">public void pauseBackgroundSaving(ChunkSavingSystems.Data var1) {
var1.pushSavingFuture(this.db.runIo(SneakyThrow.sneakyRunnable(() -> {
try (Arena var1 = Arena.ofConfined()) {
MemorySegment var2 = var1.allocate(RocksDbNative.C_POINTER);
var2.set(RocksDbNative.C_POINTER, 0L, MemorySegment.NULL);
RocksDbNative.pauseBackgroundWork(this.db.db, var2);
RocksDbChunkStorageProvider.checkError(var2);
}
})));
}
@Nonnull
@Override
class="kw">public CompletableFuture<Void> resumeBackgroundSaving() {
class="kw">return this.db.runIo(SneakyThrow.sneakyRunnable(() -> {
try (Arena var1 = Arena.ofConfined()) {
MemorySegment var2 = var1.allocate(RocksDbNative.C_POINTER);
var2.set(RocksDbNative.C_POINTER, 0L, MemorySegment.NULL);
RocksDbNative.continueBackgroundWork(this.db.db, var2);
RocksDbChunkStorageProvider.checkError(var2);
}
}));
}
@Nonnull
@Override
class="kw">public MetricResults toMetricResults() {
class="kw">return METRICS_REGISTRY.toMetricResults(this);
}
class="kw">private class="kw">static class="kw">final class BlockComponentsToSave {
@Nullable
class="kw">private class="kw">final BlockComponentSection section;
@Nullable
class="kw">private class="kw">final ShortSet dirty;
@Nullable
class="kw">private ShortSet removed;
class="kw">private class="kw">final boolean replaceAll;
class="kw">private class="kw">final ShortArrayList deletes = new ShortArrayList();
class="kw">private class="kw">final ShortArrayList putIndexes = new ShortArrayList();
class="kw">private class="kw">final ObjectArrayList<Holder<ChunkStore>> putHolders = new ObjectArrayList();
class="kw">private BlockComponentsToSave(@Nullable BlockComponentSection var1, @Nullable ShortSet var2, @Nullable ShortSet var3, boolean var4) {
this.section = var1;
this.dirty = var2;
this.removed = var3;
this.replaceAll = var4;
}
class="kw">private void deleteDirtyIndex(short var1) {
this.deletes.add(var1);
if (this.removed == null) {
this.removed = new ShortOpenHashSet();
}
this.removed.add(var1);
}
class="kw">private void restore() {
if (this.section != null) {
this.section.restoreSaveFailure(this.dirty, this.removed);
}
}
}
class="kw">private record SectionToSave(
int x,
int y,
int z,
@Nullable Holder<ChunkStore> section,
@Nullable List<UUID> entities,
@Nullable RocksDbChunkStorageProvider.Saver.BlockComponentsToSave blockComponents
) {
class="kw">private SectionToSave {
}
}
}
class="kw">private class="kw">static class="kw">final class Scratch {
class="kw">private class="kw">final MemorySegment errPtr = Arena.ofAuto().allocate(RocksDbNative.C_POINTER);
class="kw">private MemorySegment keys = Arena.ofAuto().allocate(256L);
class="kw">private MemorySegment value = Arena.ofAuto().allocate(8192L);
class="kw">private MemorySegment cfPtrs = Arena.ofAuto().allocate(RocksDbNative.C_POINTER, 8L);
class="kw">private MemorySegment keyPtrs = Arena.ofAuto().allocate(RocksDbNative.C_POINTER, 8L);
class="kw">private MemorySegment keyLens = Arena.ofAuto().allocate(RocksDbNative.C_SIZE_T, 8L);
class="kw">private MemorySegment valuePtrs = Arena.ofAuto().allocate(RocksDbNative.C_POINTER, 8L);
class="kw">private MemorySegment valueLens = Arena.ofAuto().allocate(RocksDbNative.C_SIZE_T, 8L);
class="kw">private MemorySegment errs = Arena.ofAuto().allocate(RocksDbNative.C_POINTER, 8L);
class="kw">private int arrayCapacity = 8;
class="kw">private class="kw">final BasicOutputBuffer bson = new BasicOutputBuffer();
class="kw">private MemorySegment writeBatch;
class="kw">private Scratch() {
}
class="kw">private MemorySegment clearErrPtr() {
this.errPtr.set(RocksDbNative.C_POINTER, 0L, MemorySegment.NULL);
class="kw">return this.errPtr;
}
class="kw">private MemorySegment keys(int var1) {
if (var1 < 0) {
throw new IllegalArgumentException("negative key scratch size: " + var1);
}
if (this.keys.byteSize() < var1) {
this.keys = Arena.ofAuto().allocate(Math.max(var1, this.keys.byteSize() * 2L));
}
class="kw">return this.keys;
}
class="kw">private MemorySegment value(int var1) {
if (var1 < 0) {
throw new IllegalArgumentException("negative value scratch size: " + var1);
}
if (this.value.byteSize() < var1) {
this.value = Arena.ofAuto().allocate(Math.max(var1, this.value.byteSize() * 2L));
}
class="kw">return this.value;
}
class="kw">private void ensureArrays(int var1) {
if (var1 < 0) {
throw new IllegalArgumentException("negative multiGet count: " + var1);
}
if (this.arrayCapacity < var1) {
int var2 = Math.max(var1, this.arrayCapacity * 2);
this.cfPtrs = Arena.ofAuto().allocate(RocksDbNative.C_POINTER, var2);
this.keyPtrs = Arena.ofAuto().allocate(RocksDbNative.C_POINTER, var2);
this.keyLens = Arena.ofAuto().allocate(RocksDbNative.C_SIZE_T, var2);
this.valuePtrs = Arena.ofAuto().allocate(RocksDbNative.C_POINTER, var2);
this.valueLens = Arena.ofAuto().allocate(RocksDbNative.C_SIZE_T, var2);
this.errs = Arena.ofAuto().allocate(RocksDbNative.C_POINTER, var2);
this.arrayCapacity = var2;
}
}
class="kw">private MemorySegment writeBatch() {
if (this.writeBatch == null) {
this.writeBatch = RocksDbNative.writebatchCreate();
} else {
RocksDbNative.writebatchClear(this.writeBatch);
}
class="kw">return this.writeBatch;
}
class="kw">private void destroy() {
if (this.writeBatch != null) {
RocksDbNative.writebatchDestroy(this.writeBatch);
this.writeBatch = null;
}
}
}
}