compose_handler.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package index
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "git.ycl.pub/yl32940/TsDB2/DB/core/index/btree"
  6. "git.ycl.pub/yl32940/TsDB2/DB/core/page"
  7. )
  8. func init() {
  9. Compose.RegisterHandler(page.IndexTypeCompose, &ComposeChainHandler{})
  10. }
  11. // ======================== IndexHandler: 复合二级索引处理器 ========================
  12. // ComposeChainHandler — 复合二级索引 (page.IndexTypeCompose)
  13. // 底层即 B+ 树二级索引 (与 BTreeHandler 共享 btree.SBT* 实现):
  14. // Insert/Search/Delete/RangeScan 全部委托 SBT, 条目格式 [key(keyLen) + PKID(8B BE)],
  15. // keyLen = 各分量按真实宽度定长拼接的总长 (分量不限 8 字节, 与 BTree 复合键一致)。
  16. type ComposeChainHandler struct{}
  17. func (h *ComposeChainHandler) Insert(handle page.HandleDb, entryPage *uint32, indexKey []byte, pkID uint64, rowData []byte, keyLen int) (uint32, error) {
  18. entry := make([]byte, keyLen+8)
  19. copy(entry[:keyLen], indexKey)
  20. binary.BigEndian.PutUint64(entry[keyLen:], pkID)
  21. rootPID := *entryPage
  22. newRoot, err := btree.SBTInsert(rootPID, entry, handle)
  23. if err != nil {
  24. return 0, err
  25. }
  26. *entryPage = newRoot
  27. return newRoot, nil
  28. }
  29. func (h *ComposeChainHandler) Search(handle page.HandleDb, entryPage uint32, indexKey []byte, keyLen int, resolve RowResolver) ([]byte, bool) {
  30. rootPID := entryPage
  31. if rootPID == 0 {
  32. return nil, false
  33. }
  34. pkID, found := btree.SBTSearch(rootPID, indexKey[:keyLen], handle)
  35. if !found {
  36. return nil, false
  37. }
  38. if resolve != nil {
  39. if row, ok := resolve(pkID); ok {
  40. return row, true
  41. }
  42. return nil, false
  43. }
  44. pkBuf := make([]byte, 8)
  45. binary.BigEndian.PutUint64(pkBuf, pkID)
  46. return pkBuf, true
  47. }
  48. func (h *ComposeChainHandler) Delete(handle page.HandleDb, entryPage *uint32, indexKey []byte, pkID uint64, keyLen int) error {
  49. rootPID := *entryPage
  50. if rootPID == 0 {
  51. return page.ErrNotFound
  52. }
  53. if pkID == 0 {
  54. pk, found := btree.SBTSearch(rootPID, indexKey[:keyLen], handle)
  55. if !found {
  56. return page.ErrNotFound
  57. }
  58. pkID = pk
  59. }
  60. newRoot, err := btree.SBTDeleteWithPKID(rootPID, indexKey[:keyLen], pkID, handle)
  61. if err != nil {
  62. return err
  63. }
  64. *entryPage = newRoot
  65. return nil
  66. }
  67. func (h *ComposeChainHandler) Update(handle page.HandleDb, entryPage *uint32, oldKey, newKey, rowData []byte, pkID uint64, keyLen int) error {
  68. if bytes.Equal(oldKey, newKey) {
  69. return nil
  70. }
  71. if oldKey != nil {
  72. if err := h.Delete(handle, entryPage, oldKey, pkID, len(oldKey)); err != nil && err != page.ErrNotFound {
  73. return err
  74. }
  75. }
  76. _, err := h.Insert(handle, entryPage, newKey, pkID, rowData, len(newKey))
  77. return err
  78. }
  79. func (h *ComposeChainHandler) IsRowStore() bool { return false }
  80. func (h *ComposeChainHandler) ResolveRow(handle page.HandleDb, entryPage uint32, pkID uint64, cache *[]DPRange) ([]byte, bool) {
  81. return nil, false
  82. }
  83. func (h *ComposeChainHandler) GetDataPageIDs(handle page.HandleDb, entryPage uint32) []uint32 {
  84. return nil
  85. }
  86. func (h *ComposeChainHandler) ReadDataPageRows(handle page.HandleDb, dpID uint32) [][]byte {
  87. return nil
  88. }
  89. func (h *ComposeChainHandler) RangeScan(handle page.HandleDb, entryPage uint32,
  90. startKey, endKey []byte, startInclusive, endInclusive bool, reverse bool,
  91. callback func(row []byte) bool) error {
  92. return btree.SBTRangeScan(entryPage, handle, startKey, endKey, startInclusive, endInclusive, reverse, callback)
  93. }