filechunks2_test.go 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package filer
  2. import (
  3. "context"
  4. "github.com/stretchr/testify/assert"
  5. "log"
  6. "slices"
  7. "testing"
  8. "github.com/seaweedfs/seaweedfs/weed/glog"
  9. "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
  10. )
  11. func TestDoMinusChunks(t *testing.T) {
  12. // https://github.com/seaweedfs/seaweedfs/issues/3328
  13. // clusterA and clusterB using filer.sync to sync file: hello.txt
  14. // clusterA append a new line and then clusterB also append a new line
  15. // clusterA append a new line again
  16. chunksInA := []*filer_pb.FileChunk{
  17. {Offset: 0, Size: 3, FileId: "11", ModifiedTsNs: 100},
  18. {Offset: 3, Size: 3, FileId: "22", SourceFileId: "2", ModifiedTsNs: 200},
  19. {Offset: 6, Size: 3, FileId: "33", ModifiedTsNs: 300},
  20. }
  21. chunksInB := []*filer_pb.FileChunk{
  22. {Offset: 0, Size: 3, FileId: "1", SourceFileId: "11", ModifiedTsNs: 100},
  23. {Offset: 3, Size: 3, FileId: "2", ModifiedTsNs: 200},
  24. {Offset: 6, Size: 3, FileId: "3", SourceFileId: "33", ModifiedTsNs: 300},
  25. }
  26. // clusterB using command "echo 'content' > hello.txt" to overwrite file
  27. // clusterA will receive two evenNotification, need to empty the whole file content first and add new content
  28. // the first one is oldEntry is chunksInB and newEntry is empty fileChunks
  29. firstOldEntry := chunksInB
  30. var firstNewEntry []*filer_pb.FileChunk
  31. // clusterA received the first one event, gonna empty the whole chunk, according the code in filer_sink 194
  32. // we can get the deleted chunks and newChunks
  33. firstDeletedChunks := DoMinusChunks(firstOldEntry, firstNewEntry)
  34. log.Println("first deleted chunks:", firstDeletedChunks)
  35. //firstNewEntry := DoMinusChunks(firstNewEntry, firstOldEntry)
  36. // clusterA need to delete all chunks in firstDeletedChunks
  37. emptiedChunksInA := DoMinusChunksBySourceFileId(chunksInA, firstDeletedChunks)
  38. // chunksInA supposed to be empty by minus the deletedChunks but it just delete the chunk which sync from clusterB
  39. log.Println("clusterA synced empty chunks event result:", emptiedChunksInA)
  40. // clusterB emptied it's chunks and clusterA must sync the change and empty chunks too
  41. assert.Equalf(t, firstNewEntry, emptiedChunksInA, "empty")
  42. }
  43. func TestCompactFileChunksRealCase(t *testing.T) {
  44. chunks := []*filer_pb.FileChunk{
  45. {FileId: "2,512f31f2c0700a", Offset: 0, Size: 25 - 0, ModifiedTsNs: 5320497},
  46. {FileId: "6,512f2c2e24e9e8", Offset: 868352, Size: 917585 - 868352, ModifiedTsNs: 5320492},
  47. {FileId: "7,514468dd5954ca", Offset: 884736, Size: 901120 - 884736, ModifiedTsNs: 5325928},
  48. {FileId: "5,5144463173fe77", Offset: 917504, Size: 2297856 - 917504, ModifiedTsNs: 5325894},
  49. {FileId: "4,51444c7ab54e2d", Offset: 2301952, Size: 2367488 - 2301952, ModifiedTsNs: 5325900},
  50. {FileId: "4,514450e643ad22", Offset: 2371584, Size: 2420736 - 2371584, ModifiedTsNs: 5325904},
  51. {FileId: "6,514456a5e9e4d7", Offset: 2449408, Size: 2490368 - 2449408, ModifiedTsNs: 5325910},
  52. {FileId: "3,51444f8d53eebe", Offset: 2494464, Size: 2555904 - 2494464, ModifiedTsNs: 5325903},
  53. {FileId: "4,5144578b097c7e", Offset: 2560000, Size: 2596864 - 2560000, ModifiedTsNs: 5325911},
  54. {FileId: "3,51445500b6b4ac", Offset: 2637824, Size: 2678784 - 2637824, ModifiedTsNs: 5325909},
  55. {FileId: "1,51446285e52a61", Offset: 2695168, Size: 2715648 - 2695168, ModifiedTsNs: 5325922},
  56. }
  57. printChunks("before", chunks)
  58. compacted, garbage := CompactFileChunks(context.Background(), nil, chunks)
  59. printChunks("compacted", compacted)
  60. printChunks("garbage", garbage)
  61. }
  62. func printChunks(name string, chunks []*filer_pb.FileChunk) {
  63. slices.SortFunc(chunks, func(a, b *filer_pb.FileChunk) int {
  64. if a.Offset == b.Offset {
  65. return int(a.ModifiedTsNs - b.ModifiedTsNs)
  66. }
  67. return int(a.Offset - b.Offset)
  68. })
  69. for _, chunk := range chunks {
  70. glog.V(0).Infof("%s chunk %s [%10d,%10d)", name, chunk.GetFileIdString(), chunk.Offset, chunk.Offset+int64(chunk.Size))
  71. }
  72. }