diff --git a/weed/filer/filechunks_read.go b/weed/filer/filechunks_read.go index 8a15f6e7a..e446615e2 100644 --- a/weed/filer/filechunks_read.go +++ b/weed/filer/filechunks_read.go @@ -1,6 +1,7 @@ package filer import ( + "container/list" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" "golang.org/x/exp/slices" ) @@ -33,40 +34,44 @@ func readResolvedChunks(chunks []*filer_pb.FileChunk) (visibles []VisibleInterva }) var prevX int64 - var queue []*Point + queue := list.New() // points with higher ts are at the tail + var lastPoint *Point for _, point := range points { + if queue.Len() > 0 { + lastPoint = queue.Back().Value.(*Point) + } else { + lastPoint = nil + } if point.isStart { - if len(queue) > 0 { - lastIndex := len(queue) - 1 - lastPoint := queue[lastIndex] + if lastPoint != nil { 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 + if lastPoint == nil || lastPoint.ts < point.ts { + queue.PushBack(point) + prevX = point.x + } else { + for e := queue.Front(); e != nil; e = e.Next() { + if e.Value.(*Point).ts > point.ts { + queue.InsertBefore(point, e) + break } - 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) + var isLast bool + for e := queue.Back(); e != nil; e = e.Prev() { + isLast = e.Next() == nil + if e.Value.(*Point).ts == point.ts { + queue.Remove(e) break } } - if index == lastIndex && startPoint != nil { - visibles = addToVisibles(visibles, prevX, startPoint, point) + if isLast && lastPoint != nil { + visibles = addToVisibles(visibles, prevX, lastPoint, point) prevX = point.x } } @@ -75,22 +80,6 @@ func readResolvedChunks(chunks []*filer_pb.FileChunk) (visibles []VisibleInterva 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 diff --git a/weed/filer/filechunks_read_test.go b/weed/filer/filechunks_read_test.go index d4bfca72e..5afecc52c 100644 --- a/weed/filer/filechunks_read_test.go +++ b/weed/filer/filechunks_read_test.go @@ -44,6 +44,33 @@ func TestReadResolvedChunks(t *testing.T) { visibles := readResolvedChunks(chunks) + fmt.Printf("resolved to %d visible intervales\n", len(visibles)) + for _, visible := range visibles { + fmt.Printf("[%d,%d) %s %d\n", visible.start, visible.stop, visible.fileId, visible.modifiedTsNs) + } + +} + +func TestReadResolvedChunks2(t *testing.T) { + + chunks := []*filer_pb.FileChunk{ + { + FileId: "c", + Offset: 200, + Size: 50, + ModifiedTsNs: 3, + }, + { + FileId: "e", + Offset: 200, + Size: 25, + ModifiedTsNs: 5, + }, + } + + visibles := readResolvedChunks(chunks) + + fmt.Printf("resolved to %d visible intervales\n", len(visibles)) for _, visible := range visibles { fmt.Printf("[%d,%d) %s %d\n", visible.start, visible.stop, visible.fileId, visible.modifiedTsNs) }