primary_handler.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. package index
  2. import (
  3. "TsDB2/DB/core/index/btree"
  4. "TsDB2/DB/core/index/datapage"
  5. "TsDB2/DB/core/page"
  6. "encoding/binary"
  7. )
  8. // PrimaryHandler — 主键 B+ 树索引 (IndexTypePrimary)
  9. // 存储: storeRow = [pkID(8B LE) + rowData]
  10. type PrimaryHandler struct{}
  11. func init() {
  12. Compose.RegisterHandler(page.IndexTypePrimary, &PrimaryHandler{})
  13. }
  14. func (h *PrimaryHandler) Insert(handle page.HandleDb, entryPage *uint32, indexKey []byte, pkID uint64, rowData []byte, keyLen int) (uint32, error) {
  15. pkBuf := make([]byte, 8)
  16. binary.BigEndian.PutUint64(pkBuf, pkID)
  17. storeRowData := append(pkBuf, rowData...)
  18. // 主键 B+ 树始终以 pkID(8B BE) 为 key, 与 Search/Delete/Update 保持一致
  19. return h.insertPrebuilt(handle, entryPage, pkBuf, storeRowData)
  20. }
  21. // InsertPrebuilt 插入已构建好的 storeRowData (避免重复分配)
  22. // storeRowData = [pkID(8B BE) + rowData]
  23. func (h *PrimaryHandler) InsertPrebuilt(handle page.HandleDb, entryPage *uint32, indexKey []byte, storeRowData []byte) (uint32, error) {
  24. return h.insertPrebuilt(handle, entryPage, indexKey, storeRowData)
  25. }
  26. // BuildStoreRow 用复用缓冲区构建 storeRowData = [pkID(8B BE) + rowData]
  27. // 返回的切片与 buf 共享底层数组, 调用方需立即使用
  28. func (h *PrimaryHandler) BuildStoreRow(buf []byte, pkID uint64, rowData []byte) []byte {
  29. binary.BigEndian.PutUint64(buf[:8], pkID)
  30. copy(buf[8:], rowData)
  31. return buf[:8+len(rowData)]
  32. }
  33. func (h *PrimaryHandler) insertPrebuilt(handle page.HandleDb, entryPage *uint32, indexKey []byte, storeRowData []byte) (uint32, error) {
  34. rootPID := *entryPage
  35. rowSize := uint32(len(storeRowData)) + 4 // 4B len prefix + row data
  36. // 尝试复用 DataPage: 只在路由目标叶子内查找
  37. if rootPID != 0 {
  38. if dpID, found := btree.FindLastLeafDP(handle, rootPID, rowSize, indexKey); found {
  39. dp, err := datapage.Load(handle, dpID)
  40. if err == nil {
  41. dp.AppendRow(storeRowData)
  42. dp.Save()
  43. newRoot, _, dup, err := btree.BTreePKInsert(rootPID, indexKey, dpID, handle)
  44. if err != nil {
  45. return 0, err
  46. }
  47. if !dup {
  48. *entryPage = newRoot
  49. }
  50. return newRoot, nil
  51. }
  52. }
  53. }
  54. // 无可用空间或树为空: 创建新 DataPage
  55. dp := datapage.New(handle)
  56. dp.AppendRow(storeRowData)
  57. dp.Save()
  58. newRoot, _, _, err := btree.BTreePKInsert(rootPID, indexKey, dp.PageID(), handle)
  59. if err != nil {
  60. return 0, err
  61. }
  62. *entryPage = newRoot
  63. return newRoot, nil
  64. }
  65. func (h *PrimaryHandler) Search(handle page.HandleDb, entryPage uint32, indexKey []byte, keyLen int) ([]byte, bool) {
  66. rootPID := entryPage
  67. if rootPID == 0 {
  68. return nil, false
  69. }
  70. dpID, found := btree.BTreePKSearch(rootPID, indexKey, handle)
  71. if !found {
  72. return nil, false
  73. }
  74. dp, err := datapage.Load(handle, dpID)
  75. if err != nil {
  76. return nil, false
  77. }
  78. return dp.FindRowByIndexKey(indexKey, 9) // skip pkID(8B) + schemaVer(1B)
  79. }
  80. func (h *PrimaryHandler) SearchByPK(handle page.HandleDb, entryPage uint32, pkID uint64) ([]byte, bool) {
  81. rootPID := entryPage
  82. if rootPID == 0 {
  83. return nil, false
  84. }
  85. pkKeyBE := make([]byte, 8)
  86. binary.BigEndian.PutUint64(pkKeyBE, pkID)
  87. dpID, found := btree.BTreePKSearch(rootPID, pkKeyBE, handle)
  88. if found {
  89. dp, err := datapage.Load(handle, dpID)
  90. if err == nil {
  91. if rowData, ok := dp.FindRowByPK(pkKeyBE); ok {
  92. return rowData, true
  93. }
  94. }
  95. }
  96. // 路由失败或未找到, 扫描所有叶子
  97. return btree.ScanAllLeavesForPK(rootPID, handle, pkKeyBE)
  98. }
  99. func (h *PrimaryHandler) Delete(handle page.HandleDb, entryPage *uint32, indexKey []byte, keyLen int) error {
  100. rootPID := *entryPage
  101. if rootPID == 0 {
  102. return page.ErrNotFound
  103. }
  104. dpID, found := btree.BTreePKSearch(rootPID, indexKey, handle)
  105. if found {
  106. dp, err := datapage.Load(handle, dpID)
  107. if err == nil {
  108. deleted := false
  109. if dp.DeleteByIndexKey(indexKey, 8) {
  110. deleted = true
  111. } else if dp.DeleteByPK(indexKey) {
  112. deleted = true
  113. }
  114. if deleted {
  115. if dp.AllDeleted() {
  116. newRoot, _, err := btree.BTreePKDelete(rootPID, indexKey, handle)
  117. if err != nil {
  118. return err
  119. }
  120. if newRoot != rootPID {
  121. *entryPage = newRoot
  122. }
  123. if handle.FreePage != nil {
  124. handle.FreePage(dpID)
  125. }
  126. } else {
  127. dp.Save()
  128. }
  129. return nil
  130. }
  131. }
  132. }
  133. // 索引键路由失败, 扫描所有叶子
  134. return btree.ScanAndDelete(rootPID, handle, indexKey, indexKey)
  135. }
  136. func (h *PrimaryHandler) DeleteByPK(handle page.HandleDb, entryPage *uint32, pkID uint64) error {
  137. rootPID := *entryPage
  138. if rootPID == 0 {
  139. return page.ErrNotFound
  140. }
  141. pkKeyBE := make([]byte, 8)
  142. binary.BigEndian.PutUint64(pkKeyBE, pkID)
  143. dpID, found := btree.BTreePKSearch(rootPID, pkKeyBE, handle)
  144. if found {
  145. dp, err := datapage.Load(handle, dpID)
  146. if err == nil {
  147. if dp.DeleteByPK(pkKeyBE) {
  148. if dp.AllDeleted() {
  149. newRoot, _, err := btree.BTreePKDelete(rootPID, pkKeyBE, handle)
  150. if err != nil {
  151. return err
  152. }
  153. if newRoot != rootPID {
  154. *entryPage = newRoot
  155. }
  156. if handle.FreePage != nil {
  157. handle.FreePage(dpID)
  158. }
  159. } else {
  160. dp.Save()
  161. }
  162. return nil
  163. }
  164. }
  165. }
  166. // 路由失败, 扫描所有叶子
  167. return btree.ScanAndDeleteByPK(rootPID, handle, pkKeyBE)
  168. }
  169. func (h *PrimaryHandler) Update(handle page.HandleDb, entryPage *uint32, oldKey []byte, rowData []byte, pkID uint64, keyLen int) error {
  170. rootPID := *entryPage
  171. if rootPID == 0 {
  172. return page.ErrNotFound
  173. }
  174. pkBuf := make([]byte, 8)
  175. binary.BigEndian.PutUint64(pkBuf, pkID)
  176. storeRowData := append(pkBuf, rowData...)
  177. pkKeyBE := make([]byte, 8)
  178. binary.BigEndian.PutUint64(pkKeyBE, pkID)
  179. // 先用 B+ 树路由定位 DataPage
  180. dpID, found := btree.BTreePKSearch(rootPID, pkKeyBE, handle)
  181. if found {
  182. dp, err := datapage.Load(handle, dpID)
  183. if err == nil {
  184. if err := dp.UpdateByPK(pkKeyBE, storeRowData); err == nil {
  185. return nil
  186. }
  187. }
  188. }
  189. // 路由失败, 回退扫描
  190. return btree.ScanAndUpdate(rootPID, handle, pkKeyBE, storeRowData)
  191. }
  192. func (h *PrimaryHandler) GetDataPageIDs(handle page.HandleDb, entryPage uint32) []uint32 {
  193. return btree.GetDataPageIDs(handle, entryPage)
  194. }
  195. func (h *PrimaryHandler) ReadDataPageRows(handle page.HandleDb, dpID uint32) [][]byte {
  196. dp, err := datapage.Load(handle, dpID)
  197. if err != nil {
  198. return nil
  199. }
  200. return dp.GetAllRows()
  201. }
  202. func (h *PrimaryHandler) RangeScan(handle page.HandleDb, entryPage uint32,
  203. startKey, endKey []byte, startInclusive, endInclusive bool, reverse bool,
  204. callback func(row []byte) bool) error {
  205. return btree.BTreePKRangeScan(entryPage, handle, startKey, endKey, startInclusive, endInclusive, reverse, callback)
  206. }