package index import ( "TsDB2/DB/core/index/btree" "TsDB2/DB/core/page" "encoding/binary" ) // BTreeHandler — B+ 树二级索引 (IndexTypeBTree) // 叶子条目: [key(keyLen) + PKID(8B BE)] type BTreeHandler struct{} func init() { Compose.RegisterHandler(page.IndexTypeBTree, &BTreeHandler{}) // 向后兼容:旧数据库中 IndexTypeStr=3 的索引统一用 BTreeHandler 处理 Compose.RegisterHandler(page.IndexTypeStr, &BTreeHandler{}) } func (h *BTreeHandler) Insert(handle page.HandleDb, entryPage *uint32, indexKey []byte, pkID uint64, rowData []byte, keyLen int) (uint32, error) { entry := make([]byte, keyLen+8) copy(entry[:keyLen], indexKey) binary.BigEndian.PutUint64(entry[keyLen:], pkID) rootPID := *entryPage newRoot, err := btree.SBTInsert(rootPID, entry, handle) if err != nil { return 0, err } *entryPage = newRoot return newRoot, nil } func (h *BTreeHandler) Search(handle page.HandleDb, entryPage uint32, indexKey []byte, keyLen int) ([]byte, bool) { rootPID := entryPage if rootPID == 0 { return nil, false } pkID, found := btree.SBTSearch(rootPID, indexKey[:keyLen], handle) if !found { return nil, false } pkBuf := make([]byte, 8) binary.BigEndian.PutUint64(pkBuf, pkID) return pkBuf, true } func (h *BTreeHandler) Delete(handle page.HandleDb, entryPage *uint32, indexKey []byte, keyLen int) error { rootPID := *entryPage if rootPID == 0 { return page.ErrNotFound } // 先搜索获取 pkID,再按 key+pkID 精确删除(正确处理重复 key) pkID, found := btree.SBTSearch(rootPID, indexKey[:keyLen], handle) if !found { return page.ErrNotFound } newRoot, err := btree.SBTDeleteWithPKID(rootPID, indexKey[:keyLen], pkID, handle) if err != nil { return err } *entryPage = newRoot return nil } func (h *BTreeHandler) Update(handle page.HandleDb, entryPage *uint32, oldKey []byte, rowData []byte, pkID uint64, keyLen int) error { // 二级索引 Update: 先删旧条目, 再插新条目 if err := h.Delete(handle, entryPage, oldKey, keyLen); err != nil { return err } _, err := h.Insert(handle, entryPage, oldKey, pkID, rowData, keyLen) return err } // SearchAll 查找相同 key 下的所有 pkID func (h *BTreeHandler) SearchAll(handle page.HandleDb, entryPage uint32, indexKey []byte, keyLen int) ([]uint64, bool) { rootPID := entryPage if rootPID == 0 { return nil, false } return btree.SBTSearchAll(rootPID, indexKey[:keyLen], handle) } func (h *BTreeHandler) GetDataPageIDs(handle page.HandleDb, entryPage uint32) []uint32 { // 二级索引没有 DataPage, 返回空 return nil } func (h *BTreeHandler) ReadDataPageRows(handle page.HandleDb, dpID uint32) [][]byte { // 二级索引没有 DataPage return nil } func (h *BTreeHandler) RangeScan(handle page.HandleDb, entryPage uint32, startKey, endKey []byte, startInclusive, endInclusive bool, reverse bool, callback func(row []byte) bool) error { return btree.SBTRangeScan(entryPage, handle, startKey, endKey, startInclusive, endInclusive, reverse, callback) }