新闻详情

新闻详情

首页 / 资讯中心 / 详情

gsd-core 学习库去重索引优化:批量导入 O(N+K) 的工程实践(306)

发布时间:2026/9/25 2:26:55来源:尧图网络
gsd-core 学习库去重索引优化:批量导入 O(N+K) 的工程实践(306)
【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载导读本篇围绕 gsd-core 中fix-306-learnings-dedupe-index变更记录展开讲解全局学习库Learnings Store的内容哈希去重机制以及 #306 修复如何将批量导入场景下的去重从每次写入都全库扫描的 O(K×N) 优化为一次构建索引、后续 O(1) 命中的 O(NK)。读完本文你将理解 dedupeIndex 的设计动机、底层实现、复杂度推导与回归测试保障并能在自己的批量写入场景中复用同样的先建索引、再批量写入模式。一、背景全局学习库与内容哈希去重gsd-core 维护一个跨项目的全局知识库默认存放在~/.gsd/knowledge/每条 learning 以独立 JSON 文件存储文件命名形如{id}.json。存储记录的结构定义在 src/learnings.ctsinterface LearningRecord { id: string; source_project: string; date: string; context: string; learning: string; tags: string[]; content_hash: string; }去重的核心是content_hash其计算方式位于 src/learnings.ctsfunction contentHash(learning: string, sourceProject: string): string { return crypto.createHash(sha256) .update(learning \n sourceProject) .digest(hex); }两点关键语义哈希输入 learning 文本 source_project因此相同文本、不同项目会产生不同哈希各自独立成条只有相同文本且相同项目才会被判重。测试用例 tests/learnings.test.cjs 明确验证了这一点——同一文本写入project-a与project-b会创建两条独立记录。写入结果通过created: boolean区分WriteResult携带{ id, created, content_hash }调用方可以据此统计新建了几条、跳过了几条。二、问题每次写入都全库扫描的 O(K×N)在 #306 修复之前learningsWrite的单条写入路径legacy path会在每次写入时扫描整个 store 目录逐个读取已有 JSON 文件比对哈希见 src/learnings.cts// Check for duplicate by scanning existing files (single-write path, unchanged) const files fs.readdirSync(dir).filter(f f.endsWith(.json)); for (const file of files) { const existing readLearningFile(path.join(dir, file)); if (existing existing.content_hash hash) { return { id: existing.id, created: false, content_hash: hash }; } }单条写入时这个代价可以接受但批量导入learningsCopyFromProject会逐条调用learningsWrite设 store 中已有 N 条记录本次要导入 K 条每条写入都执行一次 O(N) 的全目录readdirSync 逐文件解析比对整体复杂度为O(K×N)。当知识库积累到成千上万条、而一次导入又有几十上百条时磁盘扫描和 JSON 解析的开销会被平方级放大。三、#306 修复方案一次构建 dedupeIndex写入期 O(1) 命中修复思路非常直观把查重索引从每次写入时重建提前到批量导入开始时一次性构建后续每条写入直接用内存中的Map查哈希。3.1 写入接口增加可选索引learningsWrite的WriteOpts新增了dedupeIndex?: Mapstring, string字段src/learnings.cts键为content_hash值为已存在的idinterface WriteOpts { storeDir?: string; dedupeIndex?: Mapstring, string; }写入时的命中逻辑src/learnings.cts// #306: In bulk-import paths, callers may supply a pre-built dedupeIndex // (Mapcontent_hash, id) to avoid the per-write O(N) store scan. if (opts opts.dedupeIndex) { const dedupeIndex opts.dedupeIndex; if (dedupeIndex.has(hash)) { return { id: dedupeIndex.get(hash) as string, created: false, content_hash: hash }; } const id generateId(); const record: LearningRecord { ... }; platformWriteSync(path.join(dir, ${id}.json), JSON.stringify(record, null, 2)); dedupeIndex.set(hash, id); return { id, created: true, content_hash: hash }; }值得注意的是新建记录写入成功后会同步把新哈希写回索引dedupeIndex.set(hash, id)。这一细节保证了同一批内互相重复的内容也能被后续条目命中而不必等到下次全库扫描。3.2 批量导入时只构建一次索引learningsCopyFromProject在循环导入前先对 store 目录做一次全量扫描构建索引src/learnings.cts// #306: Build the content_hash - id dedupe index once before the loop so // that learningsWrite does not re-scan the entire store on every call — // O(K*N) - O(NK). const dir getStoreDir(opts); ensureStoreDir(dir); const dedupeIndex new Mapstring, string(); for (const file of fs.readdirSync(dir).filter(f f.endsWith(.json))) { const existing readLearningFile(path.join(dir, file)); // First-seen-wins, matching the legacy scan paths first-match return so the // dedupe-hit id is identical on both paths even if the store already holds // duplicate content_hashes. (#306) if (existing existing.content_hash !dedupeIndex.has(existing.content_hash)) { dedupeIndex.set(existing.content_hash, existing.id); } }这里有两个精心设计的语义细节First-seen-wins即使历史数据中已存在重复哈希也以第一次遇到的id为准与 legacy 扫描路径的首个匹配即返回保持一致保证两条路径返回的 dedupe 命中id完全相同。坏文件容忍readLearningFile对无法解析的 JSON 文件只打印警告并返回null索引构建和写入都不会因脏数据崩溃对应测试 tests/learnings.test.cjs。3.3 复杂度对比阶段修复前修复后索引/扫描每次写入 O(N)批量开始前一次性 O(N)K 条写入K × O(N) O(K×N)K × O(1)Map 命中总复杂度O(K×N)O(NK)四、回归测试扫描次数与导入条数解耦针对 #306测试文件 tests/learnings.test.cjs 增加了专门的dedupe scaling (#306)测试分组核心手段是用t.mock.method(fs, readdirSync)精确计数 store 目录的扫描次数test(store directory scan count is independent of imported item count, (t) { // K2 与 K6 两组导入分别统计 readdirSync 调用次数 // BEFORE the fix: count scales 1:1 with K (one scan per learningsWrite call). // AFTER the fix: count is constant (one index-build scan per learningsCopyFromProject call). assert.strictEqual(c1, c6, store directory scan count must be independent of imported item count (#306)); });该断言验证导入 2 条与导入 6 条时store 目录的扫描次数完全相等——只有一次索引构建扫描不再随导入量线性增长。这正是修复前后行为差异的直接量化。与此同时测试还固化了去重语义不被破坏store 中已有重复内容 → 跳过tests/learnings.test.cjs预置一条与 LEARNINGS.md 首节完全一致的记录后导入 3 节期望created: 2, skipped: 1store 最终恰好 3 条。同一文件内两个相同小节 → 只建一条tests/learnings.test.cjs两条完全相同的##小节导入后created: 1, skipped: 1——这验证了写入成功即回写索引的批内去重路径。五、完整链路从 extract-learnings 工作流到全局库批量导入dedupeIndex 的优化场景正是批量导入而批量导入的上游是extract-learnings 工作流/gsd:extract-learnings N读取已完成阶段的产物*-PLAN.md、*-SUMMARY.md为必需*-VERIFICATION.md、*-UAT.md、STATE.md可选提取四类知识decisions、lessons、patterns、surprises完整流程定义在 gsd-core/workflows/extract-learnings.md 与命令入口 commands/gsd/extract-learnings.md。产物写入{PHASE_DIR}/{PADDED_PHASE}-LEARNINGS.md采用##分类 ###条目的 Markdown 结构带 YAML frontmatter 记录 counts 与 missing_artifacts。learningsCopyFromProject解析该 Markdown先按##切分分类再对每个分类按###切分为独立条目——每条###项单独成为一条 learning分类被聚合为一条巨型记录会破坏 store 的相关性注入上限learnings.max_inject见 tests/learnings.test.cjs。每条的 tags 由分类标签 标题关键词自动生成src/learnings.cts。解析出的每条记录经由带dedupeIndex的learningsWrite批量写入全局库并在返回结果中汇总{ total, created, skipped }。此外docs/features/extract-learnings.md 说明当配置features.global_learnings: true时阶段完成会自动对刚完成的阶段执行提取并拷贝到全局库门控关闭默认时提取保持手动。无论自动还是手动去重都发生在全局库写入环节即 #306 优化的位置。六、实践要点与边界storeDir 可覆盖所有写入/读取接口均支持{ storeDir }覆盖默认的~/.gsd/knowledge/测试也利用该能力在临时目录中隔离验证tests/learnings.test.cjs。去重粒度是项目内哈希包含source_project跨项目相同文本不会互相去重——这是设计预期不是缺陷。坏 JSON 文件不阻塞索引构建与写入都会跳过无法解析的文件并输出警告保证历史脏数据不阻断导入。批内去重依赖索引回写只有写入成功即dedupeIndex.set这一实现细节才能让同批重复内容被正确跳过自行实现类似批量导入时不要遗漏这一环。清理能力配套learningsPrune支持按90d格式的保留期清理过期条目src/learnings.cts配合去重共同维持全局库的规模与质量。参考路径变更记录.changeset/archived/fix-306-learnings-dedupe-index.md核心实现src/learnings.cts回归测试tests/learnings.test.cjs提取工作流gsd-core/workflows/extract-learnings.md命令入口commands/gsd/extract-learnings.md功能说明docs/features/extract-learnings.md赞分享【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载相关推荐Polar 前端优化实践用 Map 索引替代重复 find 查找将 O(n²) 降为 O(n)Polar 前端优化实践用 Map 索引替代重复 find 查找将 O n² 降为 O n 本篇技术指南来自 Polar 仓库内置的 Vercel Reac后端前端金融科技gsd-core 命令参数投影单次索引优化parseNamedArgs 从 O(flags×argv) 到 O(argvflags) 的演进实录gsd core 命令参数投影单次索引优化parseNamedArgs 从 O flags×argv 到 O argvflags 的演进实录 导读 本文以gsd-core roadmap annotate-dependencies 性能优化用 Map 索引将计划查找从 O(lines×plans) 降为 O(linesplans)gsd core roadmap annotate dependencies 性能优化用 Map 索引将计划查找从 O lines×plans 降为 O li上一篇【亲测免费】 PojavLauncher_iOS 项目安装与使用教程下一篇Cleanse框架深度解析从基础绑定到高级组件设计的终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Spring Boot酒店客房管理系统:源码+论文打造完整毕设 2026/9/25 3:45:36

Spring Boot酒店客房管理系统:源码+论文打造完整毕设

简介:酒店客房管理系统毕业设计资料,包含完整源码与论文,面向Java Web课程设计或毕设开发人员,同时也适合需要搭建酒店管理场景的初学者。系统覆盖客房信息管理、客房清扫管理、用户入住管理、会员管理、收藏客房等核心业务&#…

阅读更多 →
GEO全场景智能生态:全栈隐私计算与绿色低碳规模化落地实践 2026/9/25 3:45:35

GEO全场景智能生态:全栈隐私计算与绿色低碳规模化落地实践

GEO这个缩写,去年在圈内还属于小范围讨论的概念,今年已经高频出现在各类招标书和企业战略PPT里。从热搜词的密集程度就能感受到风向的变化:GEO优化、GEO服务商、GEO投毒攻击、GEO数据结构、GEO招标项目……说明大量企业已经越过“要不要做GEO…

阅读更多 →
SpringBoot+Vue校园竞赛管理系统:从需求建模到答辩演示全解析 2026/9/25 3:45:23

SpringBoot+Vue校园竞赛管理系统:从需求建模到答辩演示全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
STM32F107+LAN8720A以太网调试指南:从CubeMX到LWIP完整流程 2026/9/25 3:45:23

STM32F107+LAN8720A以太网调试指南:从CubeMX到LWIP完整流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
jetson-inference 目标检测数据集采集与训练指南:使用 camera-capture 制作 Pascal VOC 数据集 2026/9/25 3:45:17

jetson-inference 目标检测数据集采集与训练指南:使用 camera-capture 制作 Pascal VOC 数据集

人工智能计算机视觉深度学习微调 【免费下载链接】jetson-inference Hello AI World guide to deploying deep-learning inference networks and deep vision primitives with TensorRT and NVIDIA Jetson. 项目地址: https://gitcode.com/gh_mirrors/je/jetson-inf…

阅读更多 →
Plannotator 安装验证机制详解:SHA256 校验与 SLSA 构建溯源的落地实践 2026/9/25 3:45:11

Plannotator 安装验证机制详解:SHA256 校验与 SLSA 构建溯源的落地实践

【免费下载链接】plannotator Annotate and review coding agent plans and code diffs visually, share with your team, send feedback to agents with one click. 项目地址: https://gitcode.com/gh_mirrors/pl/plannotator 点击查看 免费下载 本篇围绕 Plannot…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉