From a00a5eb5e204ee9df7e9b94797d94f9018d456d9 Mon Sep 17 00:00:00 2001 From: redkale Date: Sun, 11 Jun 2023 20:16:49 +0800 Subject: [PATCH] =?UTF-8?q?CacheSource=E5=A2=9E=E5=8A=A0diff=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/redkale/source/CacheMemorySource.java | 55 +++- .../java/org/redkale/source/CacheSource.java | 278 +++++++++--------- src/main/java/org/redkale/util/Utility.java | 93 ++++++ 3 files changed, 292 insertions(+), 134 deletions(-) diff --git a/src/main/java/org/redkale/source/CacheMemorySource.java b/src/main/java/org/redkale/source/CacheMemorySource.java index 7e1ee6676..8d6b349ff 100644 --- a/src/main/java/org/redkale/source/CacheMemorySource.java +++ b/src/main/java/org/redkale/source/CacheMemorySource.java @@ -922,6 +922,57 @@ public final class CacheMemorySource extends AbstractCacheSource { return supplyAsync(() -> del(keys), getExecutor()).whenComplete(futureCompleteConsumer); } + @Override + public CompletableFuture> sdiffAsync(final String key, final Type componentType, final String... key2s) { + return supplyAsync(() -> sdiff(key, componentType, key2s), getExecutor()).whenComplete(futureCompleteConsumer); + } + + @Override + public CompletableFuture sdiffstoreAsync(final String key, final String srcKey, final String... srcKey2s) { + return supplyAsync(() -> sdiffstore(key, srcKey, srcKey2s), getExecutor()).whenComplete(futureCompleteConsumer); + } + + @Override + public Set sdiff(final String key, final Type componentType, final String... key2s) { + Set rs = new HashSet<>(); + CacheEntry entry = container.get(key); + if (entry == null || entry.csetValue == null) { + return rs; + } + rs.addAll(entry.csetValue); + for (String k : key2s) { + CacheEntry en2 = container.get(k); + if (en2 != null && en2.csetValue != null) { + en2.csetValue.forEach(v -> rs.remove(v)); + } + } + return rs; + } + + @Override + public long sdiffstore(final String key, final String srcKey, final String... srcKey2s) { + Set rs = new HashSet<>(); + CacheEntry entry = container.get(srcKey); + if (entry == null || entry.csetValue == null) { + return 0L; + } + rs.addAll(entry.csetValue); + for (String k : srcKey2s) { + CacheEntry en2 = container.get(k); + if (en2 != null && en2.csetValue != null) { + en2.csetValue.forEach(v -> rs.remove(v)); + } + } + if (container.containsKey(key)) { + CopyOnWriteArraySet set = container.get(srcKey).csetValue; + set.clear(); + set.addAll(rs); + } else { + appendSetItem(CacheEntryType.OBJECT_SET, key, rs); + } + return rs.size(); + } + @Override public Set smembers(final String key, final Type componentType) { return (Set) get(key, componentType); @@ -1322,7 +1373,7 @@ public final class CacheMemorySource extends AbstractCacheSource { return list; } - protected void appendSetItem(CacheEntryType cacheType, String key, List values) { + protected void appendSetItem(CacheEntryType cacheType, String key, Collection values) { if (key == null) { return; } @@ -1344,7 +1395,7 @@ public final class CacheMemorySource extends AbstractCacheSource { @Override public void sadd(String key, final Type componentType, T... values) { - appendSetItem(CacheEntryType.OBJECT_SET, key, List.of(values)); + appendSetItem(CacheEntryType.OBJECT_SET, key, List.of(values)); } @Override diff --git a/src/main/java/org/redkale/source/CacheSource.java b/src/main/java/org/redkale/source/CacheSource.java index f24953acc..29f0b46b6 100644 --- a/src/main/java/org/redkale/source/CacheSource.java +++ b/src/main/java/org/redkale/source/CacheSource.java @@ -202,71 +202,31 @@ public interface CacheSource extends Resourcable { public double incrbyFloat(final String key, double num); - //------------------------ hget ------------------------ - public T hget(final String key, final String field, final Type type); + //------------------------ 键 Keys ------------------------ + public List keys(String pattern); - default String hgetString(final String key, final String field) { - return hget(key, field, String.class); + default List keys() { + return keys(null); } - default long hgetLong(final String key, final String field, long defValue) { - Long val = hget(key, field, Long.class); - return val == null ? defValue : val; + default List keysStartsWith(String startsWith) { + return keys(startsWith + "*"); } - //------------------------ hset ------------------------ - public void hset(final String key, final String field, final Convert convert, final Type type, final T value); + public List scan(AtomicLong cursor, int limit, String pattern); - default void hset(final String key, final String field, final Type type, final T value) { - hset(key, field, (Convert) null, type, value); + default List scan(AtomicLong cursor, int limit) { + return scan(cursor, limit, null); } - default void hsetString(final String key, final String field, final String value) { - hset(key, field, String.class, value); - } + //------------------------ 服务器 Server ------------------------ + public long dbsize(); - default void hsetLong(final String key, final String field, final long value) { - hset(key, field, Long.class, value); - } + public void flushdb(); - //------------------------ hsetnx ------------------------ - public boolean hsetnx(final String key, final String field, final Convert convert, final Type type, final T value); + public void flushall(); - default boolean hsetnx(final String key, final String field, final Type type, final T value) { - return hsetnx(key, field, (Convert) null, type, value); - } - - default boolean hsetnxString(final String key, final String field, final String value) { - return hsetnx(key, field, String.class, value); - } - - default boolean hsetnxLong(final String key, final String field, final long value) { - return hsetnx(key, field, Long.class, value); - } - - //------------------------ hgetall ------------------------ - public Map hgetall(final String key, final Type type); - - default Map hgetallString(final String key) { - return hgetall(key, String.class); - } - - default Map hgetallLong(final String key) { - return hgetall(key, Long.class); - } - - //------------------------ hvals ------------------------ - public List hvals(final String key, final Type type); - - default List hvalsString(final String key) { - return hvals(key, String.class); - } - - default List hvalsLong(final String key) { - return hvals(key, Long.class); - } - - //------------------------ hxxx ------------------------ + //------------------------ 哈希表 Hash ------------------------ public long hdel(final String key, String... fields); public List hkeys(final String key); @@ -285,7 +245,6 @@ public interface CacheSource extends Resourcable { public boolean hexists(final String key, String field); - //------------------------ hmxx ------------------------ public void hmset(final String key, final Serializable... values); public void hmset(final String key, final Map map); @@ -306,7 +265,66 @@ public interface CacheSource extends Resourcable { return hscan(key, type, cursor, limit, null); } - //------------------------ list ------------------------ + public T hget(final String key, final String field, final Type type); + + default String hgetString(final String key, final String field) { + return hget(key, field, String.class); + } + + default long hgetLong(final String key, final String field, long defValue) { + Long val = hget(key, field, Long.class); + return val == null ? defValue : val; + } + + public void hset(final String key, final String field, final Convert convert, final Type type, final T value); + + default void hset(final String key, final String field, final Type type, final T value) { + hset(key, field, (Convert) null, type, value); + } + + default void hsetString(final String key, final String field, final String value) { + hset(key, field, String.class, value); + } + + default void hsetLong(final String key, final String field, final long value) { + hset(key, field, Long.class, value); + } + + public boolean hsetnx(final String key, final String field, final Convert convert, final Type type, final T value); + + default boolean hsetnx(final String key, final String field, final Type type, final T value) { + return hsetnx(key, field, (Convert) null, type, value); + } + + default boolean hsetnxString(final String key, final String field, final String value) { + return hsetnx(key, field, String.class, value); + } + + default boolean hsetnxLong(final String key, final String field, final long value) { + return hsetnx(key, field, Long.class, value); + } + + public Map hgetall(final String key, final Type type); + + default Map hgetallString(final String key) { + return hgetall(key, String.class); + } + + default Map hgetallLong(final String key) { + return hgetall(key, Long.class); + } + + public List hvals(final String key, final Type type); + + default List hvalsString(final String key) { + return hvals(key, String.class); + } + + default List hvalsLong(final String key) { + return hvals(key, Long.class); + } + + //------------------------ 列表 List ------------------------ public long llen(final String key); public void ltrim(final String key, int start, int stop); @@ -423,7 +441,29 @@ public interface CacheSource extends Resourcable { rpush(key, Long.class, values); } - //------------------------ set ------------------------ + //------------------------ 集合 Set ------------------------ + public void sadd(final String key, final Type componentType, final T... values); + + default void saddString(final String key, final String... values) { + sadd(key, String.class, values); + } + + default void saddLong(final String key, final Long... values) { + sadd(key, Long.class, values); + } + + public Set sdiff(final String key, final Type componentType, final String... key2s); + + default Set sdiffString(final String key, final String... key2s) { + return sdiff(key, String.class, key2s); + } + + default Set sdiffLong(final String key, final String... key2s) { + return sdiff(key, Long.class, key2s); + } + + public long sdiffstore(final String key, final String srcKey, final String... srcKey2s); + public long scard(final String key); public Set smembers(final String key, final Type componentType); @@ -456,16 +496,6 @@ public interface CacheSource extends Resourcable { return sismember(key, Long.class, value); } - public void sadd(final String key, final Type componentType, final T... values); - - default void saddString(final String key, final String... values) { - sadd(key, String.class, values); - } - - default void saddLong(final String key, final Long... values) { - sadd(key, Long.class, values); - } - public long srem(final String key, final Type componentType, final T... values); default long sremString(final String key, final String... values) { @@ -518,29 +548,6 @@ public interface CacheSource extends Resourcable { return sscan(key, Long.class, cursor, limit, null); } - //------------------------ keys ------------------------ - public List keys(String pattern); - - default List keys() { - return keys(null); - } - - default List keysStartsWith(String startsWith) { - return keys(startsWith + "*"); - } - - public List scan(AtomicLong cursor, int limit, String pattern); - - default List scan(AtomicLong cursor, int limit) { - return scan(cursor, limit, null); - } - - public long dbsize(); - - public void flushdb(); - - public void flushall(); - //---------------------- CompletableFuture 异步版 --------------------------------- default CompletableFuture isOpenAsync() { return CompletableFuture.completedFuture(isOpen()); @@ -712,7 +719,31 @@ public interface CacheSource extends Resourcable { public CompletableFuture incrbyFloatAsync(final String key, double num); - //------------------------ hgetAsync ------------------------ + //------------------------ 键 Keys ------------------------ + public CompletableFuture> keysAsync(String pattern); + + default CompletableFuture> keysAsync() { + return keysAsync(null); + } + + default CompletableFuture> keysStartsWithAsync(String startsWith) { + return keysAsync(startsWith + "*"); + } + + public CompletableFuture> scanAsync(AtomicLong cursor, int limit, String pattern); + + default CompletableFuture> scanAsync(AtomicLong cursor, int limit) { + return scanAsync(cursor, limit, null); + } + + //------------------------ 服务器 Server ------------------------ + public CompletableFuture dbsizeAsync(); + + public CompletableFuture flushdbAsync(); + + public CompletableFuture flushallAsync(); + + //------------------------ 哈希表 Hash ------------------------ public CompletableFuture hgetAsync(final String key, final String field, final Type type); default CompletableFuture hgetStringAsync(final String key, final String field) { @@ -723,7 +754,6 @@ public interface CacheSource extends Resourcable { return hgetAsync(key, field, Long.class).thenApply(v -> v == null ? defValue : (Long) v); } - //------------------------ hsetAsync ------------------------ public CompletableFuture hsetAsync(final String key, final String field, final Convert convert, final Type type, final T value); default CompletableFuture hsetAsync(final String key, final String field, final Type type, final T value) { @@ -738,7 +768,6 @@ public interface CacheSource extends Resourcable { return hsetAsync(key, field, Long.class, value); } - //------------------------ hsetnxAsync ------------------------ public CompletableFuture hsetnxAsync(final String key, final String field, final Convert convert, final Type type, final T value); default CompletableFuture hsetnxAsync(final String key, final String field, final Type type, final T value) { @@ -753,7 +782,6 @@ public interface CacheSource extends Resourcable { return hsetnxAsync(key, field, Long.class, value); } - //------------------------ hgetallAsync ------------------------ public CompletableFuture> hgetallAsync(final String key, final Type type); default CompletableFuture> hgetallStringAsync(final String key) { @@ -764,7 +792,6 @@ public interface CacheSource extends Resourcable { return hgetallAsync(key, Long.class); } - //------------------------ hvalsAsync ------------------------ public CompletableFuture> hvalsAsync(final String key, final Type type); default CompletableFuture> hvalsStringAsync(final String key) { @@ -775,7 +802,6 @@ public interface CacheSource extends Resourcable { return hvalsAsync(key, Long.class); } - //------------------------ hxxxAsync ------------------------ public CompletableFuture hdelAsync(final String key, String... fields); public CompletableFuture> hkeysAsync(final String key); @@ -794,7 +820,6 @@ public interface CacheSource extends Resourcable { public CompletableFuture hexistsAsync(final String key, String field); - //------------------------ hmxxAsync ------------------------ public CompletableFuture hmsetAsync(final String key, final Serializable... values); public CompletableFuture hmsetAsync(final String key, final Map map); @@ -815,7 +840,7 @@ public interface CacheSource extends Resourcable { return hscanAsync(key, type, cursor, limit, null); } - //------------------------ listAsync ------------------------ + //------------------------ 列表 List ------------------------ public CompletableFuture llenAsync(final String key); public CompletableFuture ltrimAsync(final String key, int start, int stop); @@ -932,7 +957,29 @@ public interface CacheSource extends Resourcable { return rpushAsync(key, Long.class, values); } - //------------------------ setAsync ------------------------ + //------------------------ 集合 Set ------------------------ + public CompletableFuture saddAsync(final String key, final Type componentType, final T... values); + + default CompletableFuture saddStringAsync(final String key, final String... values) { + return saddAsync(key, String.class, values); + } + + default CompletableFuture saddLongAsync(final String key, final Long... values) { + return saddAsync(key, Long.class, values); + } + + public CompletableFuture> sdiffAsync(final String key, final Type componentType, final String... key2s); + + default CompletableFuture> sdiffStringAsync(final String key, final String... key2s) { + return sdiffAsync(key, String.class, key2s); + } + + default CompletableFuture> sdiffLongAsync(final String key, final String... key2s) { + return sdiffAsync(key, Long.class, key2s); + } + + public CompletableFuture sdiffstoreAsync(final String key, final String srcKey, final String... srcKey2s); + public CompletableFuture scardAsync(final String key); public CompletableFuture> smembersAsync(final String key, final Type componentType); @@ -965,16 +1012,6 @@ public interface CacheSource extends Resourcable { return sismemberAsync(key, Long.class, value); } - public CompletableFuture saddAsync(final String key, final Type componentType, final T... values); - - default CompletableFuture saddStringAsync(final String key, final String... values) { - return saddAsync(key, String.class, values); - } - - default CompletableFuture saddLongAsync(final String key, final Long... values) { - return saddAsync(key, Long.class, values); - } - public CompletableFuture sremAsync(final String key, final Type componentType, final T... values); default CompletableFuture sremStringAsync(final String key, final String... values) { @@ -1027,29 +1064,6 @@ public interface CacheSource extends Resourcable { return sscanAsync(key, Long.class, cursor, limit); } - //------------------------ keys-Async ------------------------ - public CompletableFuture> keysAsync(String pattern); - - default CompletableFuture> keysAsync() { - return keysAsync(null); - } - - default CompletableFuture> keysStartsWithAsync(String startsWith) { - return keysAsync(startsWith + "*"); - } - - public CompletableFuture> scanAsync(AtomicLong cursor, int limit, String pattern); - - default CompletableFuture> scanAsync(AtomicLong cursor, int limit) { - return scanAsync(cursor, limit, null); - } - - public CompletableFuture dbsizeAsync(); - - public CompletableFuture flushdbAsync(); - - public CompletableFuture flushallAsync(); - //-------------------------- 过期方法 ---------------------------------- @Deprecated(since = "2.8.0") public CompletableFuture> getCollectionAsync(final String key, final Type componentType); diff --git a/src/main/java/org/redkale/util/Utility.java b/src/main/java/org/redkale/util/Utility.java index 78839b63d..6585b88d9 100644 --- a/src/main/java/org/redkale/util/Utility.java +++ b/src/main/java/org/redkale/util/Utility.java @@ -1271,6 +1271,62 @@ public final class Utility { return news; } + /** + * 将一个或多个新元素添加到数组结尾 + * + * @param array 原数组 + * @param objs 待追加数据 + * + * @return 新数组 + */ + public static String[] append(final String[] array, final String... objs) { + if (array == null || array.length == 0) { + return objs; + } + if (objs == null || objs.length == 0) { + return array; + } + final String[] news = new String[array.length + objs.length]; + System.arraycopy(array, 0, news, 0, array.length); + System.arraycopy(objs, 0, news, array.length, objs.length); + return news; + } + + /** + * 将一个或多个新元素添加到数组结尾 + * + * @param one 单个对象 + * @param objs 待追加数据 + * + * @return 新数组 + */ + public static String[] append(final String one, final String... objs) { + if (one == null) { + return objs; + } + final String[] news = new String[1 + objs.length]; + news[0] = one; + System.arraycopy(objs, 0, news, 1, objs.length); + return news; + } + + /** + * 将一个或多个新元素添加到数组结尾 + * + * @param one 单个对象 + * @param two 单个对象 + * @param objs 待追加数据 + * + * @return 新数组 + */ + public static String[] append(final String one, String two, final String... objs) { + final String[] news = new String[2 + objs.length]; + news[0] = one; + news[1] = two; + System.arraycopy(objs, 0, news, 2, objs.length); + return news; + } + /** * 将一个或多个新元素添加到数组结尾 * @@ -1293,6 +1349,43 @@ public final class Utility { return news; } + /** + * 将一个或多个新元素添加到数组结尾 + * + * @param 泛型 + * @param one 单个对象 + * @param objs 待追加数据 + * + * @return 新数组 + */ + public static T[] append(final T one, final T... objs) { + if (one == null) { + return objs; + } + final T[] news = (T[]) Creator.newArray(one.getClass().getComponentType(), 1 + objs.length); + news[0] = one; + System.arraycopy(objs, 0, news, 1, objs.length); + return news; + } + + /** + * 将一个或多个新元素添加到数组结尾 + * + * @param 泛型 + * @param one 单个对象 + * @param two 单个对象 + * @param objs 待追加数据 + * + * @return 新数组 + */ + public static T[] append(final T one, T two, final T... objs) { + final T[] news = (T[]) Creator.newArray(one.getClass().getComponentType(), 2 + objs.length); + news[0] = one; + news[1] = two; + System.arraycopy(objs, 0, news, 2, objs.length); + return news; + } + /** * 将一个或多个新元素添加到数组结尾 *