2525
2626import java .util .*;
2727import java .util .concurrent .CompletableFuture ;
28- import java .util .concurrent .ExecutionException ;
2928import java .util .concurrent .ExecutorService ;
3029import java .util .concurrent .Executors ;
3130import java .util .stream .Collectors ;
@@ -350,50 +349,46 @@ public void testBasic()
350349 @ Test
351350 public void testFullCompaction () throws RocksDBException
352351 {
353- // Define the list of RocksDB paths
352+ // List of RocksDB storage paths
354353 List <String > dbPaths = new ArrayList <>();
355354 dbPaths .add ("/home/ubuntu/disk6/collected_indexes/realtime-pixels-retina/" + "/rocksdb" );
356- for (int i = 2 ; i <= 8 ; i ++)
357- {
358- dbPaths .add (
359- "/home/ubuntu/disk6/collected_indexes/realtime-pixels-retina-" + i + "/rocksdb"
360- );
361- }
355+ // for (int i = 2; i <= 8; i++)
356+ // {
357+ // dbPaths.add(
358+ // "/home/ubuntu/disk6/collected_indexes/realtime-pixels-retina-" + i + "/rocksdb"
359+ // );
360+ // }
362361
363362 long totalStart = System .currentTimeMillis ();
364363 System .out .println ("Starting parallel compaction for " + dbPaths .size () + " databases." );
365- // Define parallelism level (e.g., number of disks or cores)
366- int parallelism = 4 ;
367- ExecutorService executor = Executors .newFixedThreadPool (parallelism );
364+
365+ // Parallelism level for multiple databases (usually matches the number of disks)
366+ int dbParallelism = 4 ;
367+ ExecutorService dbExecutor = Executors .newFixedThreadPool (dbParallelism );
368+
368369 try
369370 {
371+ // Map each database path to an asynchronous compaction task
370372 List <CompletableFuture <Void >> futures = dbPaths .stream ()
371373 .map (dbPath -> CompletableFuture .runAsync (() ->
372374 {
373375 try
374376 {
375377 executeSingleDbCompaction (dbPath );
376- } catch (RocksDBException e )
378+ }
379+ catch (RocksDBException e )
377380 {
378- throw new RuntimeException (e );
381+ throw new RuntimeException ("Compaction failed for " + dbPath , e );
379382 }
380- }, executor ))
383+ }, dbExecutor ))
381384 .collect (Collectors .toList ());
382385
383- // Block until all compaction tasks are complete
384- for (CompletableFuture <Void > future : futures )
385- {
386- future .get ();
387- }
388- } catch (ExecutionException e )
389- {
390- throw new RuntimeException (e );
391- } catch (InterruptedException e )
392- {
393- throw new RuntimeException (e );
394- } finally
386+ // Wait for all DB-level tasks to finish
387+ CompletableFuture .allOf (futures .toArray (new CompletableFuture [0 ])).join ();
388+ }
389+ finally
395390 {
396- executor .shutdown ();
391+ dbExecutor .shutdown ();
397392 }
398393
399394 long totalEnd = System .currentTimeMillis ();
@@ -402,36 +397,59 @@ public void testFullCompaction() throws RocksDBException
402397
403398 private void executeSingleDbCompaction (String dbPath ) throws RocksDBException
404399 {
405- long openStart = System .currentTimeMillis ();
406- System .out .println ("Thread [" + Thread .currentThread ().getName () + "] Start Open: " + dbPath );
400+ long startTime = System .currentTimeMillis ();
401+ System .out .println ("Thread [" + Thread .currentThread ().getName () + "] Opening DB: " + dbPath );
402+
407403 RocksDB rocksDB ;
408404 Map <String , ColumnFamilyHandle > cfHandles ;
409405
410- long start = System . currentTimeMillis ();
406+ // Synchronized block to safely initialize the RocksDB instance and retrieve handles
411407 synchronized (this )
412408 {
413409 rocksDB = RocksDBFactory .createRocksDB (dbPath );
414- long openEnd = System .currentTimeMillis ();
415- System .out .println ("Open Duration: " + (openEnd - openStart ) + "ms\t Path: " + dbPath );
416410 cfHandles = new HashMap <>(RocksDBFactory .getAllCfHandles ());
411+ // Clear handles in the factory to prevent memory leaks or reuse conflicts
417412 RocksDBFactory .clearCFHandles ();
418413 }
419414
420- System .out .println ("Path: " + dbPath + " | Column Family Count: " + cfHandles .size ());
421- // Iterate through each Column Family for manual compaction
422- for (Map .Entry <String , ColumnFamilyHandle > entry : cfHandles .entrySet ())
415+ System .out .println ("Path: " + dbPath + " | CF Count: " + cfHandles .size ());
416+
417+ // Use parallel stream to compact multiple Column Families simultaneously
418+ // This allows RocksDB background threads to work on different CFs at once
419+ cfHandles .entrySet ().parallelStream ().forEach (entry ->
423420 {
424421 String cfName = entry .getKey ();
425422 ColumnFamilyHandle handle = entry .getValue ();
426423
427- System .out .println ("Compacting CF [" + cfName + "] in " + dbPath );
424+ try
425+ {
426+ System .out .println ("Compacting CF [" + cfName + "] in " + dbPath );
428427
429- // This is a blocking call per Column Family
430- rocksDB .compactRange (handle );
431- handle .close ();
432- }
433- long end = System .currentTimeMillis ();
434- System .out .println ("SUCCESS: Compaction Duration: " + (end - start ) + "ms\t Path: " + dbPath );
428+ // Configure CompactRangeOptions to force a rewrite of the bottommost level
429+ // This is mandatory to apply the new 20-bit Bloom Filter configuration
430+ CompactRangeOptions options = new CompactRangeOptions ()
431+ .setBottommostLevelCompaction (CompactRangeOptions .BottommostLevelCompaction .kForce )
432+ .setMaxSubcompactions (4 ) // Parallel threads within a single CF compaction job
433+ .setAllowWriteStall (true );
434+
435+ // Synchronous call per CF, but parallelized by the parallelStream
436+ rocksDB .compactRange (handle , null , null , options );
437+
438+ System .out .println ("Finished CF [" + cfName + "] in " + dbPath );
439+ }
440+ catch (RocksDBException e )
441+ {
442+ System .err .println ("Error during compaction for CF " + cfName + ": " + e .getMessage ());
443+ }
444+ finally
445+ {
446+ // Close handles to release native memory
447+ handle .close ();
448+ }
449+ });
450+
451+ long endTime = System .currentTimeMillis ();
452+ System .out .println ("SUCCESS: Path: " + dbPath + " | Duration: " + (endTime - startTime ) + "ms" );
435453 rocksDB .close ();
436454 }
437455}
0 commit comments