refactor: 重划包边界(对外/内部由编译器强制),拆分两个过大文件 - #285
Merged
Merged
Conversation
pkg/utils 只剩 ByteBuilder 一个函数,且只有 cmd/ban-bench 一个使用方(3 处调用)。 为此维持一个包、一个导入路径与一层公开 API,不划算。函数下沉到唯一使用它的文件里, 改名 concatBytes 以说明其行为(原名 ByteBuilder 更像类型而非函数)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
pkg/ 下同时放着两类性质相反的包:proto 与 predicate 出现在 client SDK 的公开签名里 (client.Scan 的参数就是 predicate.Predicate),是对外契约;credit、admission、metrics 则是纯内部实现。混在同一层级下,"哪些算对外 API" 只能靠口头约定。 pkg/proto → proto 对外:协议常量与 SCAN 编解码 pkg/predicate → predicate 对外:SCAN 谓词,出现在 SDK 签名中 pkg/credit → internal/credit pkg/admission → internal/admission pkg/metrics → internal/metrics 移走后 pkg/ 只剩一层无意义的包装,一并删除。 现在这条边界由编译器强制,而非文档约定。已实测:模块外导入 internal/metrics 报 "use of internal package not allowed";导入 client / proto / predicate 正常编译并可 调用 Scan。README 中「对外契约」一节同步更新。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
单文件 910 行里挤着七件事:磁盘布局常量、常驻句柄与缓存、块索引/布隆的加载、点查与全量 读、flush 落盘、compaction 合并、元信息增删查。改为四个文件,各自单一职责: sstable.go 96 行 类型与共用定义(布局常量、blockIndex、SSTable 本身) sstable_read.go 355 行 读路径:常驻句柄、块索引与布隆缓存、点查、全量读 sstable_write.go 312 行 写路径:flush 落盘、写尾、compaction 合并 sstable_meta.go 176 行 元信息:启动扫描重建、增删查、不可变快照发布 纯文件重组,无逻辑改动:拆分前后均为 25 个函数,去掉空行与注释后 697 → 716 行, 多出的 19 行是四份文件各自的 package 与 import 头。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
单文件 845 行涵盖了 Raft 的全部子系统。改为五个文件: raft.go 213 行 类型、构造、生命周期与只读访问器 raft_election.go 192 行 选举计时、发起投票、统计选票、成为 leader raft_replication.go 235 行 追加日志、心跳与复制、推进 commitIndex 并 apply raft_snapshot.go 187 行 快照触发与生成、日志条目序列化编解码 raft_persist.go 49 行 任期/投票状态与日志落盘、重启读回 纯文件重组,无逻辑改动:拆分前后均为 30 个函数。原有的 raft_wal.go(WAL 实现)与 rpc.go(RPC 传输)不动。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🐯 BanGD 数据库内核评审整体风险:🟢 低 变更总结:这是一个纯结构重组 PR,不触碰任何运行逻辑/磁盘格式/数据不变量。它做了三件事:(1) 重划包边界——把
架构问题(共 2 项)
本次评审消耗 token:共 154734 tokens(输入 143802,输出 2228,缓存命中 8704,缓存写入 0)|维度 [concurrency, memory, lock, storage, performance]|对抗式复核 3 票/条,过滤疑似误报 0 条 |
This was referenced Aug 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
结构层面的整理。先用
go list量了一遍依赖图——无环,方向干净:config是叶子,client(SDK) 只依赖proto+predicate,service作为编排层依赖其余。问题不在依赖方向,在包的划分。① 对外契约与内部实现混在同一层
pkg/下同时放着两类性质相反的包:proto、predicate出现在 SDK 的公开签名里(client.Scan的参数就是predicate.Predicate)——是对外契约credit、admission、metrics是纯内部实现混在一起,「哪些算对外 API」只能靠口头约定。重划后由编译器强制:
移走后
pkg/只剩一层无意义包装,一并删除。已实测两个方向:在模块外建临时 module 导入
internal/metrics→use of internal package not allowed;导入client/proto/predicate并实际调用Scan→ 正常编译。②
pkg/utils:23 行、1 个函数、1 个使用方只剩
ByteBuilder,只有cmd/ban-bench用(3 处)。为它维持一个包、一条导入路径和一层公开 API 不划算。下沉到唯一使用它的文件,并改名concatBytes(原名更像类型而非函数)。③ 拆分两个过大文件
storage/sstable.gosstable.go96 /_read.go355 /_write.go312 /_meta.go176raft/raft.goraft.go213 /_election.go192 /_replication.go235 /_snapshot.go187 /_persist.go49纯文件重组,无逻辑改动,并做了完整性核对:sstable 拆分前后均 25 个函数(去空行注释 697→716 行,多出的 19 行是四份文件头);raft 拆分前后均 30 个函数。
一处我查证后没有动的地方
service/delivery/governance → service/delivery看着像「子包反向依赖父包」,但deliverer.go:13写明这是刻意设计:deliverer 收接口(sender)故不 import governance,由 governance 反向 import delivery,正是为了避免 import 环。设计过的,不动。一处发现但未修的既有缺陷
全量
go test -race ./...时TestShardKV_RealSharding_ForwardedReads偶发失败(单独跑本分支与 main 各 3/3 通过,故与本 PR 无关)。根因是断言与被测设计相抵触:它要求每个副本都必须被用到,而 P2C 是延迟感知的——只有 2 个副本时它必然两个都看再选快的那个。整套并行跑造成 CPU 争抢、延迟不对称时,把流量集中到快副本正是 P2C 的设计行为,不是 bug。
修它需要重写断言(改成「制造延迟差、断言流量随之迁移」这类有向验证,而非统计分布),与本次结构重构无关,故未顺手削弱它。
验证
go build ./...(含-tags pprof)、go vet ./...、gofmt全绿;go test -race ./...连跑 2 次通过;scripts/bench.sh实跑通过。🤖 Generated with Claude Code