123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- package filer
- import (
- "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
- "golang.org/x/exp/slices"
- )
- func readResolvedChunks(chunks []*filer_pb.FileChunk) (visibles []VisibleInterval) {
- var points []*Point
- for _, chunk := range chunks {
- points = append(points, &Point{
- x: chunk.Offset,
- ts: chunk.ModifiedTsNs,
- chunk: chunk,
- isStart: true,
- })
- points = append(points, &Point{
- x: chunk.Offset + int64(chunk.Size),
- ts: chunk.ModifiedTsNs,
- chunk: chunk,
- isStart: false,
- })
- }
- slices.SortFunc(points, func(a, b *Point) bool {
- if a.x != b.x {
- return a.x < b.x
- }
- if a.ts != b.ts {
- return a.ts < b.ts
- }
- return !a.isStart
- })
- var prevX int64
- var queue []*Point
- for _, point := range points {
- if point.isStart {
- if len(queue) > 0 {
- lastIndex := len(queue) - 1
- lastPoint := queue[lastIndex]
- if point.x != prevX && lastPoint.ts < point.ts {
- visibles = addToVisibles(visibles, prevX, lastPoint, point)
- prevX = point.x
- }
- }
- // insert into queue
- for i := len(queue); i >= 0; i-- {
- if i == 0 || queue[i-1].ts <= point.ts {
- if i == len(queue) {
- prevX = point.x
- }
- queue = addToQueue(queue, i, point)
- break
- }
- }
- } else {
- lastIndex := len(queue) - 1
- index := lastIndex
- var startPoint *Point
- for ; index >= 0; index-- {
- startPoint = queue[index]
- if startPoint.ts == point.ts {
- queue = removeFromQueue(queue, index)
- break
- }
- }
- if index == lastIndex && startPoint != nil {
- visibles = addToVisibles(visibles, prevX, startPoint, point)
- prevX = point.x
- }
- }
- }
- return
- }
- func removeFromQueue(queue []*Point, index int) []*Point {
- for i := index; i < len(queue)-1; i++ {
- queue[i] = queue[i+1]
- }
- queue = queue[:len(queue)-1]
- return queue
- }
- func addToQueue(queue []*Point, index int, point *Point) []*Point {
- queue = append(queue, point)
- for i := len(queue) - 1; i > index; i-- {
- queue[i], queue[i-1] = queue[i-1], queue[i]
- }
- return queue
- }
- func addToVisibles(visibles []VisibleInterval, prevX int64, startPoint *Point, point *Point) []VisibleInterval {
- if prevX < point.x {
- chunk := startPoint.chunk
- visibles = append(visibles, VisibleInterval{
- start: prevX,
- stop: point.x,
- fileId: chunk.GetFileIdString(),
- modifiedTsNs: chunk.ModifiedTsNs,
- chunkOffset: prevX - chunk.Offset,
- chunkSize: chunk.Size,
- cipherKey: chunk.CipherKey,
- isGzipped: chunk.IsCompressed,
- })
- }
- return visibles
- }
- type Point struct {
- x int64
- ts int64
- chunk *filer_pb.FileChunk
- isStart bool
- }
|