chain_util.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package index
  2. import (
  3. "TsDB2/DB/core/page"
  4. "unsafe"
  5. )
  6. // insertEntrySorted 在索引页中有序插入一个条目
  7. func insertEntrySorted(buf []byte, hdr *page.IndexHead, entry []byte) {
  8. entryLen := int(hdr.EntryLen)
  9. count := int(hdr.Count)
  10. entries := buf[page.IndexHeadSize : page.IndexHeadSize+count*entryLen]
  11. pos := count
  12. left, right := 0, count-1
  13. for left <= right {
  14. mid := (left + right) / 2
  15. midEntry := entries[mid*entryLen : (mid+1)*entryLen]
  16. cmp := compareEntryKeys(midEntry, entry, entryLen-4)
  17. if cmp >= 0 {
  18. pos = mid
  19. right = mid - 1
  20. } else {
  21. left = mid + 1
  22. }
  23. }
  24. allEntries := buf[page.IndexHeadSize : page.IndexHeadSize+(count+1)*entryLen]
  25. copy(allEntries[(pos+1)*entryLen:(count+1)*entryLen], allEntries[pos*entryLen:count*entryLen])
  26. copy(allEntries[pos*entryLen:(pos+1)*entryLen], entry)
  27. hdr.Count++
  28. hdr.Hdr.UseSize += uint32(entryLen)
  29. }
  30. func compareEntryKeys(a, b []byte, keyLen int) int {
  31. for i := 0; i < keyLen; i++ {
  32. if a[i] < b[i] {
  33. return -1
  34. }
  35. if a[i] > b[i] {
  36. return 1
  37. }
  38. }
  39. return 0
  40. }
  41. // writeToNewIndexPage 创建新的索引页,写入一个条目,并链接到索引链
  42. func writeToNewIndexPage(handle page.HandleDb, entryPage *uint32, entry []byte, lastIdxPageID uint32) error {
  43. newIdxPID := handle.NewPage()
  44. newBuf := make([]byte, page.IndexPageSize)
  45. newHdr := (*page.IndexHead)(unsafe.Pointer(&newBuf[0]))
  46. newHdr.Hdr.Type = page.IndexDataIndex
  47. newHdr.Hdr.PageID = newIdxPID
  48. newHdr.Hdr.UseSize = uint32(page.IndexHeadSize) + uint32(len(entry))
  49. newHdr.EntryLen = uint16(len(entry))
  50. newHdr.IsLeaf = 1
  51. newHdr.Count = 1
  52. copy(newBuf[page.IndexHeadSize:], entry)
  53. if err := handle.SavePage(newIdxPID, newBuf); err != nil {
  54. return err
  55. }
  56. if *entryPage == 0 {
  57. *entryPage = newIdxPID
  58. } else if lastIdxPageID != 0 {
  59. linkBuf := make([]byte, page.IndexPageSize)
  60. if err := handle.ReadPage(lastIdxPageID, linkBuf); err == nil {
  61. linkHdr := (*page.IndexHead)(unsafe.Pointer(&linkBuf[0]))
  62. linkHdr.Hdr.NextPage = newIdxPID
  63. if err := handle.SavePage(lastIdxPageID, linkBuf); err != nil {
  64. return err
  65. }
  66. }
  67. }
  68. return nil
  69. }