walk.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package idx
  2. import (
  3. "io"
  4. "github.com/chrislusf/seaweedfs/weed/glog"
  5. "github.com/chrislusf/seaweedfs/weed/storage/types"
  6. "github.com/chrislusf/seaweedfs/weed/util"
  7. )
  8. // walks through the index file, calls fn function with each key, offset, size
  9. // stops with the error returned by the fn function
  10. func WalkIndexFile(r io.ReaderAt, fn func(key types.NeedleId, offset types.Offset, size uint32) error) error {
  11. var readerOffset int64
  12. bytes := make([]byte, types.NeedleMapEntrySize*RowsToRead)
  13. count, e := r.ReadAt(bytes, readerOffset)
  14. if count == 0 && e == io.EOF {
  15. return nil
  16. }
  17. glog.V(3).Infof("readerOffset %d count %d err: %v", readerOffset, count, e)
  18. readerOffset += int64(count)
  19. var (
  20. key types.NeedleId
  21. offset types.Offset
  22. size uint32
  23. i int
  24. )
  25. for count > 0 && e == nil || e == io.EOF {
  26. for i = 0; i+types.NeedleMapEntrySize <= count; i += types.NeedleMapEntrySize {
  27. key, offset, size = IdxFileEntry(bytes[i : i+types.NeedleMapEntrySize])
  28. if e = fn(key, offset, size); e != nil {
  29. return e
  30. }
  31. }
  32. if e == io.EOF {
  33. return nil
  34. }
  35. count, e = r.ReadAt(bytes, readerOffset)
  36. glog.V(3).Infof("readerOffset %d count %d err: %v", readerOffset, count, e)
  37. readerOffset += int64(count)
  38. }
  39. return e
  40. }
  41. func IdxFileEntry(bytes []byte) (key types.NeedleId, offset types.Offset, size uint32) {
  42. key = types.BytesToNeedleId(bytes[:types.NeedleIdSize])
  43. offset = types.BytesToOffset(bytes[types.NeedleIdSize : types.NeedleIdSize+types.OffsetSize])
  44. size = util.BytesToUint32(bytes[types.NeedleIdSize+types.OffsetSize : types.NeedleIdSize+types.OffsetSize+types.SizeSize])
  45. return
  46. }
  47. const (
  48. RowsToRead = 1024
  49. )