From a24b81018338cf415a423ca8949205b4580fe179 Mon Sep 17 00:00:00 2001 From: LamGC Date: Sat, 5 Sep 2020 11:28:40 +0800 Subject: [PATCH] =?UTF-8?q?[Change]=20CacheStore-api=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=20CacheKey=20=E4=BB=A5=E6=9B=BF=E4=BB=A3=20String=20=E4=BD=9C?= =?UTF-8?q?=E4=B8=BA=20key=20=E5=8F=82=E6=95=B0=E7=B1=BB=E5=9E=8B;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [Add] CacheKey 增加用于代表缓存项键的对象(可被缓存具体实现根据存储需要调整最终 key 的格式, 例如 Redis 的分隔符问题); [Change] CacheStore, CollectionCacheStore, ListCacheStore, MapCacheStore, SingleCacheStore 适配更改; --- .../net/lamgc/cgj/bot/cache/CacheKey.java | 86 +++++++++++++++++++ .../net/lamgc/cgj/bot/cache/CacheStore.java | 8 +- .../cgj/bot/cache/CollectionCacheStore.java | 16 ++-- .../lamgc/cgj/bot/cache/ListCacheStore.java | 12 +-- .../lamgc/cgj/bot/cache/MapCacheStore.java | 24 +++--- .../lamgc/cgj/bot/cache/SingleCacheStore.java | 8 +- 6 files changed, 120 insertions(+), 34 deletions(-) create mode 100644 ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CacheKey.java diff --git a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CacheKey.java b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CacheKey.java new file mode 100644 index 0000000..a4c06a6 --- /dev/null +++ b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CacheKey.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2020 LamGC + * + * ContentGrabbingJi is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * ContentGrabbingJi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package net.lamgc.cgj.bot.cache; + +import java.util.Arrays; +import java.util.Objects; + +/** + * 缓存键. + * 可根据不同缓存实现的需要调整名称. + * @author LamGC + */ +public final class CacheKey { + + public final static String DEFAULT_SEPARATOR = "."; + + private final String[] key; + + /** + * 创建一个缓存键名. + * @param first 组成键名的第一个部分. + * @param keyStrings 键名的其余组成部分. + * @throws NullPointerException 当 keyStrings 为 null 时抛出. + */ + public CacheKey(String first, String... keyStrings) { + Objects.requireNonNull(first); + Objects.requireNonNull(keyStrings); + this.key = new String[keyStrings.length + 1]; + this.key[0] = first; + System.arraycopy(keyStrings, 0, this.key, 1, keyStrings.length); + } + + /** + * 获取组成 Key 的字符串数组. + * @return 返回用于组成 Key 的字符串数组. + */ + public String[] getKeyArray() { + return key; + } + + /** + * 使用指定分隔符组成完整 Key. + * @param separator 分隔符. + * @return 返回组装后的完整 Key. + */ + public String join(String separator) { + return String.join(separator, key); + } + + @Override + public String toString() { + return join(DEFAULT_SEPARATOR); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + CacheKey cacheKey = (CacheKey) o; + return Arrays.equals(key, cacheKey.key); + } + + @Override + public int hashCode() { + return Arrays.hashCode(key); + } +} diff --git a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CacheStore.java b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CacheStore.java index bdb2520..d68c5cb 100644 --- a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CacheStore.java +++ b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CacheStore.java @@ -36,7 +36,7 @@ public interface CacheStore { * @return 如果设置成功, 返回 true, 如果设置失败, 或缓存项不存在, 返回 false. * @throws NullPointerException 当 key 为 null 时抛出. */ - boolean setTimeToLive(String key, long ttl); + boolean setTimeToLive(CacheKey key, long ttl); /** * 查询指定缓存项的 TTL. @@ -44,7 +44,7 @@ public interface CacheStore { * @return 如果缓存项存在且已设置 TTL, 则返回当前剩余 TTL, 如果缓存项不存在或未设置 TTL, 返回 -1. * @throws NullPointerException 当 key 为 null 时抛出. */ - long getTimeToLive(String key); + long getTimeToLive(CacheKey key); /** * 获取当前缓存项数量. @@ -70,7 +70,7 @@ public interface CacheStore { * @return 如果存在, 返回 true, 如果不存在或失效, 返回 false. * @throws NullPointerException 当 key 为 null 时抛出. */ - boolean exists(String key); + boolean exists(CacheKey key); /** * 删除指定缓存. @@ -78,7 +78,7 @@ public interface CacheStore { * @return 如果存在并删除成功, 返回 true. * @throws NullPointerException 当 key 为 null 时抛出. */ - boolean remove(String key); + boolean remove(CacheKey key); // 文档没有硬性要求"Set 中不能存在失效缓存项"的原因是因为: 即便确保了当时获取到的 Set 没有失效缓存项, // 但是如果在获取后立刻出现失效缓存项了呢? 这个情况下依然不能保证没有失效的缓存项, 故不在文档中做出该硬性要求. diff --git a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CollectionCacheStore.java b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CollectionCacheStore.java index 1be4353..ba2714f 100644 --- a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CollectionCacheStore.java +++ b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/CollectionCacheStore.java @@ -34,7 +34,7 @@ public interface CollectionCacheStore> extends CacheS * @return 如果成功返回 true. * @throws NullPointerException 当 key 或 element 为 null 时抛出; 本方法不允许存储 null 值, 因为 null 代表"没有/不存在". */ - boolean addElement(String key, E element); + boolean addElement(CacheKey key, E element); /** * 为缓存项添加一组元素. @@ -44,7 +44,7 @@ public interface CollectionCacheStore> extends CacheS * @return 如果成功添加, 返回 true, 如果无法添加(例如缓存项 List/Set 长度限制), 返回 false. * @throws NullPointerException 当 key 或 value 为 null 时抛出; 本方法不允许存储 null 值, 因为 null 代表"没有/不存在". */ - boolean addElements(String key, Collection elements); + boolean addElements(CacheKey key, Collection elements); /** * 检查指定元素是否包含在指定缓存项中. @@ -53,7 +53,7 @@ public interface CollectionCacheStore> extends CacheS * @return 如果存在, 返回 true, 如果元素不存在, 或缓存项不存在, 返回 false. * @throws NullPointerException 当 key 或 element 为 null 时抛出; 本方法不允许存储 null 值, 因为 null 代表"没有/不存在". */ - boolean containsElement(String key, E element); + boolean containsElement(CacheKey key, E element); /** * 检查指定缓存项是否为空. @@ -61,7 +61,7 @@ public interface CollectionCacheStore> extends CacheS * @return 如果缓存项无元素, 返回 true, 等效于 {@code elementsLength(key) == 0} * @throws NullPointerException 当 key 为 null 时抛出. */ - boolean isEmpty(String key); + boolean isEmpty(CacheKey key); /** * 获取指定缓存项中的元素数量. @@ -69,7 +69,7 @@ public interface CollectionCacheStore> extends CacheS * @return 返回指定缓存项中的元素数量, 如果缓存项不存在, 返回 -1. * @throws NullPointerException 当 key 为 null 时抛出. */ - int elementsLength(String key); + int elementsLength(CacheKey key); /** * 清空集合中的所有元素. @@ -77,16 +77,16 @@ public interface CollectionCacheStore> extends CacheS * @return 操作成功返回 true. * @throws NullPointerException 当 key 为 null 时抛出. */ - boolean clearCollection(String key); + boolean clearCollection(CacheKey key); /** * 删除缓存项中指定的元素. - *

该方法与 {@link CacheStore#remove(String)} 不同, 该方法仅删除缓存项中的指定元素, 即使删除后缓存项中没有元素, 也不会删除缓存项. + *

该方法与 {@link CacheStore#remove(CacheKey)} 不同, 该方法仅删除缓存项中的指定元素, 即使删除后缓存项中没有元素, 也不会删除缓存项. * @param key 待操作的缓存项键名. * @param element 欲删除的元素. * @return 如果元素存在且删除成功, 返回 true. * @throws NullPointerException 当 key 为 null 时抛出. */ - boolean removeElement(String key, E element); + boolean removeElement(CacheKey key, E element); } diff --git a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/ListCacheStore.java b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/ListCacheStore.java index 74989e2..c5797d6 100644 --- a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/ListCacheStore.java +++ b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/ListCacheStore.java @@ -35,7 +35,7 @@ public interface ListCacheStore extends CollectionCacheStore> { * 如果缓存项不存在, 或索引超出范围(超出长度或低于 0)等导致获取失败, 返回 null. * @throws NullPointerException 当 key 为 null 时抛出. */ - E getElement(String key, int index); + E getElement(CacheKey key, int index); /** * 根据返回获取部分元素. @@ -52,28 +52,28 @@ public interface ListCacheStore extends CollectionCacheStore> { * 但需要注意的是: 获取异常不包括在上述范围, 因此如果在获取中出现错误导致获取失败, 应以失败返回 null. * @throws NullPointerException 当 key 为 null 时抛出. */ - List getElementsByRange(String key, int index, int length); + List getElementsByRange(CacheKey key, int index, int length); /** * 删除指定索引的元素. * - *

该方法与 {@link CacheStore#remove(String)} 不同, 该方法仅删除缓存项中的指定元素, 即使删除后缓存项中没有元素, 也不会删除缓存项. + *

该方法与 {@link CacheStore#remove(CacheKey)} 不同, 该方法仅删除缓存项中的指定元素, 即使删除后缓存项中没有元素, 也不会删除缓存项. * @param key 待操作的缓存项键名. * @param index 欲删除元素的索引, 从 0 开始. * @return 如果元素存在且删除成功, 返回 true. * @throws NullPointerException 当 key 为 null 时抛出. */ - boolean removeElement(String key, int index); + boolean removeElement(CacheKey key, int index); /** * 删除缓存项中指定的元素. *

当 List 存在多个该元素时, 删除第一个匹配到的元素. - *

该方法与 {@link CacheStore#remove(String)} 不同, 该方法仅删除缓存项中的指定元素, 即使删除后缓存项中没有元素, 也不会删除缓存项. + *

该方法与 {@link CacheStore#remove(CacheKey)} 不同, 该方法仅删除缓存项中的指定元素, 即使删除后缓存项中没有元素, 也不会删除缓存项. * @param key 待操作的缓存项键名. * @param element 欲删除的元素. * @return 如果元素存在且删除成功, 返回 true. * @throws NullPointerException 当 key 为 null 时抛出. */ @Override - boolean removeElement(String key, E element); + boolean removeElement(CacheKey key, E element); } diff --git a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/MapCacheStore.java b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/MapCacheStore.java index 5ed5043..fd2b54a 100644 --- a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/MapCacheStore.java +++ b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/MapCacheStore.java @@ -32,7 +32,7 @@ public interface MapCacheStore extends CacheStore> { * @return 返回 Map 字段数量, 如果缓存项不存在或获取失败, 返回 -1. * @throws NullPointerException 当 key 为 null 时抛出. */ - int mapSize(String key); + int mapSize(CacheKey key); /** * 获取 Map 字段集合. @@ -40,7 +40,7 @@ public interface MapCacheStore extends CacheStore> { * @return 返回 Map 字段集合, 如果缓存项不存在, 返回 null. * @throws NullPointerException 当 key 为 null 时抛出. */ - Set mapFieldSet(String key); + Set mapFieldSet(CacheKey key); /** * 获取 Map 字段值集合. @@ -48,7 +48,7 @@ public interface MapCacheStore extends CacheStore> { * @return 返回 Map 字段值集合, 如果缓存项不存在, 返回 null. * @throws NullPointerException 当 key 为 null 时抛出. */ - Set mapValueSet(String key); + Set mapValueSet(CacheKey key); /** * 将指定的值与此映射中的指定字段关联. @@ -58,7 +58,7 @@ public interface MapCacheStore extends CacheStore> { * @return 如果成功返回 true. * @throws NullPointerException 当 key/field/value 为 null 时抛出, 缓存存储容器不允许出现 null 值. */ - boolean put(String key, String field, V value); + boolean put(CacheKey key, String field, V value); /** * 添加一组字段. @@ -67,19 +67,19 @@ public interface MapCacheStore extends CacheStore> { * @return 如果成功返回 true. * @throws NullPointerException 当 key/map 为 null 时抛出, 缓存存储容器不允许出现 null 值. */ - boolean putAll(String key, Map map); + boolean putAll(CacheKey key, Map map); /** * 如果字段不存在, 则会将指定的值与此映射中的指定字段关联. * - *

该方法与 {@link #put(String, String, Object)} 类似, 但如果字段存在, 将不会执行任何操作并以失败返回. + *

该方法与 {@link #put(CacheKey, String, Object)} 类似, 但如果字段存在, 将不会执行任何操作并以失败返回. * @param key Map 缓存项的键名. * @param field 字段名. * @param value 字段值. * @return 如果字段不存在且设置成功, 返回 true, 否则返回 false. * @throws NullPointerException 当 key/field/value 为 null 时抛出, 缓存存储容器不允许出现 null 值. */ - boolean putIfNotExist(String key, String field, V value); + boolean putIfNotExist(CacheKey key, String field, V value); /** * 获取指定字段的字段值. @@ -88,7 +88,7 @@ public interface MapCacheStore extends CacheStore> { * @return 如果 Map 缓存项存在且字段存在, 返回字段的对应值. * @throws NullPointerException 当 key/field 为 null 时抛出. */ - V get(String key, String field); + V get(CacheKey key, String field); /** * 删除 Map 中的指定字段. @@ -97,7 +97,7 @@ public interface MapCacheStore extends CacheStore> { * @return 如果 Map 缓存项存在, 字段存在并且删除成功, 返回 true. * @throws NullPointerException 当 key/field 为 null 时抛出. */ - boolean removeField(String key, String field); + boolean removeField(CacheKey key, String field); /** * 检查 Map 中是否有指定字段. @@ -106,7 +106,7 @@ public interface MapCacheStore extends CacheStore> { * @return 如果 Map 缓存项存在且字段存在, 返回 true. * @throws NullPointerException 当 key/field 为 null 时抛出. */ - boolean containsField(String key, String field); + boolean containsField(CacheKey key, String field); /** * 检查 Map 是否为空(没有任何字段). @@ -116,7 +116,7 @@ public interface MapCacheStore extends CacheStore> { * @return 如果 Map 缓存项存在且为空, 返回 true. * @throws NullPointerException 当 key 为 null 时抛出. */ - boolean mapIsEmpty(String key); + boolean mapIsEmpty(CacheKey key); /** * 清空 Map 中的所有字段(并不会删除 Map 缓存项). @@ -124,6 +124,6 @@ public interface MapCacheStore extends CacheStore> { * @return 如果存在且清空成功, 返回 true. * @throws NullPointerException 当 key 为 null 时抛出. */ - boolean clearMap(String key); + boolean clearMap(CacheKey key); } diff --git a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/SingleCacheStore.java b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/SingleCacheStore.java index 30f13eb..bf19f73 100644 --- a/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/SingleCacheStore.java +++ b/ContentGrabbingJi-CacheStore-api/src/main/java/net/lamgc/cgj/bot/cache/SingleCacheStore.java @@ -34,17 +34,17 @@ public interface SingleCacheStore extends CacheStore { * @return 如果成功返回 true. * @throws NullPointerException 当 key 或 value 为 null 时抛出; 本方法不允许存储 null 值, 因为 null 代表"没有/不存在". */ - boolean set(String key, V value); + boolean set(CacheKey key, V value); /** * 设置指定键为指定值. - *

该方法与 {@link #set(String, Object)} 类似, 但如果该 key 已经存在缓存, 则不执行 set 操作并返回 false. + *

该方法与 {@link #set(CacheKey, Object)} 类似, 但如果该 key 已经存在缓存, 则不执行 set 操作并返回 false. * @param key 缓存项键名. * @param value 缓存值. * @return 如果成功返回 true, 当 key 已存在, 或设置失败时返回 false. * @throws NullPointerException 当 key 或 value 为 null 时抛出; 本方法不允许存储 null 值, 因为 null 代表"没有/不存在". */ - boolean setIfNotExist(String key, V value); + boolean setIfNotExist(CacheKey key, V value); /** * 获取缓存项值. @@ -52,6 +52,6 @@ public interface SingleCacheStore extends CacheStore { * @return 如果缓存项存在, 返回缓存项的值, 否则返回 null. * @throws NullPointerException 当 key 为 null 时抛出. */ - V get(String key); + V get(CacheKey key); }