Skip to content

Commit 3604ed8

Browse files
committed
Add support for TDIGEST.RANK/TDIGEST.REVRANK/TDIGEST.BYRANK/TDIGEST.BYREVRANK/TDIGEST.TRIMMED_MEAN commands
1 parent 8b85a1e commit 3604ed8

File tree

9 files changed

+177
-54
lines changed

9 files changed

+177
-54
lines changed

redisbloom/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,9 @@ TDIGEST.QUANTILE | TDigest.<br/>getQuantile()<br/>getQuantileAsync() |
4646
TDIGEST.CDF | TDigest.<br/>getCdf()<br/>getCdfAsync() |
4747
TDIGEST.MERGE | TDigest.<br/>mergeTo()<br/>mergeToAsync() |
4848
TDIGEST.INFO | TDigest.<br/>getInfo()<br/>getInfoAsync() |
49+
TDIGEST.BYRANK | TDigest.<br/>byRank()<br/>byRankAsync() |
50+
TDIGEST.BYREVRANK | TDigest.<br/>byRevRank()<br/>byRevRankAsync() |
51+
TDIGEST.RANK | TDigest.<br/>rank()<br/>rankAsync() |
52+
TDIGEST.REVRANK | TDigest.<br/>revRank()<br/>revRankAsync() |
53+
TDIGEST.TRIMMED_MEAN | TDigest.<br/>trimmedMean()<br/>trimmedMeanAsync() |
4954

redisbloom/src/main/java/io/github/dengliming/redismodule/redisbloom/BloomFilter.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public BloomFilter(CommandAsyncExecutor commandExecutor, String name) {
6060
*
6161
* @param errorRate The desired probability for false positives. This should be a decimal value between 0 and 1.
6262
* @param capacity The number of entries you intend to add to the filter
63-
* @return
63+
* @return True if executed correctly, or false reply otherwise
6464
*/
6565
public boolean create(double errorRate, long capacity) {
6666
return get(createAsync(errorRate, capacity));
@@ -90,7 +90,7 @@ public RFuture<Boolean> addAsync(String item) {
9090
* Determines whether an item may exist in the Bloom Filter or not
9191
*
9292
* @param item
93-
* @return
93+
* @return True if the item exist in the filter
9494
*/
9595
public boolean exists(String item) {
9696
return get(existsAsync(item));
@@ -123,7 +123,7 @@ public RFuture<List<Boolean>> existsMultiAsync(String... items) {
123123
*
124124
* @param insertArgs {@link InsertArgs}
125125
* @param items
126-
* @return
126+
* @return The list of insert results
127127
*/
128128
public List<Boolean> insert(InsertArgs insertArgs, String... items) {
129129
return get(insertAsync(insertArgs, items));
@@ -147,7 +147,7 @@ public RFuture<List<Boolean>> insertAsync(InsertArgs insertArgs, String... items
147147
* Adds one or more items to the Bloom Filter
148148
*
149149
* @param items One or more items to add
150-
* @return
150+
* @return The list of add results
151151
*/
152152
public List<Boolean> madd(String... items) {
153153
return get(maddAsync(items));
@@ -162,7 +162,7 @@ public RFuture<List<Boolean>> maddAsync(String... items) {
162162
/**
163163
* Return information about key
164164
*
165-
* @return
165+
* @return The information of the filter
166166
*/
167167
public BloomFilterInfo getInfo() {
168168
return get(getInfoAsync());
@@ -176,7 +176,7 @@ public RFuture<BloomFilterInfo> getInfoAsync() {
176176
* Begins an incremental save of the bloom filter.
177177
*
178178
* @param iter Iterator value. This is either 0, or the iterator from a previous invocation of this command
179-
* @return
179+
* @return The iterator-data pair
180180
*/
181181
public ChunksData scanDump(int iter) {
182182
return get(scanDumpAsync(iter));
@@ -189,8 +189,8 @@ public RFuture<ChunksData> scanDumpAsync(int iter) {
189189
/**
190190
* Restores a filter previously saved using SCANDUMP
191191
*
192-
* @param chunk
193-
* @return
192+
* @param chunk Data chunk
193+
* @return True if executed correctly, or false reply otherwise
194194
*/
195195
public boolean loadChunk(ChunksData chunk) {
196196
return get(loadChunkAsync(chunk));

redisbloom/src/main/java/io/github/dengliming/redismodule/redisbloom/CountMinSketch.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.redisson.command.CommandAsyncExecutor;
2727

2828
import java.util.ArrayList;
29+
import java.util.Collections;
2930
import java.util.List;
3031

3132
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.CMS_INCRBY;
@@ -83,7 +84,7 @@ public RFuture<Boolean> createAsync(double errorRadio, double probability) {
8384
*
8485
* @param items
8586
* @param increments
86-
* @return
87+
* @return List reply of Integer reply with an updated min-count of each of the items in the sketch
8788
*/
8889
public List<Integer> incrby(String[] items, int[] increments) {
8990
return get(incrbyAsync(items, increments));
@@ -125,7 +126,7 @@ public RFuture<List<Integer>> queryAsync(String... items) {
125126
* @param keyNum Number of sketches to be merged
126127
* @param srcs Names of source sketches to be merged
127128
* @param weights Multiple of each sketch. Default =1
128-
* @return
129+
* @return True if executed correctly, or False reply otherwise
129130
*/
130131
public boolean merge(int keyNum, String[] srcs, Integer[] weights) {
131132
RAssert.notEmpty(srcs, "Srcs must not be empty");
@@ -137,19 +138,16 @@ public RFuture<Boolean> mergeAsync(int keyNum, String[] srcs, Integer[] weights)
137138
List<Object> params = new ArrayList<>();
138139
params.add(getName());
139140
params.add(keyNum);
140-
for (String src : srcs) {
141-
params.add(src);
142-
}
141+
Collections.addAll(params, srcs);
143142
if (weights.length > 0) {
144143
params.add(Keywords.WEIGHTS);
145-
for (Integer weight : weights) {
146-
params.add(weight);
147-
}
144+
Collections.addAll(params, weights);
148145
}
149146
return commandExecutor.writeAsync(getName(), codec, CMS_MERGE, params.toArray());
150147
}
151148

152149
/**
150+
* Get the information of the filter.
153151
*
154152
* @return width, depth and total count of the sketch
155153
*/

redisbloom/src/main/java/io/github/dengliming/redismodule/redisbloom/CuckooFilter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public RFuture<Integer> countAsync(String item) {
216216
/**
217217
* Get information about key
218218
*
219-
* @return
219+
* @return The information of the filter
220220
*/
221221
public CuckooFilterInfo getInfo() {
222222
return get(getInfoAsync());

redisbloom/src/main/java/io/github/dengliming/redismodule/redisbloom/TDigest.java

Lines changed: 102 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,19 @@
3030

3131
import static io.github.dengliming.redismodule.redisbloom.protocol.Keywords.COMPRESSION;
3232
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_ADD;
33+
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_BYRANK;
34+
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_BYREVRANK;
3335
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_CDF;
3436
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_CREATE;
3537
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_INFO;
3638
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_MAX;
3739
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_MERGE;
3840
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_MIN;
3941
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_QUANTILE;
42+
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_RANK;
4043
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_RESET;
44+
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_REVRANK;
45+
import static io.github.dengliming.redismodule.redisbloom.protocol.RedisCommands.TDIGEST_TRIMMED_MEAN;
4146

4247
public class TDigest extends RedissonObject {
4348

@@ -151,13 +156,7 @@ public List<Double> getQuantile(double... quantiles) {
151156

152157
public RFuture<List<Double>> getQuantileAsync(double... quantiles) {
153158
RAssert.notEmpty(quantiles, "quantiles must not be empty");
154-
155-
List<Object> params = new ArrayList<>(quantiles.length + 1);
156-
params.add(getName());
157-
for (double quantile : quantiles) {
158-
params.add(quantile);
159-
}
160-
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, TDIGEST_QUANTILE, params.toArray());
159+
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, TDIGEST_QUANTILE, buildParamsWithDoubleValues(quantiles));
161160
}
162161

163162
/**
@@ -174,12 +173,7 @@ public List<Double> getCdf(double... values) {
174173

175174
public RFuture<List<Double>> getCdfAsync(double... values) {
176175
RAssert.notEmpty(values, "values must not be empty");
177-
List<Object> params = new ArrayList<>(values.length + 1);
178-
params.add(getName());
179-
for (double value : values) {
180-
params.add(value);
181-
}
182-
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, TDIGEST_CDF, params.toArray());
176+
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, TDIGEST_CDF, buildParamsWithDoubleValues(values));
183177
}
184178

185179
/**
@@ -209,4 +203,99 @@ public TDigestInfo getInfo() {
209203
public RFuture<TDigestInfo> getInfoAsync() {
210204
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, TDIGEST_INFO, getName());
211205
}
206+
207+
/**
208+
* TDIGEST.RANK key value [value ...]
209+
*
210+
* @since Bloom 2.4.0
211+
* @return An array of results populated with rank_1, rank_2, ..., rank_N.
212+
*/
213+
public List<Integer> rank(double... values) {
214+
return get(rankAsync(values));
215+
}
216+
217+
public RFuture<List<Integer>> rankAsync(double... values) {
218+
RAssert.notEmpty(values, "values must not be empty");
219+
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, TDIGEST_RANK, buildParamsWithDoubleValues(values));
220+
}
221+
222+
/**
223+
* TDIGEST.REVRANK key value [value ...]
224+
*
225+
* @since Bloom 2.4.0
226+
* @return An array of results populated with rank_1, rank_2, ..., rank_N.
227+
*/
228+
public List<Integer> revRank(double... values) {
229+
return get(revRankAsync(values));
230+
}
231+
232+
public RFuture<List<Integer>> revRankAsync(double... values) {
233+
RAssert.notEmpty(values, "values must not be empty");
234+
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, TDIGEST_REVRANK, buildParamsWithDoubleValues(values));
235+
}
236+
237+
/**
238+
* TDIGEST.BYRANK key rank [rank ...]
239+
*
240+
* @since Bloom 2.4.0
241+
* @return An array of results populated with rank_1, rank_2, ..., rank_N.
242+
*/
243+
public List<Double> byRank(int... ranks) {
244+
return get(byRankAsync(ranks));
245+
}
246+
247+
public RFuture<List<Double>> byRankAsync(int... ranks) {
248+
RAssert.notEmpty(ranks, "ranks must not be empty");
249+
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, TDIGEST_BYRANK, buildParamsWithIntValues(ranks));
250+
}
251+
252+
/**
253+
* TDIGEST.BYREVRANK key reverse_rank [reverse_rank ...]
254+
*
255+
* @since Bloom 2.4.0
256+
* @return An array of results populated with rank_1, rank_2, ..., rank_N.
257+
*/
258+
public List<Double> byRevRank(int... reverseRanks) {
259+
return get(byRevRankAsync(reverseRanks));
260+
}
261+
262+
public RFuture<List<Double>> byRevRankAsync(int... reverseRanks) {
263+
RAssert.notEmpty(reverseRanks, "reverseRanks must not be empty");
264+
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, TDIGEST_BYREVRANK, buildParamsWithIntValues(reverseRanks));
265+
}
266+
267+
/**
268+
* TDIGEST.TRIMMED_MEAN key low_cut_quantile high_cut_quantile
269+
*
270+
* @param lowCutQuantile Exclude observation values lower than this quantile
271+
* @param highCutQuantile Exclude observation values higher than this quantile
272+
* @since Bloom 2.4.0
273+
* @return The estimation of the mean value.
274+
*/
275+
public String trimmedMean(double lowCutQuantile, double highCutQuantile) {
276+
return get(trimmedMeanAsync(lowCutQuantile, highCutQuantile));
277+
}
278+
279+
public RFuture<String> trimmedMeanAsync(double lowCutQuantile, double highCutQuantile) {
280+
return commandExecutor.readAsync(getName(), StringCodec.INSTANCE, TDIGEST_TRIMMED_MEAN, getName(),
281+
lowCutQuantile, highCutQuantile);
282+
}
283+
284+
private Object[] buildParamsWithDoubleValues(double... values) {
285+
List<Object> params = new ArrayList<>(values.length + 1);
286+
params.add(getName());
287+
for (double value : values) {
288+
params.add(value);
289+
}
290+
return params.toArray();
291+
}
292+
293+
private Object[] buildParamsWithIntValues(int... values) {
294+
List<Object> params = new ArrayList<>(values.length + 1);
295+
params.add(getName());
296+
for (int value : values) {
297+
params.add(value);
298+
}
299+
return params.toArray();
300+
}
212301
}

redisbloom/src/main/java/io/github/dengliming/redismodule/redisbloom/protocol/RedisCommands.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,9 @@ public interface RedisCommands {
8787
RedisCommand<List<Double>> TDIGEST_QUANTILE = new RedisCommand("TDIGEST.QUANTILE", new ObjectListReplayDecoder(), new DoubleReplayConvertor());
8888
RedisCommand<List<Double>> TDIGEST_CDF = new RedisCommand("TDIGEST.CDF", new ObjectListReplayDecoder(), new DoubleReplayConvertor());
8989
RedisCommand TDIGEST_MERGE = new RedisCommand("TDIGEST.MERGE", new BooleanReplayConvertor());
90+
RedisCommand<List<Integer>> TDIGEST_RANK = new RedisCommand("TDIGEST.RANK", new ObjectListReplayDecoder(), new IntegerReplayConvertor());
91+
RedisCommand<List<Integer>> TDIGEST_REVRANK = new RedisCommand("TDIGEST.REVRANK", new ObjectListReplayDecoder(), new IntegerReplayConvertor());
92+
RedisCommand<List<Double>> TDIGEST_BYRANK = new RedisCommand("TDIGEST.BYRANK", new ObjectListReplayDecoder(), new DoubleReplayConvertor());
93+
RedisCommand<List<Double>> TDIGEST_BYREVRANK = new RedisCommand("TDIGEST.BYREVRANK", new ObjectListReplayDecoder(), new DoubleReplayConvertor());
94+
RedisCommand TDIGEST_TRIMMED_MEAN = new RedisCommand("TDIGEST.TRIMMED_MEAN");
9095
}

redisbloom/src/test/java/io/github/dengliming/redismodule/redisbloom/BloomFilterTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void testReserve() {
4141
public void testAdd() {
4242
BloomFilter bloomFilter = getRedisBloomClient().getRBloomFilter("bf_add");
4343
assertThat(bloomFilter.create(0.1d, 100)).isTrue();
44-
List<Boolean> results = bloomFilter.madd(new String[]{"a", "b", "c"});
44+
List<Boolean> results = bloomFilter.madd("a", "b", "c");
4545
assertThat(results).isNotNull().hasSize(3);
4646
assertThat(bloomFilter.exists("a")).isTrue();
4747
}

redisbloom/src/test/java/io/github/dengliming/redismodule/redisbloom/CountMinSketchTest.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
import io.github.dengliming.redismodule.redisbloom.model.CountMinSketchInfo;
2020
import org.junit.jupiter.api.Test;
2121

22-
import java.util.HashMap;
2322
import java.util.List;
24-
import java.util.Map;
2523

2624
import static org.assertj.core.api.Assertions.assertThat;
2725

@@ -43,7 +41,6 @@ public void testReserve() {
4341
public void testAdd() {
4442
CountMinSketch countMinSketch = getRedisBloomClient().getCountMinSketch("cms_add");
4543
assertThat(countMinSketch.create(10, 10)).isTrue();
46-
Map<String, Integer> itemIncrement = new HashMap<>();
4744
List<Integer> results = countMinSketch.incrby(new String[]{"a"}, new int[]{3});
4845
assertThat(results).isNotNull().hasSize(1);
4946
assertThat(results.get(0)).isEqualTo(3);

0 commit comments

Comments
 (0)