public long removeAndEstimateCount(byte[] value) {
return pool.safelyReturn(jedis -> {
int[] hashes = hash(value);
String[] hashesString = encode(hashes);
Pipeline p = jedis.pipelined();
p.watch(keys.COUNTS_KEY, keys.BITS_KEY);
List<Long> counts;
List<Response<Long>> responses = new ArrayList<>(config().hashes());
for (String position : hashesString) {
responses.add(p.hincrBy(keys.COUNTS_KEY, position, -1));
}
p.sync();
counts = responses.stream().map(Response::get).collect(Collectors.toList());
while (true) {
p = jedis.pipelined();
p.multi();
for (int i = 0; i < config().hashes(); i++) {
if (counts.get(i) <= 0)
bloom.set(p, hashes[i], false);
}
Response<List<Object>> exec = p.exec();
p.sync();
if (exec.get() == null) {
p = jedis.pipelined();
p.watch(keys.COUNTS_KEY, keys.BITS_KEY);
Response<List<String>> hmget = p.hmget(keys.COUNTS_KEY, hashesString);
p.sync();
counts = hmget.get().stream().map(Long::valueOf).collect(Collectors.toList());
} else {
return Collections.min(counts);
}
}