Store 存储体系分析
概述
本文档分析 spring-ai-alibaba-graph-core 模块中的 Store 存储体系,包罗接口计划、实现模式、支持的存储范例和关键计划点。
入口类阐明
Store - 存储接口
Store 是长期内存存储的接口,提供跨会话的长期化存储本领,与 CheckpointSaver(短期状态长期化)差别,Store 专注于长期数据管理。
焦点职责:
- 提供条理化定名空间支持
- 支持结构化数据存储(Map 格式)
- 提供搜刮和过滤功能
- 支持分页查询
- 跨会话数据长期化
关键代码:- public interface Store {
- /**
- * Store an item in the specified namespace with the given key. If an item with the
- * same namespace and key already exists, it will be updated.
- * @param item the item to store
- * @throws IllegalArgumentException if item is null or invalid
- */
- void putItem(StoreItem item);
- /**
- * Retrieve an item from the specified namespace with the given key.
- * @param namespace the hierarchical namespace path
- * @param key the item key
- * @return Optional containing the item if found, empty otherwise
- * @throws IllegalArgumentException if namespace or key is null/invalid
- */
- Optional<StoreItem> getItem(List<String> namespace, String key);
- /**
- * Delete an item from the specified namespace with the given key.
- * @param namespace the hierarchical namespace path
- * @param key the item key
- * @return true if the item was deleted, false if it didn't exist
- * @throws IllegalArgumentException if namespace or key is null/invalid
- */
- boolean deleteItem(List<String> namespace, String key);
- /**
- * Search for items based on the provided search criteria.
- * @param searchRequest the search parameters
- * @return search results with matching items
- * @throws IllegalArgumentException if searchRequest is null
- */
- StoreSearchResult searchItems(StoreSearchRequest searchRequest);
- /**
- * List available namespaces based on the provided criteria.
- * @param namespaceRequest the namespace listing parameters
- * @return list of namespace paths
- * @throws IllegalArgumentException if namespaceRequest is null
- */
- List<String> listNamespaces(NamespaceListRequest namespaceRequest);
- /**
- * Clear all items from the store.
- * <p>
- * <strong>WARNING:</strong> This operation is irreversible and will remove all stored
- * data.
- * </p>
- */
- void clear();
- /**
- * Get the total number of items in the store.
- * @return the number of items stored
- */
- long size();
- /**
- * Check if the store is empty.
- * @return true if the store contains no items, false otherwise
- */
- boolean isEmpty();
- }
复制代码 BaseStore - 抽象基类
BaseStore 为全部 Store 实现提供通用的验证和工具方法,实现了模板方法模式。
焦点职责:
- 提供参数验证方法
- 提供键编码/解码工具
- 提供搜刮匹配逻辑
- 提供排序比力器
关键代码:- public abstract class BaseStore implements Store {
- /**
- * Validates the putItem parameters.
- * @param item the item to validate
- */
- protected void validatePutItem(StoreItem item) {
- if (item == null) {
- throw new IllegalArgumentException("item cannot be null");
- }
- if (item.getNamespace() == null) {
- throw new IllegalArgumentException("namespace cannot be null");
- }
- if (item.getKey() == null || item.getKey().trim().isEmpty()) {
- throw new IllegalArgumentException("key cannot be null or empty");
- }
- }
- /**
- * Validates the getItem parameters.
- * @param namespace namespace
- * @param key key
- */
- protected void validateGetItem(List<String> namespace, String key) {
- if (namespace == null) {
- throw new IllegalArgumentException("namespace cannot be null");
- }
- if (key == null) {
- throw new IllegalArgumentException("key cannot be null");
- }
- if (key.trim().isEmpty()) {
- throw new IllegalArgumentException("key cannot be empty");
- }
- }
- /**
- * Validates the deleteItem parameters.
- * @param namespace namespace
- * @param key key
- */
- protected void validateDeleteItem(List<String> namespace, String key) {
- if (namespace == null) {
- throw new IllegalArgumentException("namespace cannot be null");
- }
- if (key == null) {
- throw new IllegalArgumentException("key cannot be null");
- }
- if (key.trim().isEmpty()) {
- throw new IllegalArgumentException("key cannot be empty");
- }
- }
- /**
- * Validates the searchItems parameters.
- * @param searchRequest search request
- */
- protected void validateSearchItems(StoreSearchRequest searchRequest) {
- if (searchRequest == null) {
- throw new IllegalArgumentException("searchRequest cannot be null");
- }
- }
- /**
- * Validates the listNamespaces parameters.
- * @param namespaceRequest namespace request
- */
- protected void validateListNamespaces(NamespaceListRequest namespaceRequest) {
- if (namespaceRequest == null) {
- throw new IllegalArgumentException("namespaceRequest cannot be null");
- }
- }
- /**
- * Create store key from namespace and key Uses safe encoding to avoid conflicts from
- * special characters.
- * @param namespace namespace
- * @param key key
- * @return store key
- */
- protected String createStoreKey(List<String> namespace, String key) {
- try {
- Map<String, Object> keyData = new HashMap<>();
- keyData.put("namespace", namespace);
- keyData.put("key", key);
- return Base64.getEncoder().encodeToString(new ObjectMapper().writeValueAsBytes(keyData));
- }
- catch (Exception e) {
- throw new RuntimeException("Failed to create store key", e);
- }
- }
- /**
- * Parse store key to namespace and key.
- * @param storeKey store key
- * @return array containing [namespace, key]
- */
- @SuppressWarnings("unchecked")
- protected Object[] parseStoreKey(String storeKey) {
- try {
- byte[] decoded = Base64.getDecoder().decode(storeKey);
- Map<String, Object> keyData = new ObjectMapper().readValue(decoded, Map.class);
- List<String> namespace = (List<String>) keyData.get("namespace");
- String key = (String) keyData.get("key");
- return new Object[] { namespace, key };
- }
- catch (Exception e) {
- throw new RuntimeException("Failed to parse store key: " + storeKey, e);
- }
- }
复制代码 StoreItem - 存储项
StoreItem 体现存储中的单个数据项,包罗定名空间、键、值和时间戳。
关键代码:- public class StoreItem implements Serializable {
- /**
- * The hierarchical namespace path for organizing items. For example: ["users",
- * "user123", "preferences"]
- */
- private List<String> namespace;
- /**
- * The unique key within the namespace.
- */
- private String key;
- /**
- * The item value as a structured Map.
- */
- private Map<String, Object> value;
- /**
- * Timestamp when the item was created (milliseconds since epoch).
- */
- private long createdAt;
- /**
- * Timestamp when the item was last updated (milliseconds since epoch).
- */
- private long updatedAt;
- /**
- * Default constructor for serialization frameworks.
- */
- public StoreItem() {
- }
- /**
- * Constructs a StoreItem with the specified namespace, key, and value. Timestamps are
- * set to the current time.
- * @param namespace the hierarchical namespace path
- * @param key the item key
- * @param value the item value
- */
- public StoreItem(List<String> namespace, String key, Map<String, Object> value) {
- this.namespace = namespace;
- this.key = key;
- this.value = value;
- long now = System.currentTimeMillis();
- this.createdAt = now;
- this.updatedAt = now;
- }
- /**
- * Constructs a StoreItem with full parameters including timestamps.
- * @param namespace the hierarchical namespace path
- * @param key the item key
- * @param value the item value
- * @param createdAt creation timestamp (milliseconds since epoch)
- * @param updatedAt last update timestamp (milliseconds since epoch)
- */
- public StoreItem(List<String> namespace, String key, Map<String, Object> value, long createdAt, long updatedAt) {
- this.namespace = namespace;
- this.key = key;
- this.value = value;
- this.createdAt = createdAt;
- this.updatedAt = updatedAt;
- }
- /**
- * Static factory method to create a StoreItem.
- * @param namespace the hierarchical namespace path
- * @param key the item key
- * @param value the item value
- * @return a new StoreItem instance
- */
- public static StoreItem of(List<String> namespace, String key, Map<String, Object> value) {
- return new StoreItem(namespace, key, value);
- }
复制代码 Store 实现类
MemoryStore - 内存存储
基于 ConcurrentHashMap 的内存实现,实用于测试和开辟情况。
关键代码:- public class MemoryStore extends BaseStore {
- /**
- * Thread-safe storage for store items. Key format: "namespace1/namespace2/key"
- */
- private final Map<String, StoreItem> storage = new ConcurrentHashMap<>();
- /**
- * Read-write lock for thread safety during search operations.
- */
- private final ReadWriteLock lock = new ReentrantReadWriteLock();
- @Override
- public void putItem(StoreItem item) {
- validatePutItem(item);
- lock.writeLock().lock();
- try {
- String storeKey = createStoreKey(item.getNamespace(), item.getKey());
- storage.put(storeKey, item);
- }
- finally {
- lock.writeLock().unlock();
- }
- }
- @Override
- public Optional<StoreItem> getItem(List<String> namespace, String key) {
- validateGetItem(namespace, key);
- lock.readLock().lock();
- try {
- String storeKey = createStoreKey(namespace, key);
- return Optional.ofNullable(storage.get(storeKey));
- }
- finally {
- lock.readLock().unlock();
- }
- }
复制代码 特点:
- 线程安全(利用 ConcurrentHashMap 和 ReadWriteLock)
- 高性能(内存访问)
- 数据不长期化(应用重启后丢失)
FileSystemStore - 文件体系存储
基于文件体系的长期化存储实现。
特点:
- 数据长期化到当地文件体系
- 支持目次结构构造
- 适当单机摆设
DatabaseStore - 数据库存储
基于关系型数据库(MySQL/PostgreSQL)的存储实现。
特点:
RedisStore - Redis 存储
基于 Redis 的存储实现。
特点:
MongoStore - MongoDB 存储
基于 MongoDB 的存储实现。
特点:
关键类关系图
以下 PlantUML 类图展示了 Store 体系的类关系:
这种计划克制了特殊字符辩论,确保键的唯一性。
3. 搜刮和过滤
StoreSearchRequest 支持多种搜刮方式:
- 定名空间过滤:在指定定名空间下搜刮
- 文本查询:在键和值中搜刮文本
- 自界说过滤:基于值的键值对过滤
- 排序:支持多字段排序
- 分页:支持 offset 和 limit
关键代码:- protected boolean matchesSearchCriteria(StoreItem item, StoreSearchRequest searchRequest) {
- // Namespace filter
- List<String> namespaceFilter = searchRequest.getNamespace();
- if (!namespaceFilter.isEmpty() && !startsWithPrefix(item.getNamespace(), namespaceFilter)) {
- return false;
- }
- // Text query filter
- String query = searchRequest.getQuery();
- if (query != null && !query.trim().isEmpty()) {
- String lowerQuery = query.toLowerCase();
- // Search in key
- if (!item.getKey().toLowerCase().contains(lowerQuery)) {
- // Search in value
- String valueStr = item.getValue().toString().toLowerCase();
- if (!valueStr.contains(lowerQuery)) {
- return false;
- }
- }
- }
- // Custom filters
- Map<String, Object> filters = searchRequest.getFilter();
- if (!filters.isEmpty()) {
- Map<String, Object> itemValue = item.getValue();
- for (Map.Entry<String, Object> filter : filters.entrySet()) {
- Object itemVal = itemValue.get(filter.getKey());
- if (!Objects.equals(itemVal, filter.getValue())) {
- return false;
- }
- }
- }
- return true;
- }
复制代码 实现关键点阐明
1. 模板方法模式
BaseStore 实现了模板方法模式:
- 界说通用的验证和工具方法
- 子类实现详细的存储逻辑
- 确保全部实现的划一性
2. 战略模式
差别的 Store 实当代表差别的存储战略:
- MemoryStore:内存战略(快速但不长期)
- FileSystemStore:文件体系战略(长期但单机)
- DatabaseStore:数据库战略(事件支持)
- RedisStore:缓存战略(高性能)
- MongoStore:文档数据库战略(机动)
3. 线程安全
- MemoryStore 利用 ConcurrentHashMap 和 ReadWriteLock 确保线程安全
- 其他实现依靠底层存储的线程安全机制
4. 键编码计划
利用 Base64 编码克制特殊字符题目:
- 支持恣意定名空间和键名
- 确保键的唯一性
- 便于序列化和反序列化
5. 搜刮优化
BaseStore 提供通用的搜刮匹配逻辑:
- 定名空间前缀匹配
- 文本包罗匹配
- 自界说过滤匹配
- 多字段排序支持
总结阐明
焦点计划理念
- 同一接口:Store 接口界说同一的存储操纵,屏蔽底层实现差别
- 条理化构造:通过定名空间支持数据的条理化构造
- 机动查询:支持多种搜刮和过滤方式
- 可扩展性:通过接口和抽象类支持新的存储实现
支持的存储模式
- 内存模式(MemoryStore):适当测试和开辟
- 文件体系模式(FileSystemStore):适当单机摆设
- 数据库模式(DatabaseStore):适当生产情况,支持事件
- 缓存模式(RedisStore):适当高性能场景
- 文档数据库模式(MongoStore):适当非结构化数据
关键上风
- 划一性:全部实现依照类似的接口规范
- 可更换性:差别实现可以无缝更换
- 可扩展性:易于添加新的存储实现
- 范例安全:利用泛型和接口确保范例安全
利用场景
- 长期影象:Agent 的长期影象存储
- 知识库:存储结构化知识
- 用户数据:存储用户偏好和设置
- 会话数据:跨会话的数据长期化
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |