布谷鸟过滤器核心代码

发布时间 2023-06-28 09:53:09作者: 莫等流年闲
private boolean writeBits(long curIndex, long tag, Boolean bitValue) {
CommandBatchService executorService = new CommandBatchService(commandExecutor);
RBitSetAsync bs = redisUtils.createBitSet(executorService);
// 判断curIndex出是否已有值
log.info("writeBits:tag-bit:{}", Long.toBinaryString(tag));
for (int i = 0; i < BUCKET_SIZE; i++) {
// todo 检查与下面的设置要加同步锁才能保证原子性,检查index出i位置是否已存在tag。与redission的bloom过滤器无需加锁不同,
// 因为它不是一个桶只存放一个元素,而是元素共用bit位,添加元素时,只要有一个bit位从0变成1,则表示添加成功,否则失败。
// 所以利用redis本身的单进程处理实现了put的原子性,而线程安全
if (isExistTag(curIndex, i, tag) == bitValue) {
log.info("writeBits:continue:{}", i);
continue;
}
long[] bitIndexes = getPosOfTrue(curIndex, i, tag);
System.out.println("writeBits:bitIndexes:" + JSON.toJSONString(bitIndexes));
for (long bitIndex : bitIndexes) {
// 将位下标对应位设置1或0
if (bitIndex != -1) {
bs.setAsync(bitIndex, bitValue);
}
}
// 返回修改前的值,若是插入值,这里应该全部返回true,否则返回false
List<Boolean> results = (List<Boolean>) executorService.execute().getResponses();
log.info("writeBits:results:{}", JSON.toJSONString(results));
// for (Boolean val : results.subList(1, results.size() - 1)) {
// if (val.equals(bitValue)) {
// isExistTag(curIndex, i, tag);
// System.out.println("writeBits:true");
// return bitValue;
// }
// }
return true;
}
// System.out.println("writeBits:false");
return false;
}

private boolean isExistTag(long curIndex, int posInBucket, long tag) {
// 检查指定桶的pos处是否存在tag
log.info("checkTag:curIndex:" + curIndex + ",posInBucket:" + posInBucket + ",tag:" + tag);
CommandBatchService executorService = new CommandBatchService(commandExecutor);
RBitSetAsync bs = redisUtils.createBitSet(executorService);
long startPos = curIndex * BUCKET_SIZE * BITS_PER_TAG + (long) posInBucket * BITS_PER_TAG;
long endPos = startPos + BITS_PER_TAG;
for (long i = startPos; i < endPos; i++) {
bs.getAsync(i);
}
List<Boolean> result = (List<Boolean>) executorService.execute().getResponses();
// System.out.println("checkTag:results:" + JSON.toJSONString(result));
for (int i = 0; i < BITS_PER_TAG; i++) {
// 比如tag=15,bit表示0000 0000 0000 1111
if (((tag & (1L << i)) == 0) == result.get(i)) {
// 有一个bit不相同,就表示不存在,返回false
return false;
}
}
// System.out.println("checkTag:results:-----------true---------------------------");
return true;
}