filechunks_read.go 2.6 KB

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