-
-
Save sankarcheppali/579de3a02b88dc6af5986567825bae4c to your computer and use it in GitHub Desktop.
Using redis bloom filters with Spring redis-template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.icircuit.bf.redis; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.beans.factory.annotation.Qualifier; | |
import org.springframework.data.redis.core.RedisCallback; | |
import org.springframework.data.redis.core.RedisTemplate; | |
import org.springframework.stereotype.Component; | |
import java.util.Arrays; | |
import java.util.List; | |
import java.util.Set; | |
import java.util.stream.IntStream; | |
import java.util.stream.Stream; | |
import static java.util.stream.Collectors.toSet; | |
@Component | |
public class RedisBloomFilter { | |
RedisTemplate<String, String> redisTemplate; | |
/** | |
* spring redis template backed by jedis driver | |
*/ | |
@Autowired | |
public RedisBloomFilter(RedisTemplate<String, String> redisTemplate) { | |
this.redisTemplate = redisTemplate; | |
} | |
private static final String BF_MULTI_ADD = "BF.MADD"; | |
private static final String BF_MULTI_FIND = "BF.MEXISTS"; | |
/** | |
* returns entries that were not present previously in the bloom filter and were added | |
*/ | |
public Set<String> put(String filterName, Set<String> entries) { | |
return runCmd(BF_MULTI_ADD, filterName, entries); | |
} | |
/** | |
* returns entries that were present in the bloom filter | |
*/ | |
public Set<String> get(String filterName, Set<String> entries) { | |
return runCmd(BF_MULTI_FIND, filterName, entries); | |
} | |
private Set<String> runCmd(String bfOp, String key, Set<String> entries) { | |
return redisTemplate.execute((RedisCallback<Set<String>>) connection -> { | |
final String[] entriesArr = entries.toArray(new String[0]); | |
byte[][] args = Stream.concat(Stream.of(key), Arrays.stream(entriesArr)) | |
.map(String::getBytes) | |
.toArray(byte[][]::new); | |
List<Number> result = (List<Number>) connection.execute(bfOp, args); | |
return IntStream.range(0, result.size()) | |
.filter(index -> result.get(index).intValue() == 1) | |
.mapToObj(index -> entriesArr[index]) | |
.collect(toSet()); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment