@Test public void testParallelLeveledCompaction() throws Exception { String ksname = "Keyspace1"; String cfname = "StandardLeveled"; Keyspace keyspace = Keyspace.open(ksname); ColumnFamilyStore store = keyspace.getColumnFamilyStore(cfname); store.disableAutoCompaction(); LeveledCompactionStrategy lcs = (LeveledCompactionStrategy) store.getCompactionStrategy(); ByteBuffer value = ByteBuffer.wrap(new byte[100 * 1024]); // 100 KB value, make it easy to have multiple files // Enough data to have a level 1 and 2 int rows = 128; int columns = 10; // Adds enough data to trigger multiple sstable per level for (int r = 0; r < rows; r++) { DecoratedKey key = Util.dk(String.valueOf(r)); RowMutation rm = new RowMutation(ksname, key.key); for (int c = 0; c < columns; c++) { rm.add(cfname, ByteBufferUtil.bytes("column" + c), value, 0); } rm.apply(); store.forceBlockingFlush(); } // Execute LCS in parallel ExecutorService executor = new ThreadPoolExecutor( 4, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>()); List<Runnable> tasks = new ArrayList<Runnable>(); while (true) { while (true) { final AbstractCompactionTask t = lcs.getMaximalTask(Integer.MIN_VALUE); if (t == null) break; tasks.add( new Runnable() { public void run() { t.execute(null); } }); } if (tasks.isEmpty()) break; List<Future<?>> futures = new ArrayList<Future<?>>(tasks.size()); for (Runnable r : tasks) futures.add(executor.submit(r)); FBUtilities.waitOnFutures(futures); tasks.clear(); } // Assert all SSTables are lined up correctly. LeveledManifest manifest = lcs.manifest; int levels = manifest.getLevelCount(); for (int level = 0; level < levels; level++) { List<SSTableReader> sstables = manifest.getLevel(level); // score check assert (double) SSTable.getTotalBytes(sstables) / manifest.maxBytesForLevel(level) < 1.00; // overlap check for levels greater than 0 if (level > 0) { for (SSTableReader sstable : sstables) { Set<SSTableReader> overlaps = LeveledManifest.overlapping(sstable, sstables); assert overlaps.size() == 1 && overlaps.contains(sstable); } } } for (SSTableReader sstable : store.getSSTables()) { assert sstable.getSSTableLevel() == sstable.getSSTableLevel(); } }