Objects
Object holder¶
Java implementation of Valkey or Redis based RBucket object is a holder for any type of object. Size is limited to 512Mb. This object is thread-safe.
Code examples:
RBucket<AnyObject> bucket = redisson.getBucket("anyObject");
RFuture<Void> future = bucket.setAsync(new AnyObject(1));
RFuture<AnyObject> objfuture = bucket.getAsync();
RFuture<Boolean> tsFuture = bucket.trySetAsync(new AnyObject(3));
RFuture<Boolean> csFuture = bucket.compareAndSetAsync(new AnyObject(4), new AnyObject(5));
RFuture<AnyObject> gsFuture = bucket.getAndSetAsync(new AnyObject(6));
RedissonReactiveClient redisson = redissonClient.reactive();
RBucketReactive<AnyObject> bucket = redisson.getBucket("anyObject");
Mono<Void> mono = bucket.set(new AnyObject(1));
Mono<AnyObject> objMono = bucket.get();
Mono<Boolean> tsMono = bucket.trySet(new AnyObject(3));
Mono<Boolean> csMono = bucket.compareAndSet(new AnyObject(4), new AnyObject(5));
Mono<AnyObject> gsMono = bucket.getAndSet(new AnyObject(6));
RedissonRxClient redisson = redissonClient.rxJava();
RBucketRx<AnyObject> bucket = redisson.getBucket("anyObject");
Completable rx = bucket.set(new AnyObject(1));
Maybe<AnyObject> objRx = bucket.get();
Single<Boolean> tsRx = bucket.trySet(new AnyObject(3));
Single<Boolean> csRx = bucket.compareAndSet(new AnyObject(4), new AnyObject(5));
Maybe<AnyObject> gsRx = bucket.getAndSet(new AnyObject(6));
Use RBuckets interface to execute operations over multiple RBucket objects:
Code examples:
RBuckets buckets = redisson.getBuckets();
// get all bucket values
Map<String, V> loadedBuckets = buckets.get("myBucket1", "myBucket2", "myBucket3");
Map<String, Object> map = new HashMap<>();
map.put("myBucket1", new MyObject());
map.put("myBucket2", new MyObject());
// sets all or nothing if some bucket is already exists
buckets.trySet(map);
// store all at once
buckets.set(map);
RBuckets buckets = redisson.getBuckets();
// get all bucket values
RFuture<Map<String, V>> bucketsFuture = buckets.getAsync("myBucket1", "myBucket2", "myBucket3");
Map<String, Object> map = new HashMap<>();
map.put("myBucket1", new MyObject());
map.put("myBucket2", new MyObject());
// sets all or nothing if some bucket is already exists
RFuture<Boolean> tsFuture = buckets.trySetAsync(map);
// store all at once
RFuture<Void> sFuture = buckets.setAsync(map);
RedissonReactiveClient redisson = redissonClient.reactive();
RBucketsReactive buckets = redisson.getBuckets();
// get all bucket values
Mono<Map<String, V>> bucketsMono = buckets.getAsync("myBucket1", "myBucket2", "myBucket3");
Map<String, Object> map = new HashMap<>();
map.put("myBucket1", new MyObject());
map.put("myBucket2", new MyObject());
// sets all or nothing if some bucket is already exists
Mono<Boolean> tsMono = buckets.trySet(map);
// store all at once
Mono<Void> sMono = buckets.set(map);
RedissonRxClient redisson = redissonClient.rxJava();
RBucketsRx buckets = redisson.getBuckets();
// get all bucket values
Single<Map<String, V>> bucketsRx = buckets.get("myBucket1", "myBucket2", "myBucket3");
Map<String, Object> map = new HashMap<>();
map.put("myBucket1", new MyObject());
map.put("myBucket2", new MyObject());
// sets all or nothing if some bucket is already exists
Single<Boolean> tsRx = buckets.trySet(map);
// store all at once
Completable sRx = buckets.set(map);
Listeners¶
Redisson allows binding listeners per RBucket object. This requires the notify-keyspace-events setting to be enabled on Valkey or Redis side.
| Listener class name | Event description | Valkey or Redisnotify-keyspace-events value |
|---|---|---|
| org.redisson.api.listener.TrackingListener | Data created/updated after read operation | - |
| org.redisson.api.listener.SetObjectListener | Data created/updated | E$ |
| org.redisson.api.ExpiredObjectListener | RBucket object expired |
Ex |
| org.redisson.api.DeletedObjectListener | RBucket object deleted |
Ex |
Code examples:
RBucket<String> bucket = redisson.getBucket("anyObject");
int setListenerId = bucket.addListener(new SetObjectListener() {
@Override
public void onSet(String name) {
// handle set event
}
});
int deletedListenerId = bucket.addListener(new DeletedObjectListener() {
@Override
public void onDeleted(String name) {
// handle delete event
}
});
// ...
bucket.removeListener(setListenerId);
bucket.removeListener(deletedListenerId);
RBucketAsync<String> bucket = redisson.getBucket("anyObject");
RFuture<Integer> setListenerFuture = bucket.addListenerAsync(new SetObjectListener() {
@Override
public void onSet(String name) {
// handle set event
}
});
RFuture<Integer> deletedListenerFuture = bucket.addListenerAsync(new DeletedObjectListener() {
@Override
public void onDeleted(String name) {
// handle delete event
}
});
// ...
bucket.removeListenerAsync(setListenerFuture.get());
bucket.removeListenerAsync(deletedListenerFuture.get());
RedissonReactiveClient redisson = redissonClient.reactive();
RBucketReactive<String> bucket = redisson.getBucket("anyObject");
Mono<Integer> setListenerMono = bucket.addListener(new SetObjectListener() {
@Override
public void onSet(String name) {
// handle set event
}
});
Mono<Integer> deletedListenerMono = bucket.addListener(new DeletedObjectListener() {
@Override
public void onDeleted(String name) {
// handle delete event
}
});
// ...
setListenerMono.flatMap(bucket::removeListener).subscribe();
deletedListenerMono.flatMap(bucket::removeListener).subscribe();
RedissonRxClient redisson = redissonClient.rxJava();
RBucketRx<String> bucket = redisson.getBucket("anyObject");
Single<Integer> setListenerRx = bucket.addListener(new SetObjectListener() {
@Override
public void onSet(String name) {
// handle set event
}
});
Single<Integer> deletedListenerRx = bucket.addListener(new DeletedObjectListener() {
@Override
public void onDeleted(String name) {
// handle delete event
}
});
// ...
setListenerRx.flatMapCompletable(bucket::removeListener).subscribe();
deletedListenerRx.flatMapCompletable(bucket::removeListener).subscribe();
Binary stream holder¶
Java implementation of Valkey or Redis based RBinaryStream object holds sequence of bytes. It extends RBucket interface and size is limited to 512Mb. This object is thread-safe.
Code examples:
RedissonReactiveClient redisson = redissonClient.reactive();
RBinaryStreamReactive stream = redisson.getBinaryStream("anyStream");
ByteBuffer content = ...
Mono<Void> mono = stream.set(content);
Mono<byte[]> mono = stream.getAndSet(content);
Mono<Boolean> mono = stream.trySet(content);
Mono<Boolean> mono = stream.compareAndSet(oldContent, content);
Mono<Integer> mono = stream.write(content);
stream.position(0);
Mono<Integer> mono = stream.read(b);
RedissonRxClient redisson = redissonClient.rxJava();
RBinaryStreamRx stream = redisson.getBinaryStream("anyStream");
ByteBuffer content = ...
Completable rx = stream.set(content);
Maybe<byte[]> rx = stream.getAndSet(content);
Single<Boolean> rx = stream.trySet(content);
Single<Boolean> rx = stream.compareAndSet(oldContent, content);
Single<Integer> rx = stream.write(content);
stream.position(0);
Single<Integer> rx = stream.read(b);
Code example of java.io.InputStream and java.io.OutputStream interfaces usage:
RBinaryStream stream = redisson.getBinaryStream("anyStream");
InputStream is = stream.getInputStream();
byte[] readBuffer = ...
is.read(readBuffer);
OutputStream os = stream.getOuputStream();
byte[] contentToWrite = ...
os.write(contentToWrite);
Code example of java.nio.channels.SeekableByteChannel interface usage:
RBinaryStream stream = redisson.getBinaryStream("anyStream");
SeekableByteChannel sbc = stream.getChannel();
ByteBuffer readBuffer = ...
sbc.read(readBuffer);
sbc.position(0);
ByteBuffer contentToWrite = ...
sbc.write(contentToWrite);
sbc.truncate(234);
Code example of java.nio.channels.AsynchronousByteChannel interface usage:
RBinaryStream stream = redisson.getBinaryStream("anyStream");
AsynchronousByteChannel sbc = stream.getAsynchronousChannel();
ByteBuffer readBuffer = ...
sbc.read(readBuffer);
ByteBuffer contentToWrite = ...
sbc.write(contentToWrite);
Listeners¶
Redisson allows binding listeners per RBinaryStream object. This requires the notify-keyspace-events setting to be enabled on Valkey or Redis side.
| Listener class name | Event description | Valkey or Redisnotify-keyspace-events value |
|---|---|---|
| org.redisson.api.listener.TrackingListener | Data created/updated after read operation | - |
| org.redisson.api.listener.SetObjectListener | Data created/updated | E$ |
| org.redisson.api.ExpiredObjectListener | RBinaryStream object expired |
Ex |
| org.redisson.api.DeletedObjectListener | RBinaryStream object deleted |
Ex |
Code examples:
RBinaryStream stream = redisson.getBinaryStream("anyStream");
int setListenerId = stream.addListener(new SetObjectListener() {
@Override
public void onSet(String name) {
// handle set event
}
});
int deletedListenerId = stream.addListener(new DeletedObjectListener() {
@Override
public void onDeleted(String name) {
// handle delete event
}
});
// ...
stream.removeListener(setListenerId);
stream.removeListener(deletedListenerId);
RBinaryStreamAsync stream = redisson.getBinaryStream("anyStream");
RFuture<Integer> setListenerFuture = stream.addListenerAsync(new SetObjectListener() {
@Override
public void onSet(String name) {
// handle set event
}
});
RFuture<Integer> deletedListenerFuture = stream.addListenerAsync(new DeletedObjectListener() {
@Override
public void onDeleted(String name) {
// handle delete event
}
});
// ...
stream.removeListenerAsync(setListenerFuture.get());
stream.removeListenerAsync(deletedListenerFuture.get());
RedissonReactiveClient redisson = redissonClient.reactive();
RBinaryStreamReactive stream = redisson.getBinaryStream("anyStream");
Mono<Integer> setListenerMono = stream.addListener(new SetObjectListener() {
@Override
public void onSet(String name) {
// handle set event
}
});
Mono<Integer> deletedListenerMono = stream.addListener(new DeletedObjectListener() {
@Override
public void onDeleted(String name) {
// handle delete event
}
});
// ...
setListenerMono.flatMap(stream::removeListener).subscribe();
deletedListenerMono.flatMap(stream::removeListener).subscribe();
RedissonRxClient redisson = redissonClient.rxJava();
RBinaryStreamRx stream = redisson.getBinaryStream("anyStream");
Single<Integer> setListenerRx = stream.addListener(new SetObjectListener() {
@Override
public void onSet(String name) {
// handle set event
}
});
Single<Integer> deletedListenerRx = stream.addListener(new DeletedObjectListener() {
@Override
public void onDeleted(String name) {
// handle delete event
}
});
// ...
setListenerRx.flatMapCompletable(stream::removeListener).subscribe();
deletedListenerRx.flatMapCompletable(stream::removeListener).subscribe();
JSON object holder¶
Java implementation of Valkey or Redis based JsonBucket object stores data in JSON format using JSON.* commands. JSON data encoding/decoding handled by JsonCodec which is a required parameter. Available implementation is org.redisson.codec.JacksonCodec. This object is thread-safe.
Use JSON Store for key-value implementation and local cache support.
Code examples:
RJsonBucket<AnyObject> bucket = redisson.getJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
bucket.set(new AnyObject(1));
AnyObject obj = bucket.get();
bucket.trySet(new AnyObject(3));
bucket.compareAndSet(new AnyObject(4), new AnyObject(5));
bucket.getAndSet(new AnyObject(6));
List<String> values = bucket.get(new JacksonCodec<>(new TypeReference<List<String>>() {}), "values");
long aa = bucket.arrayAppend("$.obj.values", "t3", "t4");
RJsonBucket<AnyObject> bucket = redisson.getJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
RFuture<Void> future = bucket.setAsync(new AnyObject(1));
RFuture<AnyObject> objfuture = bucket.getAsync();
RFuture<Boolean> tsFuture = bucket.trySetAsync(new AnyObject(3));
RFuture<Boolean> csFuture = bucket.compareAndSetAsync(new AnyObject(4), new AnyObject(5));
RFuture<AnyObject> gsFuture = bucket.getAndSetAsync(new AnyObject(6));
RFuture<List<String>> gFuture = bucket.getAsync(new JacksonCodec<>(new TypeReference<List<String>>() {}), "obj.values");
RFuture<Long> aaFuture = bucket.arrayAppendAsync("$.obj.values", "t3", "t4");
RedissonReactiveClient redisson = redissonClient.reactive();
RJsonBucketReactive<AnyObject> bucket = redisson.getJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
Mono<Void> mono = bucket.set(new AnyObject(1));
Mono<AnyObject> objMono = bucket.get();
Mono<Boolean> tsMono = bucket.trySet(new AnyObject(3));
Mono<Boolean> csMono = bucket.compareAndSet(new AnyObject(4), new AnyObject(5));
Mono<AnyObject> gsMono = bucket.getAndSet(new AnyObject(6));
Mono<List<String>> vsMono = bucket.get(new JacksonCodec<>(new TypeReference<List<String>>() {}), "values");
Mono<Long> aaMono = bucket.arrayAppend("$.obj.values", "t3", "t4");
RedissonRxClient redisson = redissonClient.rxJava();
RJsonBucketRx<AnyObject> bucket = redisson.getJsonBucket("anyObject", new JacksonCodec<>(AnyObject.class));
Completable rx = bucket.set(new AnyObject(1));
Maybe<AnyObject> objRx = bucket.get();
Single<Boolean> tsRx = bucket.trySet(new AnyObject(3));
Single<Boolean> csRx = bucket.compareAndSet(new AnyObject(4), new AnyObject(5));
Maybe<AnyObject> gsRx = bucket.getAndSet(new AnyObject(6));
Single<List<String>> valuesRx = bucket.get(new JacksonCodec<>(new TypeReference<List<String>>() {}), "values");
Single<Long> aaRx = bucket.arrayAppend("$.obj.values", "t3", "t4");
Geospatial holder¶
Java implementation of Valkey or Redis based RGeo object is a holder for geospatial items. This object is thread-safe.
Code examples:
RGeo<String> geo = redisson.getGeo("test");
geo.add(new GeoEntry(13.361389, 38.115556, "Palermo"),
new GeoEntry(15.087269, 37.502669, "Catania"));
Double distance = geo.dist("Palermo", "Catania", GeoUnit.METERS);
Map<String, GeoPosition> positions = geo.pos("test2", "Palermo", "test3", "Catania", "test1");
List<String> cities = geo.search(GeoSearchArgs.from(15, 37).radius(200, GeoUnit.KILOMETERS));
Map<String, GeoPosition> citiesWithPositions = geo.searchWithPosition(GeoSearchArgs.from(15, 37).radius(200, GeoUnit.KILOMETERS));
RGeo<String> geo = redisson.getGeo("test");
RFuture<Long> addFuture = geo.addAsync(new GeoEntry(13.361389, 38.115556, "Palermo"),
new GeoEntry(15.087269, 37.502669, "Catania"));
RFuture<Double> distanceFuture = geo.distAsync("Palermo", "Catania", GeoUnit.METERS);
RFuture<Map<String, GeoPosition>> positionsFuture = geo.posAsync("test2", "Palermo", "test3", "Catania", "test1");
RFuture<List<String>> citiesFuture = geo.searchAsync(GeoSearchArgs.from(15, 37).radius(200, GeoUnit.KILOMETERS));
RFuture<Map<String, GeoPosition>> citiesWithPositions = geo.searchWithPositionAsync(GeoSearchArgs.from(15, 37).radius(200, GeoUnit.KILOMETERS));
RedissonReactiveClient redisson = redissonClient.reactive();
RGeoReactive<String> geo = redisson.getGeo("test");
Mono<Long> addFuture = geo.add(new GeoEntry(13.361389, 38.115556, "Palermo"),
new GeoEntry(15.087269, 37.502669, "Catania"));
Mono<Double> distanceFuture = geo.dist("Palermo", "Catania", GeoUnit.METERS);
Mono<Map<String, GeoPosition>> positionsFuture = geo.pos("test2", "Palermo", "test3", "Catania", "test1");
Mono<List<String>> citiesFuture = geo.search(GeoSearchArgs.from(15, 37).radius(200, GeoUnit.KILOMETERS));
Mono<Map<String, GeoPosition>> citiesWithPositions = geo.searchWithPosition(GeoSearchArgs.from(15, 37).radius(200, GeoUnit.KILOMETERS));
RedissonRxClient redisson = redissonClient.rxJava();
RGeoRx<String> geo = redisson.getGeo("test");
Single<Long> addFuture = geo.add(new GeoEntry(13.361389, 38.115556, "Palermo"),
new GeoEntry(15.087269, 37.502669, "Catania"));
Single<Double> distanceFuture = geo.dist("Palermo", "Catania", GeoUnit.METERS);
Single<Map<String, GeoPosition>> positionsFuture = geo.pos("test2", "Palermo", "test3", "Catania", "test1");
Single<List<String>> citiesFuture = geo.search(GeoSearchArgs.from(15, 37).radius(200, GeoUnit.KILOMETERS));
Single<Map<String, GeoPosition>> citiesWithPositions = geo.searchWithPosition(GeoSearchArgs.from(15, 37).radius(200, GeoUnit.KILOMETERS));
BitSet¶
Java implementation of Valkey or Redis based RBitSet object provides API similar to java.util.BitSet. It represents vector of bits that grows as needed. Size limited to 4 294 967 295 bits. This object is thread-safe.
Code examples:
RBitSetAsync set = redisson.getBitSet("simpleBitset");
RFuture<Boolean> setFuture = set.setAsync(0, true);
RFuture<Boolean> setFuture = set.setAsync(1812, false);
RFuture<Void> clearFuture = set.clearAsync(0);
RFuture<Void> andFuture = set.andAsync("anotherBitset");
RFuture<Void> xorFuture = set.xorAsync("anotherBitset");
RedissonReactiveClient redisson = redissonClient.reactive();
RBitSetReactive set = redisson.getBitSet("simpleBitset");
Mono<Boolean> setMono = set.set(0, true);
Mono<Boolean> setMono = set.set(1812, false);
Mono<Void> clearMono = set.clear(0);
Mono<Void> andMono = set.and("anotherBitset");
Mono<Void> xorMono = set.xor("anotherBitset");
RedissonRxClient redisson = redissonClient.rxJava();
RBitSetRx set = redisson.getBitSet("simpleBitset");
Single<Boolean> setRx = set.set(0, true);
Single<Boolean> setRx = set.set(1812, false);
Completable clearRx = set.clear(0);
Completable andRx = set.and("anotherBitset");
Completable xorRx = set.xor("anotherBitset");
Data partitioning¶
Although 'RBitSet' object is cluster compatible its content isn't scaled across multiple master nodes. BitSet data partitioning available only in cluster mode and implemented by separate RClusteredBitSet object. It uses distributed implementation of roaring bitmap structure. Size is limited by whole Cluster memory. More details about partitioning here.
Below is the list of all available BitSet implementations:
| RedissonClient method name |
Data partitioning support |
Ultra-fast read/write |
|---|---|---|
| getBitSet() open-source version |
❌ | ❌ |
| getBitSet() Redisson PRO version |
❌ | ✔️ |
| getClusteredBitSet() available only in Redisson PRO |
✔️ | ✔️ |
Code example:
RClusteredBitSet set = redisson.getClusteredBitSet("simpleBitset");
set.set(0, true);
set.set(1812, false);
set.clear(0);
set.addAsync("e");
set.xor("anotherBitset");
Bloom filter¶
Java implementation of Valkey or Redis based RBloomFilter object is a bloom filter. Number of contained bits is limited to 2^32 with data partitioning to 2^63. This object is thread-safe.
Must be initialized with capacity size by tryInit(expectedInsertions, falseProbability) method before usage.
Code examples:
RBloomFilterAsync<SomeObject> bloomFilter = redisson.getBloomFilter("sample");
RFuture<Boolean> initFuture = bloomFilter.tryInitAsync(55000000L, 0.03);
RFuture<Boolean> addFuture = bloomFilter.addAsync(new SomeObject("field1Value", "field2Value"));
RFuture<Boolean> containsFuture = bloomFilter.containsAsync(new SomeObject("field1Value", "field8Value"));
RFuture<Long> countFuture = bloomFilter.countAsync();
RedissonReactiveClient redissonReactive = redisson.reactive();
RBloomFilterReactive<SomeObject> bloomFilter = redissonReactive.getBloomFilter("sample");
Mono<Boolean> initMono = bloomFilter.tryInit(55000000L, 0.03);
Mono<Boolean> addMono = bloomFilter.add(new SomeObject("field1Value", "field2Value"));
Mono<Boolean> containsMono = bloomFilter.contains(new SomeObject("field1Value", "field8Value"));
Mono<Long> countMono = bloomFilter.count();
RedissonRxClient redissonRx = redisson.rxJava();
RBloomFilterRx<SomeObject> bloomFilter = redissonRx.getBloomFilter("sample");
Single<Boolean> initSingle = bloomFilter.tryInit(55000000L, 0.03);
Single<Boolean> addSingle = bloomFilter.add(new SomeObject("field1Value", "field2Value"));
Single<Boolean> containsSingle = bloomFilter.contains(new SomeObject("field1Value", "field8Value"));
Single<Long> countSingle = bloomFilter.count();
Data partitioning¶
This feature available only in Redisson PRO edition.
Although 'RBloomFilter' object is cluster compatible its content isn't scaled across multiple master nodes. Bloom Filter data partitioning support available only in cluster mode and implemented by separate RClusteredBloomFilter object. This implementation uses more efficient distributed memory allocation algorithm. It allows to "shrink" memory space consumed by unused bits across all Valkey or Redis nodes. State of each instance is partitioned across all nodes in Valkey or Redis cluster. Number of contained bits is limited to 2^63. More details about partitioning here.
Below is the list of all available BloomFilter implementations:
| RedissonClient method name |
Data partitioning support |
Ultra-fast read/write | Bits amount limit |
|---|---|---|---|
| getBloomFilter() open-source version |
❌ | ❌ | 2^32 |
| getBloomFilter() Redisson PRO version |
❌ | ✔️ | 2^32 |
| getClusteredBloomFilter() available only in Redisson PRO |
✔️ | ✔️ | 2^63 |
RClusteredBloomFilter<SomeObject> bloomFilter = redisson.getClusteredBloomFilter("sample");
// initialize bloom filter with
// expectedInsertions = 255000000
// falseProbability = 0.03
bloomFilter.tryInit(255000000L, 0.03);
bloomFilter.add(new SomeObject("field1Value", "field2Value"));
bloomFilter.add(new SomeObject("field5Value", "field8Value"));
bloomFilter.contains(new SomeObject("field1Value", "field8Value"));
Bloom filter (Native)¶
Java implementation of Valkey or Redis based RBloomFilterNative object is a Bloom filter based on native BF.* commands. This object is thread-safe.
Must be initialized with error rate and capacity by init(errorRate, capacity) method before usage.
Code examples:
RBloomFilterNative<String> bloomFilter = redisson.getBloomFilterNative("sample");
// initialize bloom filter with
// errorRate = 0.03
// capacity = 55000000
bloomFilter.init(0.03, 55000000L);
bloomFilter.add("field1Value");
bloomFilter.add("field2Value");
Set<String> addedItems = bloomFilter.add(Arrays.asList("field3Value", "field4Value", "field5Value"));
boolean isPresent = bloomFilter.exists("field1Value");
Set<String> presentItems = bloomFilter.exists(Arrays.asList("field1Value", "field8Value"));
long count = bloomFilter.count();
RBloomFilterNative<String> bloomFilter = redisson.getBloomFilterNative("sample");
// initialize bloom filter with
// errorRate = 0.03
// capacity = 55000000
RFuture<Void> initFuture = bloomFilter.initAsync(0.03, 55000000L);
RFuture<Boolean> addFuture = bloomFilter.addAsync("field1Value");
RFuture<Boolean> addFuture2 = bloomFilter.addAsync("field2Value");
RFuture<Set<String>> addedFuture = bloomFilter.addAsync(Arrays.asList("field3Value", "field4Value", "field5Value"));
RFuture<Boolean> existsFuture = bloomFilter.existsAsync("field1Value");
RFuture<Set<String>> existsAllFuture = bloomFilter.existsAsync(Arrays.asList("field1Value", "field8Value"));
RFuture<Long> countFuture = bloomFilter.countAsync();
RedissonReactiveClient redisson = redissonClient.reactive();
RBloomFilterNativeReactive<String> bloomFilter = redisson.getBloomFilterNative("sample");
// initialize bloom filter with
// errorRate = 0.03
// capacity = 55000000
Mono<Void> initMono = bloomFilter.init(0.03, 55000000L);
Mono<Boolean> addMono = bloomFilter.add("field1Value");
Mono<Boolean> addMono2 = bloomFilter.add("field2Value");
Mono<Set<String>> addedMono = bloomFilter.add(Arrays.asList("field3Value", "field4Value", "field5Value"));
Mono<Boolean> existsMono = bloomFilter.exists("field1Value");
Mono<Set<String>> existsAllMono = bloomFilter.exists(Arrays.asList("field1Value", "field8Value"));
Mono<Long> countMono = bloomFilter.count();
RedissonRxClient redisson = redissonClient.rxJava();
RBloomFilterNativeRx<String> bloomFilter = redisson.getBloomFilterNative("sample");
// initialize bloom filter with
// errorRate = 0.03
// capacity = 55000000
Completable initRx = bloomFilter.init(0.03, 55000000L);
Single<Boolean> addRx = bloomFilter.add("field1Value");
Single<Boolean> addRx2 = bloomFilter.add("field2Value");
Single<Set<String>> addedRx = bloomFilter.add(Arrays.asList("field3Value", "field4Value", "field5Value"));
Single<Boolean> existsRx = bloomFilter.exists("field1Value");
Single<Set<String>> existsAllRx = bloomFilter.exists(Arrays.asList("field1Value", "field8Value"));
Single<Long> countRx = bloomFilter.count();
Advanced initialization
Use BloomFilterInitArgs builder for advanced initialization parameters such as expansion rate and non-scaling mode. Parameters expansionRate and nonScaling are mutually exclusive.
Non-scaling mode prevents creation of sub-filters when capacity is reached:
Insert
The insert() method combines filter auto-creation (if it doesn't yet exist) with element insertion. It supports optional parameters including capacity, errorRate, expansionRate, nonScaling, and noCreate.
RedissonReactiveClient redisson = redissonClient.reactive();
RBloomFilterNativeReactive<String> bloomFilter = redisson.getBloomFilterNative("sample");
Mono<Set<String>> addedMono = bloomFilter.insert(
BloomFilterInsertArgs.<String>elements(Arrays.asList("field1Value", "field2Value", "field3Value"))
.capacity(1000000L)
.errorRate(0.01));
RedissonRxClient redisson = redissonClient.rxJava();
RBloomFilterNativeRx<String> bloomFilter = redisson.getBloomFilterNative("sample");
Single<Set<String>> addedRx = bloomFilter.insert(
BloomFilterInsertArgs.<String>elements(Arrays.asList("field1Value", "field2Value", "field3Value"))
.capacity(1000000L)
.errorRate(0.01));
Setting noCreate to true prevents the filter from being created automatically and causes the command to fail if the filter does not already exist:
RedissonReactiveClient redisson = redissonClient.reactive();
RBloomFilterNativeReactive<String> bloomFilter = redisson.getBloomFilterNative("sample");
Mono<Set<String>> addedMono = bloomFilter.insert(
BloomFilterInsertArgs.<String>elements(Arrays.asList("field1Value", "field2Value"))
.noCreate(true));
Filter information
The getInfo() method returns a BloomFilterInfo object containing filter details: capacity, size, sub-filter count, item count, and expansion rate. Use getInfo(BloomFilterInfoOption) to query a specific metric individually.
RBloomFilterNative<String> bloomFilter = redisson.getBloomFilterNative("sample");
BloomFilterInfo info = bloomFilter.getInfo();
long capacity = info.getCapacity();
long size = info.getSize();
long subFilterCount = info.getSubFilterCount();
long itemCount = info.getItemCount();
long expansionRate = info.getExpansionRate();
// query a specific metric
long currentCapacity = bloomFilter.getInfo(BloomFilterInfoOption.CAPACITY);
long currentItems = bloomFilter.getInfo(BloomFilterInfoOption.ITEMS);
RBloomFilterNative<String> bloomFilter = redisson.getBloomFilterNative("sample");
RFuture<BloomFilterInfo> infoFuture = bloomFilter.getInfoAsync();
// query a specific metric
RFuture<Long> capacityFuture = bloomFilter.getInfoAsync(BloomFilterInfoOption.CAPACITY);
RFuture<Long> itemsFuture = bloomFilter.getInfoAsync(BloomFilterInfoOption.ITEMS);
RedissonReactiveClient redisson = redissonClient.reactive();
RBloomFilterNativeReactive<String> bloomFilter = redisson.getBloomFilterNative("sample");
Mono<BloomFilterInfo> infoMono = bloomFilter.getInfo();
// query a specific metric
Mono<Long> capacityMono = bloomFilter.getInfo(BloomFilterInfoOption.CAPACITY);
Mono<Long> itemsMono = bloomFilter.getInfo(BloomFilterInfoOption.ITEMS);
RedissonRxClient redisson = redissonClient.rxJava();
RBloomFilterNativeRx<String> bloomFilter = redisson.getBloomFilterNative("sample");
Single<BloomFilterInfo> infoRx = bloomFilter.getInfo();
// query a specific metric
Single<Long> capacityRx = bloomFilter.getInfo(BloomFilterInfoOption.CAPACITY);
Single<Long> itemsRx = bloomFilter.getInfo(BloomFilterInfoOption.ITEMS);
Available BloomFilterInfoOption values: CAPACITY, SIZE, FILTERS, ITEMS, EXPANSION.
Data dump and restore
The scanDump() and loadChunk() methods allow serialization and deserialization of a Bloom filter for backup, replication, or migration between Valkey or Redis instances. Iteration starts from 0 and completes when the returned iterator is 0 with empty data. Requires Redis Bloom 1.0.0 and higher.
RBloomFilterNative<String> sourceFilter = redisson.getBloomFilterNative("source");
RBloomFilterNative<String> targetFilter = redisson.getBloomFilterNative("target");
// dump all chunks from source filter
long iterator = 0;
do {
BloomFilterScanDumpInfo dumpInfo = sourceFilter.scanDump(iterator);
iterator = dumpInfo.getIterator();
if (dumpInfo.getData() != null && dumpInfo.getData().length > 0) {
// load chunk into target filter
targetFilter.loadChunk(iterator, dumpInfo.getData());
}
} while (iterator != 0);
RBloomFilterNative<String> sourceFilter = redisson.getBloomFilterNative("source");
RBloomFilterNative<String> targetFilter = redisson.getBloomFilterNative("target");
// dump all chunks from source filter
long iterator = 0;
do {
RFuture<BloomFilterScanDumpInfo> dumpFuture = sourceFilter.scanDumpAsync(iterator);
BloomFilterScanDumpInfo dumpInfo = dumpFuture.get();
iterator = dumpInfo.getIterator();
if (dumpInfo.getData() != null && dumpInfo.getData().length > 0) {
// load chunk into target filter
RFuture<Void> loadFuture = targetFilter.loadChunkAsync(iterator, dumpInfo.getData());
}
} while (iterator != 0);
RedissonReactiveClient redisson = redissonClient.reactive();
RBloomFilterNativeReactive<String> sourceFilter = redisson.getBloomFilterNative("source");
RBloomFilterNativeReactive<String> targetFilter = redisson.getBloomFilterNative("target");
// dump all chunks from source filter
long iterator = 0;
do {
BloomFilterScanDumpInfo dumpInfo = sourceFilter.scanDump(iterator).block();
iterator = dumpInfo.getIterator();
if (dumpInfo.getData() != null && dumpInfo.getData().length > 0) {
// load chunk into target filter
targetFilter.loadChunk(iterator, dumpInfo.getData()).block();
}
} while (iterator != 0);
RedissonRxClient redisson = redissonClient.rxJava();
RBloomFilterNativeRx<String> sourceFilter = redisson.getBloomFilterNative("source");
RBloomFilterNativeRx<String> targetFilter = redisson.getBloomFilterNative("target");
// dump all chunks from source filter
long iterator = 0;
do {
BloomFilterScanDumpInfo dumpInfo = sourceFilter.scanDump(iterator).blockingGet();
iterator = dumpInfo.getIterator();
if (dumpInfo.getData() != null && dumpInfo.getData().length > 0) {
// load chunk into target filter
targetFilter.loadChunk(iterator, dumpInfo.getData()).blockingAwait();
}
} while (iterator != 0);
Cuckoo filter¶
Java implementation of Valkey or Redis based RCuckooFilter object is a cuckoo filter. A cuckoo filter is a probabilistic data structure for fast set membership testing, similar to a Bloom filter but with support for element deletion and counting. Covers CF.* commands of the Redis Bloom module. This object is thread-safe.
Initialization
The filter must be initialized before use. Simple initialization requires only a capacity value. Advanced initialization allows tuning of bucket size, max iterations, and expansion rate through CuckooFilterInitArgs.
Code examples:
RCuckooFilter<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// simple initialization with capacity only
RFuture<Void> future = filter.initAsync(100000);
// advanced initialization with detailed parameters
RFuture<Void> advFuture = filter.initAsync(CuckooFilterInitArgs.capacity(100000)
.bucketSize(4)
.maxIterations(500)
.expansion(2));
RedissonReactiveClient redisson = redissonClient.reactive();
RCuckooFilterReactive<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// simple initialization with capacity only
Mono<Void> mono = filter.init(100000);
// advanced initialization with detailed parameters
Mono<Void> advMono = filter.init(CuckooFilterInitArgs.capacity(100000)
.bucketSize(4)
.maxIterations(500)
.expansion(2));
RedissonRxClient redisson = redissonClient.rxJava();
RCuckooFilterRx<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// simple initialization with capacity only
Completable rx = filter.init(100000);
// advanced initialization with detailed parameters
Completable advRx = filter.init(CuckooFilterInitArgs.capacity(100000)
.bucketSize(4)
.maxIterations(500)
.expansion(2));
Adding elements
Elements can be added individually or in bulk. The add() method allows adding the same element multiple times. The addIfAbsent() method adds an element only if it does not already exist in the filter. Bulk operations accept CuckooFilterAddArgs with optional capacity and noCreate parameters.
Code examples:
RCuckooFilter<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// add a single element (allows duplicates)
boolean added = filter.add("element1");
// add element only if it does not already exist
boolean addedNew = filter.addIfAbsent("element2");
// bulk add with optional parameters
Set<String> addedItems = filter.add(
CuckooFilterAddArgs.<String>items(List.of("a", "b", "c"))
.capacity(50000)
.noCreate());
// bulk add only absent elements
Set<String> newItems = filter.addIfAbsent(
CuckooFilterAddArgs.<String>items(List.of("d", "e", "f"))
.capacity(50000));
RCuckooFilter<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// add a single element (allows duplicates)
RFuture<Boolean> addFuture = filter.addAsync("element1");
// add element only if it does not already exist
RFuture<Boolean> addNxFuture = filter.addIfAbsentAsync("element2");
// bulk add with optional parameters
RFuture<Set<String>> bulkFuture = filter.addAsync(
CuckooFilterAddArgs.<String>items(List.of("a", "b", "c"))
.capacity(50000)
.noCreate());
// bulk add only absent elements
RFuture<Set<String>> bulkNxFuture = filter.addIfAbsentAsync(
CuckooFilterAddArgs.<String>items(List.of("d", "e", "f"))
.capacity(50000));
RedissonReactiveClient redisson = redissonClient.reactive();
RCuckooFilterReactive<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// add a single element (allows duplicates)
Mono<Boolean> addMono = filter.add("element1");
// add element only if it does not already exist
Mono<Boolean> addNxMono = filter.addIfAbsent("element2");
// bulk add with optional parameters
Mono<Set<String>> bulkMono = filter.add(
CuckooFilterAddArgs.<String>items(List.of("a", "b", "c"))
.capacity(50000)
.noCreate());
// bulk add only absent elements
Mono<Set<String>> bulkNxMono = filter.addIfAbsent(
CuckooFilterAddArgs.<String>items(List.of("d", "e", "f"))
.capacity(50000));
RedissonRxClient redisson = redissonClient.rxJava();
RCuckooFilterRx<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// add a single element (allows duplicates)
Single<Boolean> addRx = filter.add("element1");
// add element only if it does not already exist
Single<Boolean> addNxRx = filter.addIfAbsent("element2");
// bulk add with optional parameters
Single<Set<String>> bulkRx = filter.add(
CuckooFilterAddArgs.<String>items(List.of("a", "b", "c"))
.capacity(50000)
.noCreate());
// bulk add only absent elements
Single<Set<String>> bulkNxRx = filter.addIfAbsent(
CuckooFilterAddArgs.<String>items(List.of("d", "e", "f"))
.capacity(50000));
Checking element existence and counting occurrences
The exists() method checks if an element may exist in the filter. A return value of false guarantees the element is not present. A return value of true means the element may exist (false positives are possible). Multiple elements can be checked at once with exists(Collection). The count() method returns the approximate number of times an element has been added to the filter.
Code examples:
RCuckooFilter<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// check single element
boolean mayExist = filter.exists("element1");
// check multiple elements at once
Set<String> existing = filter.exists(List.of("a", "b", "c", "d"));
// get approximate count of times an element was added
long approxCount = filter.count("element1");
RCuckooFilter<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// check single element
RFuture<Boolean> existsFuture = filter.existsAsync("element1");
// check multiple elements at once
RFuture<Set<String>> mExistsFuture = filter.existsAsync(List.of("a", "b", "c", "d"));
// get approximate count of times an element was added
RFuture<Long> countFuture = filter.countAsync("element1");
RedissonReactiveClient redisson = redissonClient.reactive();
RCuckooFilterReactive<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// check single element
Mono<Boolean> existsMono = filter.exists("element1");
// check multiple elements at once
Mono<Set<String>> mExistsMono = filter.exists(List.of("a", "b", "c", "d"));
// get approximate count of times an element was added
Mono<Long> countMono = filter.count("element1");
RedissonRxClient redisson = redissonClient.rxJava();
RCuckooFilterRx<String> filter = redisson.getCuckooFilter("myCuckooFilter");
// check single element
Single<Boolean> existsRx = filter.exists("element1");
// check multiple elements at once
Single<Set<String>> mExistsRx = filter.exists(List.of("a", "b", "c", "d"));
// get approximate count of times an element was added
Single<Long> countRx = filter.count("element1");
Removing elements
Unlike Bloom filters, cuckoo filters support element deletion. The remove() method deletes an element from the filter and returns true if it was found and removed.
Note: Deleting an element that was never added to the filter may cause false negatives for other elements.
Code examples:
Filter information
The getInfo() method returns a CuckooFilterInfo object containing filter statistics: memory size in bytes, number of buckets, number of sub-filters, number of inserted items, number of deleted items, bucket size, expansion rate, and maximum iterations.
Code examples:
RCuckooFilter<String> filter = redisson.getCuckooFilter("myCuckooFilter");
CuckooFilterInfo info = filter.getInfo();
info.getSize(); // memory size in bytes
info.getNumberOfBuckets(); // number of buckets
info.getNumberOfFilters(); // number of sub-filters
info.getNumberOfInsertedItems();// number of inserted items
info.getNumberOfDeletedItems(); // number of deleted items
info.getBucketSize(); // items per bucket
info.getExpansionRate(); // expansion rate
info.getMaxIterations(); // max swap attempts
HyperLogLog¶
Java implementation of Valkey or Redis based HyperLogLog object is a probabilistic data structure that lets you maintain counts of millions of items with extreme space efficiency. This object is thread-safe.
Code examples:
RateLimiter¶
Java implementation of Valkey or Redis based RateLimiter object restricts the total rate of calls either from all threads regardless of Redisson instance or from all threads working with the same Redisson instance. Doesn't guarantee fairness. This object is thread-safe.
Code example: