You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.7 KiB

3 years ago
3 years ago
3 years ago
  1. package idx
  2. import (
  3. "io"
  4. "github.com/chrislusf/seaweedfs/weed/glog"
  5. "github.com/chrislusf/seaweedfs/weed/storage/types"
  6. )
  7. // walks through the index file, calls fn function with each key, offset, size
  8. // stops with the error returned by the fn function
  9. func WalkIndexFile(r io.ReaderAt, fn func(key types.NeedleId, offset types.Offset, size types.Size) error) error {
  10. var readerOffset int64
  11. bytes := make([]byte, types.NeedleMapEntrySize*RowsToRead)
  12. count, e := r.ReadAt(bytes, readerOffset)
  13. if count == 0 && e == io.EOF {
  14. return nil
  15. }
  16. glog.V(3).Infof("readerOffset %d count %d err: %v", readerOffset, count, e)
  17. readerOffset += int64(count)
  18. var (
  19. key types.NeedleId
  20. offset types.Offset
  21. size types.Size
  22. i int
  23. )
  24. for count > 0 && e == nil || e == io.EOF {
  25. for i = 0; i+types.NeedleMapEntrySize <= count; i += types.NeedleMapEntrySize {
  26. key, offset, size = IdxFileEntry(bytes[i : i+types.NeedleMapEntrySize])
  27. if e = fn(key, offset, size); e != nil {
  28. return e
  29. }
  30. }
  31. if e == io.EOF {
  32. return nil
  33. }
  34. count, e = r.ReadAt(bytes, readerOffset)
  35. glog.V(3).Infof("readerOffset %d count %d err: %v", readerOffset, count, e)
  36. readerOffset += int64(count)
  37. }
  38. return e
  39. }
  40. //copied from WalkIndexFile, just init readerOffset from milestone
  41. func WalkIndexFileIncrement(r io.ReaderAt, milestone uint64, fn func(key types.NeedleId, offset types.Offset, size types.Size) error) error {
  42. var readerOffset = int64(milestone * types.NeedleMapEntrySize)
  43. bytes := make([]byte, types.NeedleMapEntrySize*RowsToRead)
  44. count, e := r.ReadAt(bytes, readerOffset)
  45. if count == 0 && e == io.EOF {
  46. return nil
  47. }
  48. glog.V(3).Infof("readerOffset %d count %d err: %v", readerOffset, count, e)
  49. readerOffset += int64(count)
  50. var (
  51. key types.NeedleId
  52. offset types.Offset
  53. size types.Size
  54. i int
  55. )
  56. for count > 0 && e == nil || e == io.EOF {
  57. for i = 0; i+types.NeedleMapEntrySize <= count; i += types.NeedleMapEntrySize {
  58. key, offset, size = IdxFileEntry(bytes[i : i+types.NeedleMapEntrySize])
  59. if e = fn(key, offset, size); e != nil {
  60. return e
  61. }
  62. }
  63. if e == io.EOF {
  64. return nil
  65. }
  66. count, e = r.ReadAt(bytes, readerOffset)
  67. glog.V(3).Infof("readerOffset %d count %d err: %v", readerOffset, count, e)
  68. readerOffset += int64(count)
  69. }
  70. return e
  71. }
  72. func IdxFileEntry(bytes []byte) (key types.NeedleId, offset types.Offset, size types.Size) {
  73. key = types.BytesToNeedleId(bytes[:types.NeedleIdSize])
  74. offset = types.BytesToOffset(bytes[types.NeedleIdSize : types.NeedleIdSize+types.OffsetSize])
  75. size = types.BytesToSize(bytes[types.NeedleIdSize+types.OffsetSize : types.NeedleIdSize+types.OffsetSize+types.SizeSize])
  76. return
  77. }
  78. const (
  79. RowsToRead = 1024
  80. )