utils.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package util
  2. // IsHighBitSet 判断最高位是否为 1(表/字段是否被删除)
  3. func IsHighBitSet(b byte) bool {
  4. return b&0x80 != 0
  5. }
  6. // SetHighBit 将最高位置 1(标记删除)
  7. func SetHighBit(b byte) byte {
  8. return b | 0x80
  9. }
  10. // BytesToString 字节数组转字符串(固定长度表名专用)
  11. func BytesToString(b []byte) string {
  12. for i := range b {
  13. if b[i] == 0 {
  14. return string(b[:i])
  15. }
  16. }
  17. return string(b)
  18. }
  19. // 工具函数:int64比较
  20. func CompareInt64(a, b int64) int {
  21. if a < b {
  22. return -1
  23. } else if a > b {
  24. return 1
  25. }
  26. return 0
  27. }
  28. // 工具函数:uint64比较
  29. func CompareUint64(a, b uint64) int {
  30. if a < b {
  31. return -1
  32. } else if a > b {
  33. return 1
  34. }
  35. return 0
  36. }
  37. // BinarySearch
  38. // 通用二分查找:适用于所有有序 []byte 连续存储的索引条目
  39. // entryLen: 单个条目长度
  40. // compare: 比较函数:mid条目数据 vs 目标key
  41. // 返回:找到的位置pos, 是否找到found
  42. func BinarySearch(
  43. entries []byte,
  44. entryLen int,
  45. key []byte,
  46. compare func(a, b []byte) int,
  47. ) (pos uint32, found bool) {
  48. n := len(entries) / entryLen
  49. if n == 0 {
  50. return 0, false
  51. }
  52. left := 0
  53. right := n - 1
  54. pos = uint32(n)
  55. for left <= right {
  56. mid := (left + right) >> 1
  57. start := mid * entryLen
  58. midEntry := entries[start : start+entryLen]
  59. cmp := compare(midEntry, key) // <--- 现在两个参数
  60. switch {
  61. case cmp == 0:
  62. return uint32(mid), true
  63. case cmp < 0:
  64. left = mid + 1
  65. default:
  66. right = mid - 1
  67. pos = uint32(mid)
  68. }
  69. }
  70. return pos, false
  71. }