walk.go 1.6 KB

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