chain_util.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. _ = handle.SavePage(newIdxPID, newBuf)
  54. if *entryPage == 0 {
  55. *entryPage = newIdxPID
  56. } else if lastIdxPageID != 0 {
  57. linkBuf := make([]byte, page.IndexPageSize)
  58. if err := handle.ReadPage(lastIdxPageID, linkBuf); err == nil {
  59. linkHdr := (*page.IndexHead)(unsafe.Pointer(&linkBuf[0]))
  60. linkHdr.Hdr.NextPage = newIdxPID
  61. _ = handle.SavePage(lastIdxPageID, linkBuf)
  62. }
  63. }
  64. return nil
  65. }