filechunks_read.go 2.6 KB

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