RankedSet { public CompletableFuture<Boolean> add(TransactionContext tc, byte[] key) { checkKey(key); final int keyHash = getKeyHash(key); return tc.runAsync(tr -> countCheckedKey(tr, key) .thenCompose(count -> { final boolean duplicate = count != null && count > 0; if (duplicate && !config.isCountDuplicates()) { return READY_FALSE; } final int nlevels = config.getNLevels(); List<CompletableFuture<Void>> futures = new ArrayList<>(nlevels); for (int li = 0; li < nlevels; ++li) { final int level = li; CompletableFuture<Void> future; if (level == 0) { future = addLevelZeroKey(tr, key, level, duplicate); } else if (duplicate || (keyHash & LEVEL_FAN_VALUES[level]) != 0) { future = addIncrementLevelKey(tr, key, level, duplicate); } else { future = AsyncUtil.whenAll(futures); futures = new ArrayList<>(nlevels - li); future = future.thenCompose(vignore -> addInsertLevelKey(tr, key, level)); } futures.add(future); } return AsyncUtil.whenAll(futures).thenApply(vignore -> true); })); } RankedSet(Subspace subspace, Executor executor, Config config);  RankedSet(Subspace subspace, Executor executor, HashFunction hashFunction, int nlevels);  RankedSet(Subspace subspace, Executor executor, int nlevels);  RankedSet(Subspace subspace, Executor executor); static ConfigBuilder newConfigBuilder(); CompletableFuture<Void> init(TransactionContext tc); CompletableFuture<Boolean> initNeeded(ReadTransactionContext tc); CompletableFuture<Boolean> add(TransactionContext tc, byte[] key); CompletableFuture<Boolean> remove(TransactionContext tc, byte[] key); CompletableFuture<Void> clear(TransactionContext tc); CompletableFuture<Boolean> contains(ReadTransactionContext tc, byte[] key); CompletableFuture<Long> count(ReadTransactionContext tc, byte[] key); CompletableFuture<byte[]> getNth(ReadTransactionContext tc, long rank); List<byte[]> getRangeList(ReadTransactionContext tc, byte[] beginKey, byte[] endKey); AsyncIterable<byte[]> getRange(ReadTransaction tr, byte[] beginKey, byte[] endKey); CompletableFuture<Void> preloadForLookup(ReadTransaction tr); CompletableFuture<Long> rank(ReadTransactionContext tc, byte[] key); CompletableFuture<Long> rank(ReadTransactionContext tc, byte[] key, boolean nullIfMissing); CompletableFuture<Long> size(ReadTransactionContext tc); static final HashFunction JDK_ARRAY_HASH; static final HashFunction CRC_HASH; static final HashFunction RANDOM_HASH; static final HashFunction DEFAULT_HASH_FUNCTION; static final int MAX_LEVELS; static final int DEFAULT_LEVELS; static final Config DEFAULT_CONFIG; }
@Test @Tag(Tags.Slow) public void randomFiveThreads() throws InterruptedException { List<Throwable> uncaught = Collections.synchronizedList(new ArrayList<>()); Thread[] threads = new Thread[5]; for (int i = 0; i < threads.length; ++i) { threads[i] = new Thread(() -> { thousandRankedSetOps(db, newRankedSet()); }, "RSTest" + i); threads[i].setUncaughtExceptionHandler((t, e) -> uncaught.add(e)); } for (Thread t : threads) { t.start(); } for (Thread t : threads) { t.join(60 * 1000); } assertEquals("[]", uncaught.toString()); }