split.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. package btree
  2. // ======================== B+ 树分裂策略参数 ========================
  3. //
  4. // 分裂点过去写死为 "total/2" (对半分)。这里把它抽成可配参数, 并且主键树与
  5. // 二级树**各自独立** —— 两个参数分别声明在对应的索引处理器文件里, 不随索引
  6. // 元数据 (IndexMeta) 传递:
  7. //
  8. // 主键 B+ 树 -> DB/core/index/primary_handler.go (btree.PKSplitCfg)
  9. // 二级 B+ 树 -> DB/core/index/btree_handler.go (btree.SBTSplitCfg)
  10. // SplitConfig 描述一棵 B+ 树的分裂策略。
  11. type SplitConfig struct {
  12. // SplitPercent 分裂时左节点保留的条目百分比 (1~99); <=0 或 >=100 时按 50 处理。
  13. SplitPercent int
  14. // SequentialRight 顺序(右端)追加时, 是否让右节点只保留 1 条。
  15. // 自增/递增键总是插到最右端, 若仍对半分, 每次分裂都要白搬半页 (写放大);
  16. // 置 true 后左节点几乎保留满页, 只有 1 条落到新右节点。
  17. SequentialRight bool
  18. }
  19. var (
  20. // PKSplitCfg 主键 B+ 树分裂策略 (由 primary_handler.go 声明)
  21. PKSplitCfg = SplitConfig{SplitPercent: 50, SequentialRight: true}
  22. // SBTSplitCfg 二级 B+ 树分裂策略 (由 btree_handler.go 声明)
  23. SBTSplitCfg = SplitConfig{SplitPercent: 50, SequentialRight: false}
  24. )
  25. // splitPoint 计算分裂分界下标 mid: 左节点保留 [0,mid), 右节点保留 [mid,total)。
  26. // insertedAtRight 表示本次插入落在节点最右端。
  27. func splitPoint(total int, cfg SplitConfig, insertedAtRight bool) int {
  28. if total <= 1 {
  29. return 1
  30. }
  31. if cfg.SequentialRight && insertedAtRight {
  32. return total - 1
  33. }
  34. p := cfg.SplitPercent
  35. if p <= 0 || p >= 100 {
  36. p = 50
  37. }
  38. mid := total * p / 100
  39. if mid < 1 {
  40. mid = 1
  41. }
  42. if mid > total-1 {
  43. mid = total - 1
  44. }
  45. return mid
  46. }