btree_handler.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package index
  2. import (
  3. "TsDB2/DB/core/index/btree"
  4. "TsDB2/DB/core/page"
  5. "encoding/binary"
  6. )
  7. // BTreeHandler — B+ 树二级索引 (IndexTypeBTree)
  8. // 叶子条目: [key(keyLen) + PKID(8B BE)]
  9. type BTreeHandler struct{}
  10. func init() {
  11. Compose.RegisterHandler(page.IndexTypeBTree, &BTreeHandler{})
  12. // 向后兼容:旧数据库中 IndexTypeStr=3 的索引统一用 BTreeHandler 处理
  13. Compose.RegisterHandler(page.IndexTypeStr, &BTreeHandler{})
  14. }
  15. func (h *BTreeHandler) Insert(handle page.HandleDb, entryPage *uint32, indexKey []byte, pkID uint64, rowData []byte, keyLen int) (uint32, error) {
  16. entry := make([]byte, keyLen+8)
  17. copy(entry[:keyLen], indexKey)
  18. binary.BigEndian.PutUint64(entry[keyLen:], pkID)
  19. rootPID := *entryPage
  20. newRoot, err := btree.SBTInsert(rootPID, entry, handle)
  21. if err != nil {
  22. return 0, err
  23. }
  24. *entryPage = newRoot
  25. return newRoot, nil
  26. }
  27. func (h *BTreeHandler) Search(handle page.HandleDb, entryPage uint32, indexKey []byte, keyLen int) ([]byte, bool) {
  28. rootPID := entryPage
  29. if rootPID == 0 {
  30. return nil, false
  31. }
  32. pkID, found := btree.SBTSearch(rootPID, indexKey[:keyLen], handle)
  33. if !found {
  34. return nil, false
  35. }
  36. pkBuf := make([]byte, 8)
  37. binary.BigEndian.PutUint64(pkBuf, pkID)
  38. return pkBuf, true
  39. }
  40. func (h *BTreeHandler) Delete(handle page.HandleDb, entryPage *uint32, indexKey []byte, keyLen int) error {
  41. rootPID := *entryPage
  42. if rootPID == 0 {
  43. return page.ErrNotFound
  44. }
  45. // 先搜索获取 pkID,再按 key+pkID 精确删除(正确处理重复 key)
  46. pkID, found := btree.SBTSearch(rootPID, indexKey[:keyLen], handle)
  47. if !found {
  48. return page.ErrNotFound
  49. }
  50. newRoot, err := btree.SBTDeleteWithPKID(rootPID, indexKey[:keyLen], pkID, handle)
  51. if err != nil {
  52. return err
  53. }
  54. *entryPage = newRoot
  55. return nil
  56. }
  57. func (h *BTreeHandler) Update(handle page.HandleDb, entryPage *uint32, oldKey []byte, rowData []byte, pkID uint64, keyLen int) error {
  58. // 二级索引 Update: 先删旧条目, 再插新条目
  59. if err := h.Delete(handle, entryPage, oldKey, keyLen); err != nil {
  60. return err
  61. }
  62. _, err := h.Insert(handle, entryPage, oldKey, pkID, rowData, keyLen)
  63. return err
  64. }
  65. // SearchAll 查找相同 key 下的所有 pkID
  66. func (h *BTreeHandler) SearchAll(handle page.HandleDb, entryPage uint32, indexKey []byte, keyLen int) ([]uint64, bool) {
  67. rootPID := entryPage
  68. if rootPID == 0 {
  69. return nil, false
  70. }
  71. return btree.SBTSearchAll(rootPID, indexKey[:keyLen], handle)
  72. }
  73. func (h *BTreeHandler) GetDataPageIDs(handle page.HandleDb, entryPage uint32) []uint32 {
  74. // 二级索引没有 DataPage, 返回空
  75. return nil
  76. }
  77. func (h *BTreeHandler) ReadDataPageRows(handle page.HandleDb, dpID uint32) [][]byte {
  78. // 二级索引没有 DataPage
  79. return nil
  80. }
  81. func (h *BTreeHandler) RangeScan(handle page.HandleDb, entryPage uint32,
  82. startKey, endKey []byte, startInclusive, endInclusive bool, reverse bool,
  83. callback func(row []byte) bool) error {
  84. return btree.SBTRangeScan(entryPage, handle, startKey, endKey, startInclusive, endInclusive, reverse, callback)
  85. }