idx_binary_search_test.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package storage
  2. import (
  3. "os"
  4. "testing"
  5. "github.com/seaweedfs/seaweedfs/weed/storage/idx"
  6. "github.com/seaweedfs/seaweedfs/weed/storage/needle"
  7. "github.com/seaweedfs/seaweedfs/weed/storage/super_block"
  8. "github.com/seaweedfs/seaweedfs/weed/storage/types"
  9. "github.com/stretchr/testify/assert"
  10. )
  11. func TestFirstInvalidIndex(t *testing.T) {
  12. dir := t.TempDir()
  13. v, err := NewVolume(dir, dir, "", 1, NeedleMapInMemory, &super_block.ReplicaPlacement{}, &needle.TTL{}, 0, 0, 0)
  14. if err != nil {
  15. t.Fatalf("volume creation: %v", err)
  16. }
  17. type WriteInfo struct {
  18. offset int64
  19. size int32
  20. }
  21. // initialize 20 needles then update first 10 needles
  22. for i := 1; i <= 30; i++ {
  23. n := newRandomNeedle(uint64(i))
  24. n.Flags = 0x08
  25. _, _, _, err := v.writeNeedle2(n, true, false)
  26. if err != nil {
  27. t.Fatalf("write needle %d: %v", i, err)
  28. }
  29. }
  30. b, err := os.ReadFile(v.IndexFileName() + ".idx")
  31. if err != nil {
  32. t.Fatal(err)
  33. }
  34. // base case every record is valid -> nothing is filtered
  35. index, err := idx.FirstInvalidIndex(b, func(key types.NeedleId, offset types.Offset, size types.Size) (bool, error) {
  36. return true, nil
  37. })
  38. if err != nil {
  39. t.Fatalf("failed to complete binary search %v", err)
  40. }
  41. assert.Equal(t, 30, index, "when every record is valid nothing should be filtered from binary search")
  42. index, err = idx.FirstInvalidIndex(b, func(key types.NeedleId, offset types.Offset, size types.Size) (bool, error) {
  43. return false, nil
  44. })
  45. if err != nil {
  46. t.Fatal(err)
  47. }
  48. assert.Equal(t, 0, index, "when every record is invalid everything should be filtered from binary search")
  49. index, err = idx.FirstInvalidIndex(b, func(key types.NeedleId, offset types.Offset, size types.Size) (bool, error) {
  50. return key < 20, nil
  51. })
  52. if err != nil {
  53. t.Fatal(err)
  54. }
  55. // needle key range from 1 to 30 so < 20 means 19 keys are valid and cutoff the bytes at 19 * 16 = 304
  56. assert.Equal(t, 19, index, "when every record is invalid everything should be filtered from binary search")
  57. index, err = idx.FirstInvalidIndex(b, func(key types.NeedleId, offset types.Offset, size types.Size) (bool, error) {
  58. return key <= 1, nil
  59. })
  60. if err != nil {
  61. t.Fatal(err)
  62. }
  63. // needle key range from 1 to 30 so <=1 1 means 1 key is valid and cutoff the bytes at 1 * 16 = 16
  64. assert.Equal(t, 1, index, "when every record is invalid everything should be filtered from binary search")
  65. }