RogueMap 开发助手
这是什么
RogueMap 是 Java 嵌入式堆外存储引擎(Maven groupId com.yomahub),使用内存映射文件(mmap)保存主要数据,以降低 JVM 堆压力。索引和运行时元数据仍可能占用 JVM 堆。三个发布模块:
roguemap-core— 四种堆外数据结构:RogueMap(键值)、RogueList(双向链表)、RogueSet(集合)、RogueQueue(FIFO 队列);支持持久化、自动检查点、自动扩容,其中事务与 TTL 仅 RogueMap 完整实现roguemap-embedding—UniversalEmbeddingProvider,兼容 OpenAI/v1/embeddings协议,不依赖第三方 HTTP 客户端roguemap-memory— RogueMemory AI 记忆层:HNSW 向量 ANN + BM25 关键词混合检索(RRF 融合),mmap 持久化
本 skill 基于 RogueMap 1.1.7 源码编写,Java 8+。本次源码核验基线为 commit e78b7f9b1825e35910119284d6299aab5265c039;版本或 commit 不匹配时重新核验,不套用本基线的内部行为结论。
行为准则(必须遵守)
- 先做更新自检。本 skill 每次会话首次被触发时,必须先运行
scripts/version-check.sh再处理用户问题;结果按下方「更新自检」一节处理,检查失败则静默继续,不得因该检查中断或拒绝正常回答。 - 先确认版本。本 skill 的事实基线是 1.1.7。用户未说明版本时按 1.1.7 回答并注明版本;用户使用其他版本或询问“最新行为”时必须重新核对源码。
- 先读参考文件。按下方「参考文件路由」读取相关文件后再写代码或作答;涉及数据安全、崩溃恢复或容量规划时同时读取运维与 RogueMemory 参考,禁止只凭速查表下结论。
- 按来源优先级核验:用户提供的本地源码 > 本 skill 的 1.1.7 references > 官方仓库与官方文档。不要使用博客、聚合站或搜索摘要作为 API 依据。需要源码时先用
scripts/source-lookup.sh path探测本地仓库,再用grep、find、show子命令定位;本地没有源码时,必须先征得用户同意才能运行scripts/source-lookup.sh clone。联网时优先用户指定仓库,否则中文优先 Giteehttps://gitee.com/bryan31/RogueMap,英文优先 GitHubhttps://github.com/bryan31/RogueMap。 - 绝不编造 API。reference 未记录的类或方法不得直接用于代码,也不得仅因 reference 未记录就断言它不存在;先在匹配版本源码中确认。1.1.7 的典型错误写法包括:
RogueMap.builder()、RogueMap.Tx、memory.hybridSearch()、putIfAbsent。 - 明确保证边界。区分“线程内原子性”“checkpoint 可恢复性”“OS 可能刷盘”和“断电保证”;没有源码与测试支撑时不得使用“任何情况不丢”“完全线程安全”“零堆内存”等绝对表述。
- 给出可运行答案。Java 完整示例必须包含必要 import、资源关闭和变量作用域;不完整片段要明确标为片段。涉及版本差异、持久化或性能时,回答中注明依据版本和关键限制。
Maven 依赖(1.1.7)
<!-- 核心堆外数据结构 -->
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>roguemap-core</artifactId>
<version>1.1.7</version>
</dependency>
<!-- AI 记忆层(自动传递 roguemap-embedding,无需单独引入) -->
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>roguemap-memory</artifactId>
<version>1.1.7</version>
</dependency>
Kryo 5.6.2 已是 roguemap-core 的 compile 依赖,KryoObjectCodec 开箱即用,无需额外引入。
一分钟上手
// RogueMap:临时模式键值存储
try (RogueMap<String, Long> map = RogueMap.<String, Long>mmap()
.temporary() // 或 .persistent("data/my.db")
.keyCodec(StringCodec.INSTANCE)
.valueCodec(PrimitiveCodecs.LONG)
.build()) {
map.put("alice", 100L);
Long v = map.get("alice");
}
// RogueMemory:AI 记忆混合检索
try (RogueMemory mem = RogueMemory.mmap()
.persistent("data/mem") // 不带扩展名,生成 .mem/.hnsw
.embeddingProvider(new UniversalEmbeddingProvider(apiKey))
.build()) {
String id = mem.add("用户偏好深色模式");
List<MemoryResult> results = mem.search("界面偏好", 5);
}
关键事实速查(最易错点)
| 事实 | 说明 |
|---|---|
| 入口 | RogueMap.mmap() / RogueList.mmap() / RogueSet.mmap() / RogueQueue.mmap() / RogueMemory.mmap(),不是 builder() |
| 必填项 | Map 要 keyCodec + valueCodec;List/Set/Queue 要 elementCodec;模式要 temporary() 或 persistent(path) 二选一 |
| 默认索引 | segmentedIndex(64)(64 段 StampedLock),事务只支持它 |
| TTL | 只有 RogueMap 真正生效;List/Set/Queue 的 defaultTTL() 是 no-op |
| lowHeapIndex | 仅 String 键、codec 必须 StringCodec.INSTANCE(身份比较)、不支持事务、不兼容旧格式文件 |
| compact | core 支持 compact 的结构:返回新实例、旧实例已关闭,且不保留 autoExpand/defaultTTL/autoCheckpoint;RogueMemory:旧实例不自动关闭,按 reference 的安全顺序交接 |
| 遍历 | RogueMap 没有 keySet()/entrySet()/putIfAbsent,用 forEach((k,v)->...)、keys()、values()、iterator() |
| null 值 | PrimitiveCodecs 不支持 null value;StringCodec null 安全 |
| allocateSize 默认 | 全部结构(含 RogueMemory)256MB;不足且未开 autoExpand → 抛 OutOfMemoryError |
| RogueMemory | 无 temporary 模式;persistent(path) 不带扩展名;不配 provider 时 HYBRID 退化为纯 BM25,VECTOR_ONLY 恒返回空 |
| Embedding baseUrl | 只写到 /v1,不要带 /embeddings 后缀;Ollama 的 apiKey 传 "" |
| 单实例限制 | 一个持久化文件同时只能打开一个实例;1.1.7 不用 OS 文件锁强制,调用方必须保证 |
| RogueMemory 恢复边界 | checkpoint/close 才更新文件头恢复上界;之后新增而未 checkpoint 的记录,异常退出后不保证恢复 |
| RogueMemory 堆内存 | 内容与向量在 mmap;HNSW 图、BM25 倒排索引、OrdinalRegistry 和偏移表仍占 JVM 堆,必须实测容量 |
参考文件路由
| 要做什么 | 读这个文件 |
|---|---|
| 写 RogueMap/RogueList/RogueSet/RogueQueue 代码、索引选型、事务、TTL、Codec、批量 API | references/core-api.md |
| 持久化、崩溃恢复、checkpoint/flush/close、autoExpand、compact、监控指标、并发、性能、最佳实践 | references/operations.md |
| RogueMemory 增删改查、混合检索、namespace/metadata 过滤、Embedding、恢复边界、容量与堆内存规划 | references/rogue-memory.md |
| 报错排障、行为异常、版本差异、已知坑、「为什么我的代码不工作」 | references/faq.md |
源码核验工具
scripts/source-lookup.sh 提供本地优先的源码定位和受控克隆:
| 子命令 | 作用 |
|---|---|
path |
输出找到的 RogueMap 本地仓库;找不到时退出码为 2,不会联网 |
clone |
克隆官方 Gitee 仓库并检出本 skill 的源码基线;仅在用户明确同意后运行 |
grep <pattern> |
在源码仓库的 Java 文件中检索并显示行号 |
grepall <pattern> |
在源码仓库的全部文件中检索并显示行号 |
find <name> |
按文件名定位文件 |
show <path> [a-b] |
显示指定文件,可选行号范围 |
环境变量:ROGUEMAP_REPO 可指定本地源码目录,ROGUEMAP_REF 可覆盖默认核验提交,ROGUEMAP_CACHE 可覆盖缓存目录,ROGUEMAP_REMOTE 可覆盖克隆地址。
更新自检
本 skill 被触发时,先运行 scripts/version-check.sh 检查自身是否为最新版本:
| 退出码 | 含义 | 处理方式 |
|---|---|---|
| 0 | 已是最新 | 继续正常工作,无需提示 |
| 2 | 远端有更新 | 告知用户本地与远端版本号,征得同意后执行脚本输出的 npx skills update 命令完成更新 |
| 1 | 检查失败(离线、网络受限等) | 静默跳过,不影响任何正常功能 |
该检查只读取远端 SKILL.md 的 version 字段,不执行远端任何代码。结果按天缓存在 ~/.cache/how2useroguemap/(可用 HOW2USEROGUEMAP_CACHE 覆盖),同一天内重复运行直接回放缓存、不重复联网;HOW2USEROGUEMAP_CHECK_FORCE=1 可强制重新检查。
如需在 agent hook 中挂载本脚本,命令末尾必须追加 || true——部分 hook 体系把退出码 2 解释为「阻断」,与本脚本的「有更新」含义冲突。
常见幻觉对照
| 错误(编造) | 正确 |
|---|---|
RogueMap.<String,Long>builder().path(...) |
RogueMap.<String,Long>mmap().persistent(...) |
new OpenAIEmbeddingProvider(...) |
new UniversalEmbeddingProvider(apiKey)(该旧类已废弃) |
RogueMap.Transaction<K,V> txn = ... |
RogueMapTransaction<K,V> txn = map.beginTransaction() |
map.put(k, v, Duration.ofSeconds(30)) |
map.put(k, v, 30, TimeUnit.SECONDS) |
mem.hybridSearch("q", 5) |
mem.search("q", 5)(HYBRID 是默认 SearchMode) |
.codec(StringCodec.INSTANCE)(List/Set/Queue) |
.elementCodec(StringCodec.INSTANCE) |