diff --git a/pom.xml b/pom.xml index fa9be00b4d..69d56c082c 100644 --- a/pom.xml +++ b/pom.xml @@ -208,7 +208,7 @@ - + org.apache.felix maven-bundle-plugin @@ -217,11 +217,11 @@ bundle-manifest process-classes - + manifest - + - + diff --git a/src/main/java/redis/clients/jedis/BinaryClient.java b/src/main/java/redis/clients/jedis/BinaryClient.java index 3c48a867d8..05e317139d 100644 --- a/src/main/java/redis/clients/jedis/BinaryClient.java +++ b/src/main/java/redis/clients/jedis/BinaryClient.java @@ -1750,6 +1750,10 @@ public void xtrim(byte[] key, long maxLen, boolean approximateLength) { } } + public void xtrim(byte[] key, XTrimParams params) { + sendCommand(XTRIM, params.getByteParams(key)); + } + /** * @deprecated This method will be removed due to bug regarding {@code block} param. Use * {@link #xreadGroup(byte..., byte..., redis.clients.jedis.params.XReadGroupParams, java.util.Map.Entry...)}. diff --git a/src/main/java/redis/clients/jedis/BinaryJedis.java b/src/main/java/redis/clients/jedis/BinaryJedis.java index 292d6e2796..aab02a7ba7 100644 --- a/src/main/java/redis/clients/jedis/BinaryJedis.java +++ b/src/main/java/redis/clients/jedis/BinaryJedis.java @@ -4729,6 +4729,13 @@ public Long xtrim(byte[] key, long maxLen, boolean approximateLength) { return client.getIntegerReply(); } + @Override + public Long xtrim(byte[] key, XTrimParams params) { + checkIsInMultiOrPipeline(); + client.xtrim(key, params); + return client.getIntegerReply(); + } + @Override public List xpending(byte[] key, byte[] groupname, byte[] start, byte[] end, int count, byte[] consumername) { diff --git a/src/main/java/redis/clients/jedis/BinaryJedisCluster.java b/src/main/java/redis/clients/jedis/BinaryJedisCluster.java index d6c3a53b35..9878129d1b 100644 --- a/src/main/java/redis/clients/jedis/BinaryJedisCluster.java +++ b/src/main/java/redis/clients/jedis/BinaryJedisCluster.java @@ -2638,6 +2638,16 @@ public Long execute(Jedis connection) { }.runBinary(key); } + @Override + public Long xtrim(final byte[] key, final XTrimParams params) { + return new JedisClusterCommand(connectionHandler, maxAttempts) { + @Override + public Long execute(Jedis connection) { + return connection.xtrim(key, params); + } + }.runBinary(key); + } + @Override public List xpending(final byte[] key, final byte[] groupname, final byte[] start, final byte[] end, final int count, final byte[] consumername) { diff --git a/src/main/java/redis/clients/jedis/BinaryShardedJedis.java b/src/main/java/redis/clients/jedis/BinaryShardedJedis.java index 46753b1e85..ac25d991a8 100644 --- a/src/main/java/redis/clients/jedis/BinaryShardedJedis.java +++ b/src/main/java/redis/clients/jedis/BinaryShardedJedis.java @@ -15,6 +15,7 @@ import redis.clients.jedis.params.GetExParams; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import redis.clients.jedis.params.LPosParams; @@ -1205,6 +1206,12 @@ public Long xtrim(byte[] key, long maxLen, boolean approximateLength) { return j.xtrim(key, maxLen, approximateLength); } + @Override + public Long xtrim(byte[] key, XTrimParams params) { + Jedis j = getShard(key); + return j.xtrim(key, params); + } + @Override public List xpending(byte[] key, byte[] groupname, byte[] start, byte[] end, int count, byte[] consumername) { diff --git a/src/main/java/redis/clients/jedis/Client.java b/src/main/java/redis/clients/jedis/Client.java index c96b1b5572..a7718fb13f 100644 --- a/src/main/java/redis/clients/jedis/Client.java +++ b/src/main/java/redis/clients/jedis/Client.java @@ -1501,6 +1501,11 @@ public void xtrim(String key, long maxLen, boolean approximateLength) { xtrim(SafeEncoder.encode(key), maxLen, approximateLength); } + @Override + public void xtrim(String key, XTrimParams params) { + xtrim(SafeEncoder.encode(key), params); + } + @Override public void xreadGroup(String groupname, String consumer, int count, long block, boolean noAck, Entry... streams) { diff --git a/src/main/java/redis/clients/jedis/Jedis.java b/src/main/java/redis/clients/jedis/Jedis.java index 2a9fc1eff1..785a8743ae 100644 --- a/src/main/java/redis/clients/jedis/Jedis.java +++ b/src/main/java/redis/clients/jedis/Jedis.java @@ -4257,6 +4257,13 @@ public long xtrim(final String key, final long maxLen, final boolean approximate return client.getIntegerReply(); } + @Override + public long xtrim(final String key, final XTrimParams params) { + checkIsInMultiOrPipeline(); + client.xtrim(key, params); + return client.getIntegerReply(); + } + /** * {@inheritDoc} */ diff --git a/src/main/java/redis/clients/jedis/JedisCluster.java b/src/main/java/redis/clients/jedis/JedisCluster.java index 72a053999d..eb3cf49303 100644 --- a/src/main/java/redis/clients/jedis/JedisCluster.java +++ b/src/main/java/redis/clients/jedis/JedisCluster.java @@ -2742,6 +2742,16 @@ public Long execute(Jedis connection) { }.run(key); } + @Override + public Long xtrim(final String key, final XTrimParams params) { + return new JedisClusterCommand(connectionHandler, maxAttempts) { + @Override + public Long execute(Jedis connection) { + return connection.xtrim(key, params); + } + }.run(key); + } + @Override public List xclaim(final String key, final String group, final String consumername, final long minIdleTime, final long newIdleTime, final int retries, final boolean force, diff --git a/src/main/java/redis/clients/jedis/PipelineBase.java b/src/main/java/redis/clients/jedis/PipelineBase.java index 9d3af6754a..af48349056 100644 --- a/src/main/java/redis/clients/jedis/PipelineBase.java +++ b/src/main/java/redis/clients/jedis/PipelineBase.java @@ -12,6 +12,7 @@ import redis.clients.jedis.params.GetExParams; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import redis.clients.jedis.params.LPosParams; @@ -2304,6 +2305,18 @@ public Response xtrim(byte[] key, long maxLen, boolean approximateLength) return getResponse(BuilderFactory.LONG); } + @Override + public Response xtrim(byte[] key, XTrimParams params) { + getClient(key).xtrim(key, params); + return getResponse(BuilderFactory.LONG); + } + + @Override + public Response xtrim(String key, XTrimParams params) { + getClient(key).xtrim(key, params); + return getResponse(BuilderFactory.LONG); + } + @Override public Response> xclaim(String key, String group, String consumername, long minIdleTime, long newIdleTime, int retries, boolean force, StreamEntryID... ids) { diff --git a/src/main/java/redis/clients/jedis/Protocol.java b/src/main/java/redis/clients/jedis/Protocol.java index 96aedda1c7..2174cc0c0c 100644 --- a/src/main/java/redis/clients/jedis/Protocol.java +++ b/src/main/java/redis/clients/jedis/Protocol.java @@ -73,6 +73,7 @@ public final class Protocol { public static final byte[] BYTES_TRUE = toByteArray(1); public static final byte[] BYTES_FALSE = toByteArray(0); public static final byte[] BYTES_TILDE = SafeEncoder.encode("~"); + public static final byte[] BYTES_EQUAL = SafeEncoder.encode("="); public static final byte[] POSITIVE_INFINITY_BYTES = "+inf".getBytes(); public static final byte[] NEGATIVE_INFINITY_BYTES = "-inf".getBytes(); @@ -283,7 +284,7 @@ public static enum Keyword implements Rawable { GETNAME, SETNAME, LIST, MATCH, COUNT, PING, PONG, UNLOAD, REPLACE, KEYS, PAUSE, DOCTOR, BLOCK, NOACK, STREAMS, KEY, CREATE, MKSTREAM, SETID, DESTROY, DELCONSUMER, MAXLEN, GROUP, ID, IDLE, TIME, RETRYCOUNT, FORCE, USAGE, SAMPLES, STREAM, GROUPS, CONSUMERS, HELP, FREQ, SETUSER, - GETUSER, DELUSER, WHOAMI, CAT, GENPASS, USERS, LOG, INCR, SAVE, JUSTID, WITHVALUES, UNBLOCK; + GETUSER, DELUSER, WHOAMI, CAT, GENPASS, USERS, LOG, INCR, SAVE, JUSTID, WITHVALUES, UNBLOCK, MINID; /** * @deprecated This will be private in future. Use {@link #getRaw()}. diff --git a/src/main/java/redis/clients/jedis/ShardedJedis.java b/src/main/java/redis/clients/jedis/ShardedJedis.java index 2c3fb2a073..651893cfc1 100644 --- a/src/main/java/redis/clients/jedis/ShardedJedis.java +++ b/src/main/java/redis/clients/jedis/ShardedJedis.java @@ -14,6 +14,7 @@ import redis.clients.jedis.params.GetExParams; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import redis.clients.jedis.params.LPosParams; @@ -1189,6 +1190,12 @@ public long xtrim(String key, long maxLen, boolean approximateLength) { return j.xtrim(key, maxLen, approximateLength); } + @Override + public long xtrim(String key, XTrimParams params) { + Jedis j = getShard(key); + return j.xtrim(key, params); + } + @Override public List xrevrange(String key, StreamEntryID end, StreamEntryID start) { Jedis j = getShard(key); diff --git a/src/main/java/redis/clients/jedis/commands/BinaryJedisClusterCommands.java b/src/main/java/redis/clients/jedis/commands/BinaryJedisClusterCommands.java index 3f222ddd72..45f18dcd6a 100644 --- a/src/main/java/redis/clients/jedis/commands/BinaryJedisClusterCommands.java +++ b/src/main/java/redis/clients/jedis/commands/BinaryJedisClusterCommands.java @@ -13,6 +13,7 @@ import redis.clients.jedis.params.GetExParams; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import redis.clients.jedis.params.LPosParams; @@ -415,6 +416,8 @@ List georadiusByMemberReadonly(byte[] key, byte[] member, dou Long xtrim(byte[] key, long maxLen, boolean approximateLength); + Long xtrim(byte[] key, XTrimParams params); + Object xpending(final byte[] key, final byte[] groupname); List xpending(byte[] key, byte[] groupname, byte[] start, byte[] end, int count, byte[] consumername); diff --git a/src/main/java/redis/clients/jedis/commands/BinaryJedisCommands.java b/src/main/java/redis/clients/jedis/commands/BinaryJedisCommands.java index 06fc0af9d5..10fc9ca803 100644 --- a/src/main/java/redis/clients/jedis/commands/BinaryJedisCommands.java +++ b/src/main/java/redis/clients/jedis/commands/BinaryJedisCommands.java @@ -20,6 +20,7 @@ import redis.clients.jedis.params.GetExParams; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import redis.clients.jedis.params.LPosParams; @@ -445,6 +446,8 @@ default List xrange(byte[] key, byte[] start, byte[] end, long count) { Long xtrim(byte[] key, long maxLen, boolean approximateLength); + Long xtrim(byte[] key, XTrimParams params); + Object xpending(byte[] key, byte[] groupname); List xpending(byte[] key, byte[] groupname, byte[] start, byte[] end, int count, byte[] consumername); diff --git a/src/main/java/redis/clients/jedis/commands/BinaryRedisPipeline.java b/src/main/java/redis/clients/jedis/commands/BinaryRedisPipeline.java index ae302720e4..c2cca237eb 100644 --- a/src/main/java/redis/clients/jedis/commands/BinaryRedisPipeline.java +++ b/src/main/java/redis/clients/jedis/commands/BinaryRedisPipeline.java @@ -14,6 +14,7 @@ import redis.clients.jedis.params.GetExParams; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import redis.clients.jedis.params.LPosParams; @@ -417,6 +418,8 @@ Response> georadiusByMemberReadonly(byte[] key, byte[] m Response xtrim(byte[] key, long maxLen, boolean approximateLength); + Response xtrim(byte[] key, XTrimParams params); + Response> xclaim(byte[] key, byte[] group, byte[] consumername, long minIdleTime, long newIdleTime, int retries, boolean force, byte[]... ids); diff --git a/src/main/java/redis/clients/jedis/commands/Commands.java b/src/main/java/redis/clients/jedis/commands/Commands.java index 4974e789de..028cd8ced6 100644 --- a/src/main/java/redis/clients/jedis/commands/Commands.java +++ b/src/main/java/redis/clients/jedis/commands/Commands.java @@ -15,6 +15,7 @@ import redis.clients.jedis.params.ClientKillParams; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import redis.clients.jedis.params.LPosParams; @@ -494,6 +495,8 @@ default void restoreReplace(String key, int ttl, byte[] serializedValue) { void xtrim(String key, long maxLen, boolean approximateLength); + void xtrim(String key, XTrimParams params); + /** * @deprecated This method will be removed due to bug regarding {@code block} param. Use * {@link #xreadGroup(java.lang.String, java.lang.String, redis.clients.jedis.params.XReadGroupParams, java.util.Map)}. diff --git a/src/main/java/redis/clients/jedis/commands/JedisClusterCommands.java b/src/main/java/redis/clients/jedis/commands/JedisClusterCommands.java index 9da25a8db9..dd265d05e5 100644 --- a/src/main/java/redis/clients/jedis/commands/JedisClusterCommands.java +++ b/src/main/java/redis/clients/jedis/commands/JedisClusterCommands.java @@ -16,6 +16,7 @@ import redis.clients.jedis.params.GetExParams; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import redis.clients.jedis.params.LPosParams; @@ -581,6 +582,14 @@ List georadiusByMemberReadonly(String key, String member, dou */ Long xtrim( String key, long maxLen, boolean approximateLength); + /** + * XTRIM key MAXLEN|MINID [=|~] threshold [LIMIT count] + * @param key + * @param params + * @return + */ + Long xtrim(String key, XTrimParams params); + /** * XCLAIM * [IDLE ] [TIME ] [RETRYCOUNT ] diff --git a/src/main/java/redis/clients/jedis/commands/JedisCommands.java b/src/main/java/redis/clients/jedis/commands/JedisCommands.java index 07648a8f52..8f4913cf1e 100644 --- a/src/main/java/redis/clients/jedis/commands/JedisCommands.java +++ b/src/main/java/redis/clients/jedis/commands/JedisCommands.java @@ -25,6 +25,7 @@ import redis.clients.jedis.params.GetExParams; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import redis.clients.jedis.params.LPosParams; @@ -585,6 +586,14 @@ List xpending(String key, String groupname, StreamEntryID st */ long xtrim( String key, long maxLen, boolean approximate); + /** + * XTRIM key MAXLEN|MINID [=|~] threshold [LIMIT count] + * @param key + * @param params + * @return + */ + long xtrim(String key, XTrimParams params); + /** * XCLAIM * [IDLE ] [TIME ] [RETRYCOUNT ] diff --git a/src/main/java/redis/clients/jedis/commands/RedisPipeline.java b/src/main/java/redis/clients/jedis/commands/RedisPipeline.java index 8d4f59974a..2e95005375 100644 --- a/src/main/java/redis/clients/jedis/commands/RedisPipeline.java +++ b/src/main/java/redis/clients/jedis/commands/RedisPipeline.java @@ -17,6 +17,7 @@ import redis.clients.jedis.params.GetExParams; import redis.clients.jedis.params.SetParams; import redis.clients.jedis.params.XClaimParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.params.ZAddParams; import redis.clients.jedis.params.ZIncrByParams; import redis.clients.jedis.params.LPosParams; @@ -409,6 +410,8 @@ Response> xpending(String key, String groupname, Response xtrim( String key, long maxLen, boolean approximateLength); + Response xtrim(String key, XTrimParams params); + Response> xclaim( String key, String group, String consumername, long minIdleTime, long newIdleTime, int retries, boolean force, StreamEntryID... ids); diff --git a/src/main/java/redis/clients/jedis/params/XTrimParams.java b/src/main/java/redis/clients/jedis/params/XTrimParams.java new file mode 100644 index 0000000000..2bdd508d11 --- /dev/null +++ b/src/main/java/redis/clients/jedis/params/XTrimParams.java @@ -0,0 +1,90 @@ +package redis.clients.jedis.params; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import redis.clients.jedis.Protocol; +import redis.clients.jedis.util.SafeEncoder; + +import static redis.clients.jedis.Protocol.Keyword.LIMIT; +import static redis.clients.jedis.Protocol.Keyword.MAXLEN; +import static redis.clients.jedis.Protocol.Keyword.MINID; + +public class XTrimParams extends Params { + + private Long maxLen; + + private boolean approximateTrimming; + + private boolean exactTrimming; + + private String minId; + + private Long limit; + + public static XTrimParams xTrimParams() { + return new XTrimParams(); + } + + + public XTrimParams maxLen(long maxLen) { + this.maxLen = maxLen; + return this; + } + + public XTrimParams minId(String minId) { + this.minId = minId; + return this; + } + + public XTrimParams approximateTrimming() { + this.approximateTrimming = true; + return this; + } + + public XTrimParams exactTrimming() { + this.exactTrimming = true; + return this; + } + + public XTrimParams limit(long limit) { + this.limit = limit; + return this; + } + + public byte[][] getByteParams(byte[] key, byte[]... args) { + List byteParams = new ArrayList<>(); + byteParams.add(key); + + if (maxLen != null) { + byteParams.add(MAXLEN.getRaw()); + + if (approximateTrimming) { + byteParams.add(Protocol.BYTES_TILDE); + } else if (exactTrimming) { + byteParams.add(Protocol.BYTES_EQUAL); + } + + byteParams.add(Protocol.toByteArray(maxLen)); + } else if (minId != null) { + byteParams.add(MINID.getRaw()); + + if (approximateTrimming) { + byteParams.add(Protocol.BYTES_TILDE); + } else if (exactTrimming) { + byteParams.add(Protocol.BYTES_EQUAL); + } + + byteParams.add(SafeEncoder.encode(minId)); + } + + if (limit != null) { + byteParams.add(LIMIT.getRaw()); + byteParams.add(Protocol.toByteArray(limit)); + } + + Collections.addAll(byteParams, args); + return byteParams.toArray(new byte[byteParams.size()][]); + } +} diff --git a/src/test/java/redis/clients/jedis/tests/commands/StreamsCommandsTest.java b/src/test/java/redis/clients/jedis/tests/commands/StreamsCommandsTest.java index 962a3e44ce..21ce909d05 100644 --- a/src/test/java/redis/clients/jedis/tests/commands/StreamsCommandsTest.java +++ b/src/test/java/redis/clients/jedis/tests/commands/StreamsCommandsTest.java @@ -26,6 +26,7 @@ import redis.clients.jedis.params.XClaimParams; import redis.clients.jedis.params.XReadGroupParams; import redis.clients.jedis.params.XReadParams; +import redis.clients.jedis.params.XTrimParams; import redis.clients.jedis.util.SafeEncoder; public class StreamsCommandsTest extends JedisCommandTestBase { @@ -239,17 +240,32 @@ public void xtrim() { Map map1 = new HashMap(); map1.put("f1", "v1"); - jedis.xadd("xtrim-stream", null, map1); - jedis.xadd("xtrim-stream", null, map1); - jedis.xadd("xtrim-stream", null, map1); - jedis.xadd("xtrim-stream", null, map1); - jedis.xadd("xtrim-stream", null, map1); + for (int i = 1; i <= 5; i++) { + jedis.xadd("xtrim-stream", null, map1); + } assertEquals(5L, jedis.xlen("xtrim-stream").longValue()); jedis.xtrim("xtrim-stream", 3, false); assertEquals(3L, jedis.xlen("xtrim-stream").longValue()); } + @Test + public void xtrimWithParams() { + Map map1 = new HashMap<>(); + map1.put("f1", "v1"); + for (int i = 1; i <= 5; i++) { + jedis.xadd("xtrim-stream", new StreamEntryID("0-" + i), map1); + } + assertEquals(5L, jedis.xlen("xtrim-stream").longValue()); + + jedis.xtrim("xtrim-stream", XTrimParams.xTrimParams().maxLen(3).exactTrimming()); + assertEquals(3L, jedis.xlen("xtrim-stream").longValue()); + + // minId + jedis.xtrim("xtrim-stream", XTrimParams.xTrimParams().minId("0-4").exactTrimming()); + assertEquals(2L, jedis.xlen("xtrim-stream").longValue()); + } + @Test public void xrevrange() { List range = jedis.xrevrange("xrevrange-stream", (StreamEntryID) null,