From 177ff0c9cbcb5f56766678fb1b49ad52f0b59f3a Mon Sep 17 00:00:00 2001 From: Maciej Szeszko Date: Wed, 22 Jan 2025 13:11:56 -0800 Subject: [PATCH] WIP --- .../java/org/rocksdb/EventListenerTest.java | 71 +++++++++++++++---- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/java/src/test/java/org/rocksdb/EventListenerTest.java b/java/src/test/java/org/rocksdb/EventListenerTest.java index 8e36a230298f..7a32beb885ec 100644 --- a/java/src/test/java/org/rocksdb/EventListenerTest.java +++ b/java/src/test/java/org/rocksdb/EventListenerTest.java @@ -73,23 +73,66 @@ public void onFlushBegin(final RocksDB rocksDb, final FlushJobInfo flushJobInfo) flushDb(onFlushBeginListener, wasCbCalled); } + + // TODO(mszeszko): This is just a temporary copy-pasta from RocksDBTest.java + // to see if we can trigger on file table deletion callback. If it works, + // we'll use similar but simpler approach in the final version. void deleteTableFile(final AbstractEventListener el, final AtomicBoolean wasCbCalled) throws RocksDBException { - try (final Options opt = - new Options().setCreateIfMissing(true).setListeners(Collections.singletonList(el)); + final int KEY_SIZE = 20; + final int VALUE_SIZE = 1000; + final int FILE_SIZE = 64000; + final int NUM_FILES = 10; + + final int KEY_INTERVAL = 10000; + /* + * Intention of these options is to end up reliably with 10 files + * we will be deleting using deleteFilesInRange. + * It is writing roughly number of keys that will fit in 10 files (target size) + * It is writing interleaved so that files from memory on L0 will overlap + * Then compaction cleans everything, and we should end up with 10 files + */ + try (final Options opt = new Options() + .setCreateIfMissing(true) + .setCompressionType(CompressionType.NO_COMPRESSION) + .setTargetFileSizeBase(FILE_SIZE) + .setWriteBufferSize(FILE_SIZE / 2) + .setDisableAutoCompactions(true) + .setLevelCompactionDynamicLevelBytes(false); final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) { - assertThat(db).isNotNull(); - final byte[] value = new byte[24]; - rand.nextBytes(value); - db.put("testKey".getBytes(), value); - final RocksDB.LiveFiles liveFiles = db.getLiveFiles(); - assertThat(liveFiles).isNotNull(); - assertThat(liveFiles.files).isNotNull(); - assertThat(liveFiles.files.isEmpty()).isFalse(); - db.delete("testKey".getBytes()); - final FlushOptions flushOptions = new FlushOptions(); - db.flush(flushOptions); - db.compactRange("testKey".getBytes(), null); + final int records = FILE_SIZE / (KEY_SIZE + VALUE_SIZE); + + // fill database with key/value pairs + final byte[] value = new byte[VALUE_SIZE]; + int key_init = 0; + for (int o = 0; o < NUM_FILES; ++o) { + int int_key = key_init++; + for (int i = 0; i < records; ++i) { + int_key += KEY_INTERVAL; + rand.nextBytes(value); + + db.put(String.format("%020d", int_key).getBytes(), value); + } + } + try (final FlushOptions flushOptions = new FlushOptions().setWaitForFlush(true)) { + db.flush(flushOptions); + } + db.compactRange(); + // Make sure we do create one more L0 files. + assertThat(db.getProperty("rocksdb.num-files-at-level0")).isEqualTo("0"); + + // Should be 10, but we are OK with asserting +- 2 + int files = Integer.parseInt(db.getProperty("rocksdb.num-files-at-level1")); + assertThat(files).isBetween(8, 12); + + // Delete lower 60% (roughly). Result should be 5, but we are OK with asserting +- 2 + // Important is that we know something was deleted (JNI call did something) + // Exact assertions are done in C++ unit tests + db.deleteFilesInRanges(null, + Arrays.asList(null, String.format("%020d", records * KEY_INTERVAL * 6 / 10).getBytes()), + false); + files = Integer.parseInt(db.getProperty("rocksdb.num-files-at-level1")); + assertThat(files).isBetween(3, 7); assertThat(wasCbCalled.get()).isTrue(); } }