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.

121 lines
3.2 KiB

  1. package erasure_coding
  2. import (
  3. "fmt"
  4. "os"
  5. "testing"
  6. "github.com/chrislusf/seaweedfs/weed/storage"
  7. "github.com/chrislusf/seaweedfs/weed/storage/needle_map"
  8. "github.com/chrislusf/seaweedfs/weed/storage/types"
  9. "github.com/klauspost/reedsolomon"
  10. )
  11. func TestEncodingDecoding(t *testing.T) {
  12. largeBlockSize := int64(10000)
  13. smallBlockSize := int64(100)
  14. bufferSize := 50
  15. baseFileName := "1"
  16. file, err := os.OpenFile(baseFileName+".dat", os.O_RDONLY, 0)
  17. if err != nil {
  18. t.Logf("failed to open dat file: %v", err)
  19. }
  20. fi, err := file.Stat()
  21. if err != nil {
  22. t.Logf("failed to stat dat file: %v", err)
  23. }
  24. err = encodeDatFile(fi.Size(), err, baseFileName, bufferSize, largeBlockSize, file, smallBlockSize)
  25. if err != nil {
  26. t.Logf("failed to stat dat file: %v", err)
  27. }
  28. file.Close()
  29. err = writeSortedEcxFiles(baseFileName)
  30. if err != nil {
  31. t.Logf("writeSortedEcxFiles: %v", err)
  32. }
  33. err = validateFiles(baseFileName)
  34. if err != nil {
  35. t.Logf("writeSortedEcxFiles: %v", err)
  36. }
  37. }
  38. func encodeDatFile(remainingSize int64, err error, baseFileName string, bufferSize int, largeBlockSize int64, file *os.File, smallBlockSize int64) error {
  39. var processedSize int64
  40. enc, err := reedsolomon.New(DataShardsCount, ParityShardsCount)
  41. if err != nil {
  42. return fmt.Errorf("failed to create encoder: %v", err)
  43. }
  44. buffers := make([][]byte, DataShardsCount+ParityShardsCount)
  45. outputs, err := openEcFiles(baseFileName)
  46. defer closeEcFiles(outputs)
  47. if err != nil {
  48. return fmt.Errorf("failed to open dat file: %v", err)
  49. }
  50. for i, _ := range buffers {
  51. buffers[i] = make([]byte, bufferSize)
  52. }
  53. for remainingSize > largeBlockSize*DataShardsCount {
  54. err = encodeData(file, enc, processedSize, largeBlockSize, buffers, outputs)
  55. if err != nil {
  56. return fmt.Errorf("failed to encode large chunk data: %v", err)
  57. }
  58. remainingSize -= largeBlockSize * DataShardsCount
  59. processedSize += largeBlockSize * DataShardsCount
  60. }
  61. for remainingSize > 0 {
  62. encodeData(file, enc, processedSize, smallBlockSize, buffers, outputs)
  63. if err != nil {
  64. return fmt.Errorf("failed to encode small chunk data: %v", err)
  65. }
  66. remainingSize -= smallBlockSize * DataShardsCount
  67. processedSize += smallBlockSize * DataShardsCount
  68. }
  69. return nil
  70. }
  71. func writeSortedEcxFiles(baseFileName string) (e error) {
  72. var indexFile *os.File
  73. if indexFile, e = os.OpenFile(baseFileName+".idx", os.O_RDONLY, 0644); e != nil {
  74. return fmt.Errorf("cannot read Volume Index %s.idx: %v", baseFileName, e)
  75. }
  76. cm := needle_map.NewCompactMap()
  77. storage.WalkIndexFile(indexFile, func(key types.NeedleId, offset types.Offset, size uint32) error {
  78. if !offset.IsZero() && size != types.TombstoneFileSize {
  79. cm.Set(key, offset, size)
  80. } else {
  81. cm.Delete(key)
  82. }
  83. return nil
  84. })
  85. ecxFile, err := os.OpenFile(baseFileName+".ecx", os.O_TRUNC|os.O_CREATE|os.O_WRONLY, 0644)
  86. if err != nil {
  87. return fmt.Errorf("failed to open dat file: %v", err)
  88. }
  89. defer ecxFile.Close()
  90. err = cm.AscendingVisit(func(value needle_map.NeedleValue) error {
  91. bytes := value.ToBytes()
  92. _, writeErr := ecxFile.Write(bytes)
  93. return writeErr
  94. })
  95. if err != nil {
  96. return fmt.Errorf("failed to open dat file: %v", err)
  97. }
  98. return nil
  99. }
  100. func validateFiles(baseFileName string) error {
  101. return nil
  102. }