CommandObjectsCuckooFilterCommandsTest.java
package redis.clients.jedis.commands.commandobjects;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import redis.clients.jedis.RedisProtocol;
import redis.clients.jedis.bloom.CFInsertParams;
import redis.clients.jedis.bloom.CFReserveParams;
/**
* Tests related to <a href="https://redis.io/commands/?group=cf">Cuckoo filter</a> commands.
*/
public class CommandObjectsCuckooFilterCommandsTest extends CommandObjectsModulesTestBase {
public CommandObjectsCuckooFilterCommandsTest(RedisProtocol protocol) {
super(protocol);
}
@Test
public void testCuckooFilterAdd() {
String key = "testCuckooFilter";
String reserve = exec(commandObjects.cfReserve(key, 1000));
assertThat(reserve, equalTo("OK"));
Boolean add = exec(commandObjects.cfAdd(key, "apple"));
assertThat(add, equalTo(true));
Boolean addNx = exec(commandObjects.cfAddNx(key, "apple"));
assertThat(addNx, equalTo(false)); // "apple" already exists, NX makes this fail
Boolean addNx2 = exec(commandObjects.cfAddNx(key, "banana"));
assertThat(addNx2, equalTo(true));
Long count = exec(commandObjects.cfCount(key, "apple"));
assertThat(count, greaterThanOrEqualTo(1L));
}
@Test
public void testCuckooFilterReserveInsertAndCount() {
String key = "testCuckooFilterAdvanced";
CFReserveParams reserveParams = new CFReserveParams()
.bucketSize(4).maxIterations(500).expansion(1);
String reserve = exec(commandObjects.cfReserve(key, 5000, reserveParams));
assertThat(reserve, equalTo("OK"));
List<Boolean> insert = exec(commandObjects.cfInsert(
key, "apple", "banana", "carrot", "date"));
assertThat(insert, everyItem(equalTo(true)));
CFInsertParams insertParams = new CFInsertParams().noCreate();
List<Boolean> insertWithParams = exec(commandObjects.cfInsert(
key, insertParams, "eggplant", "fig", "grape", "apple"));
assertThat(insertWithParams, everyItem(equalTo(true)));
Long countApple = exec(commandObjects.cfCount(key, "apple"));
assertThat(countApple, greaterThanOrEqualTo(2L));
Long countBanana = exec(commandObjects.cfCount(key, "banana"));
assertThat(countBanana, greaterThanOrEqualTo(1L));
Long countNonExisting = exec(commandObjects.cfCount(key, "watermelon"));
assertThat(countNonExisting, equalTo(0L));
}
@Test
public void testCuckooFilterInsertNx() {
String key = "testCf";
String[] items = { "item1", "item2", "item3" };
CFInsertParams insertParams = new CFInsertParams().capacity(1000L).noCreate();
List<Boolean> insertNx1 = exec(commandObjects.cfInsertNx(key, items));
assertThat(insertNx1, not(empty()));
assertThat(insertNx1, everyItem(equalTo(true)));
long countAfterFirstInsert = exec(commandObjects.cfCount(key, "item1"));
assertThat(countAfterFirstInsert, greaterThanOrEqualTo(1L));
List<Boolean> insertNx2 = exec(commandObjects.cfInsertNx(key, insertParams, items));
assertThat(insertNx2, not(empty()));
assertThat(insertNx2, everyItem(equalTo(false)));
long countAfterSecondInsert = exec(commandObjects.cfCount(key, "item1"));
assertThat(countAfterSecondInsert, greaterThanOrEqualTo(1L)); // count should remain the same
}
@Test
public void testCuckooFilterExistsAndDel() {
String key = "testCf";
String item = "item1";
boolean existsBeforeInsert = exec(commandObjects.cfExists(key, item));
assertThat(existsBeforeInsert, equalTo(false));
Boolean add = exec(commandObjects.cfAdd(key, item));
assertThat(add, equalTo(true));
boolean existsAfterInsert = exec(commandObjects.cfExists(key, item));
assertThat(existsAfterInsert, equalTo(true));
boolean delete = exec(commandObjects.cfDel(key, item));
assertThat(delete, equalTo(true));
boolean existsAfterDelete = exec(commandObjects.cfExists(key, item));
assertThat(existsAfterDelete, equalTo(false));
}
@Test
public void testCuckooFilterMExists() {
String key = "testCf";
exec(commandObjects.cfInsert(key, "item1", "item2", "item3"));
List<Boolean> mExists = exec(commandObjects.cfMExists(
key, "item1", "item2", "item3", "item4", "item5"));
assertThat(mExists, contains(true, true, true, false, false));
}
@Test
public void testCuckooFilterScanDumpAndLoadChunk() {
long capacity = 5000;
CFReserveParams reserveParams = new CFReserveParams()
.bucketSize(4).maxIterations(500).expansion(1);
String key = "testCf";
String reserve = exec(commandObjects.cfReserve(key, capacity, reserveParams));
assertThat(reserve, equalTo("OK"));
// add some items to the source
for (int i = 0; i < 1000; i++) {
exec(commandObjects.cfAdd(key, "item" + i));
}
String newKey = "testCfLoadChunk";
// scandump and load
long iterator = 0;
do {
Map.Entry<Long, byte[]> scanDumpResult = exec(commandObjects.cfScanDump(key, iterator));
iterator = scanDumpResult.getKey();
if (iterator > 0) {
byte[] data = scanDumpResult.getValue();
assertThat(data, notNullValue());
String loadChunk = exec(commandObjects.cfLoadChunk(newKey, iterator, data));
assertThat(loadChunk, equalTo("OK"));
}
} while (iterator != 0);
// verify destination
for (int i = 0; i < 1000; i++) {
boolean exists = exec(commandObjects.cfExists(newKey, "item" + i));
assertThat(exists, equalTo(true));
}
boolean missingItem = exec(commandObjects.cfExists(newKey, "item1001"));
assertThat(missingItem, equalTo(false));
}
@Test
public void testCuckooFilterInfo() {
String key = "testCfInfo";
exec(commandObjects.cfReserve(key, 1000));
exec(commandObjects.cfAdd(key, "item1"));
Map<String, Object> info = exec(commandObjects.cfInfo(key));
assertThat(info, hasEntry("Number of items inserted", 1L));
}
}