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.

94 lines
2.4 KiB

  1. package main
  2. import (
  3. "flag"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "github.com/chrislusf/seaweedfs/weed/glog"
  8. "github.com/chrislusf/seaweedfs/weed/storage"
  9. "github.com/chrislusf/seaweedfs/weed/storage/backend"
  10. "github.com/chrislusf/seaweedfs/weed/storage/needle"
  11. )
  12. var (
  13. volumePath = flag.String("dir", "/tmp", "data directory to store files")
  14. volumeCollection = flag.String("collection", "", "the volume collection name")
  15. volumeId = flag.Int("volumeId", -1, "a volume id. The volume should already exist in the dir. The volume index file should not exist.")
  16. )
  17. func Checksum(n *needle.Needle) string {
  18. return fmt.Sprintf("%s%x", n.Id, n.Cookie)
  19. }
  20. type VolumeFileScanner4SeeDat struct {
  21. version needle.Version
  22. block storage.SuperBlock
  23. dir string
  24. hashes map[string]bool
  25. dat *os.File
  26. datBackend backend.DataStorageBackend
  27. }
  28. func (scanner *VolumeFileScanner4SeeDat) VisitSuperBlock(superBlock storage.SuperBlock) error {
  29. scanner.version = superBlock.Version()
  30. scanner.block = superBlock
  31. return nil
  32. }
  33. func (scanner *VolumeFileScanner4SeeDat) ReadNeedleBody() bool {
  34. return true
  35. }
  36. func (scanner *VolumeFileScanner4SeeDat) VisitNeedle(n *needle.Needle, offset int64, needleHeader, needleBody []byte) error {
  37. if scanner.datBackend == nil {
  38. newFileName := filepath.Join(*volumePath, "dat_fixed")
  39. newDatFile, err := os.Create(newFileName)
  40. if err != nil {
  41. glog.Fatalf("Write New Volume Data %v", err)
  42. }
  43. scanner.datBackend = backend.NewDiskFile(newDatFile)
  44. scanner.datBackend.WriteAt(scanner.block.Bytes(), 0)
  45. }
  46. checksum := Checksum(n)
  47. if scanner.hashes[checksum] {
  48. glog.V(0).Infof("duplicate checksum:%s fid:%d,%s%x @ offset:%d", checksum, *volumeId, n.Id, n.Cookie, offset)
  49. return nil
  50. }
  51. scanner.hashes[checksum] = true
  52. _, s, _, e := n.Append(scanner.datBackend, scanner.version)
  53. fmt.Printf("size %d error %v\n", s, e)
  54. return nil
  55. }
  56. func main() {
  57. flag.Parse()
  58. vid := needle.VolumeId(*volumeId)
  59. outpath, _ := filepath.Abs(filepath.Dir(os.Args[0]))
  60. scanner := &VolumeFileScanner4SeeDat{
  61. dir: filepath.Join(outpath, "out"),
  62. hashes: map[string]bool{},
  63. }
  64. if _, err := os.Stat(scanner.dir); err != nil {
  65. if err := os.MkdirAll(scanner.dir, os.ModePerm); err != nil {
  66. glog.Fatalf("could not create output dir : %s", err)
  67. }
  68. }
  69. err := storage.ScanVolumeFile(*volumePath, *volumeCollection, vid, storage.NeedleMapInMemory, scanner)
  70. if err != nil {
  71. glog.Fatalf("Reading Volume File [ERROR] %s\n", err)
  72. }
  73. }