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.

105 lines
2.3 KiB

  1. package filer
  2. import (
  3. "container/list"
  4. "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
  5. "golang.org/x/exp/slices"
  6. )
  7. func readResolvedChunks(chunks []*filer_pb.FileChunk) (visibles []VisibleInterval) {
  8. var points []*Point
  9. for _, chunk := range chunks {
  10. points = append(points, &Point{
  11. x: chunk.Offset,
  12. ts: chunk.ModifiedTsNs,
  13. chunk: chunk,
  14. isStart: true,
  15. })
  16. points = append(points, &Point{
  17. x: chunk.Offset + int64(chunk.Size),
  18. ts: chunk.ModifiedTsNs,
  19. chunk: chunk,
  20. isStart: false,
  21. })
  22. }
  23. slices.SortFunc(points, func(a, b *Point) bool {
  24. if a.x != b.x {
  25. return a.x < b.x
  26. }
  27. if a.ts != b.ts {
  28. return a.ts < b.ts
  29. }
  30. return !a.isStart
  31. })
  32. var prevX int64
  33. queue := list.New() // points with higher ts are at the tail
  34. var lastPoint *Point
  35. for _, point := range points {
  36. if queue.Len() > 0 {
  37. lastPoint = queue.Back().Value.(*Point)
  38. } else {
  39. lastPoint = nil
  40. }
  41. if point.isStart {
  42. if lastPoint != nil {
  43. if point.x != prevX && lastPoint.ts < point.ts {
  44. visibles = addToVisibles(visibles, prevX, lastPoint, point)
  45. prevX = point.x
  46. }
  47. }
  48. // insert into queue
  49. if lastPoint == nil || lastPoint.ts < point.ts {
  50. queue.PushBack(point)
  51. prevX = point.x
  52. } else {
  53. for e := queue.Front(); e != nil; e = e.Next() {
  54. if e.Value.(*Point).ts > point.ts {
  55. queue.InsertBefore(point, e)
  56. break
  57. }
  58. }
  59. }
  60. } else {
  61. isLast := true
  62. for e := queue.Back(); e != nil; e = e.Prev() {
  63. if e.Value.(*Point).ts == point.ts {
  64. queue.Remove(e)
  65. break
  66. }
  67. isLast = false
  68. }
  69. if isLast && lastPoint != nil {
  70. visibles = addToVisibles(visibles, prevX, lastPoint, point)
  71. prevX = point.x
  72. }
  73. }
  74. }
  75. return
  76. }
  77. func addToVisibles(visibles []VisibleInterval, prevX int64, startPoint *Point, point *Point) []VisibleInterval {
  78. if prevX < point.x {
  79. chunk := startPoint.chunk
  80. visibles = append(visibles, VisibleInterval{
  81. start: prevX,
  82. stop: point.x,
  83. fileId: chunk.GetFileIdString(),
  84. modifiedTsNs: chunk.ModifiedTsNs,
  85. chunkOffset: prevX - chunk.Offset,
  86. chunkSize: chunk.Size,
  87. cipherKey: chunk.CipherKey,
  88. isGzipped: chunk.IsCompressed,
  89. })
  90. }
  91. return visibles
  92. }
  93. type Point struct {
  94. x int64
  95. ts int64
  96. chunk *filer_pb.FileChunk
  97. isStart bool
  98. }