more efficient readResolvedChunks with linked list

This commit is contained in:
chrislu 2022-12-27 03:29:11 -08:00
parent 3daaefec60
commit 86b9aa3173
2 changed files with 51 additions and 35 deletions

View file

@ -1,6 +1,7 @@
package filer package filer
import ( import (
"container/list"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
) )
@ -33,40 +34,44 @@ func readResolvedChunks(chunks []*filer_pb.FileChunk) (visibles []VisibleInterva
}) })
var prevX int64 var prevX int64
var queue []*Point queue := list.New() // points with higher ts are at the tail
var lastPoint *Point
for _, point := range points { for _, point := range points {
if queue.Len() > 0 {
lastPoint = queue.Back().Value.(*Point)
} else {
lastPoint = nil
}
if point.isStart { if point.isStart {
if len(queue) > 0 { if lastPoint != nil {
lastIndex := len(queue) - 1
lastPoint := queue[lastIndex]
if point.x != prevX && lastPoint.ts < point.ts { if point.x != prevX && lastPoint.ts < point.ts {
visibles = addToVisibles(visibles, prevX, lastPoint, point) visibles = addToVisibles(visibles, prevX, lastPoint, point)
prevX = point.x prevX = point.x
} }
} }
// insert into queue // insert into queue
for i := len(queue); i >= 0; i-- { if lastPoint == nil || lastPoint.ts < point.ts {
if i == 0 || queue[i-1].ts <= point.ts { queue.PushBack(point)
if i == len(queue) {
prevX = point.x prevX = point.x
} } else {
queue = addToQueue(queue, i, point) for e := queue.Front(); e != nil; e = e.Next() {
if e.Value.(*Point).ts > point.ts {
queue.InsertBefore(point, e)
break break
} }
} }
}
} else { } else {
lastIndex := len(queue) - 1 var isLast bool
index := lastIndex for e := queue.Back(); e != nil; e = e.Prev() {
var startPoint *Point isLast = e.Next() == nil
for ; index >= 0; index-- { if e.Value.(*Point).ts == point.ts {
startPoint = queue[index] queue.Remove(e)
if startPoint.ts == point.ts {
queue = removeFromQueue(queue, index)
break break
} }
} }
if index == lastIndex && startPoint != nil { if isLast && lastPoint != nil {
visibles = addToVisibles(visibles, prevX, startPoint, point) visibles = addToVisibles(visibles, prevX, lastPoint, point)
prevX = point.x prevX = point.x
} }
} }
@ -75,22 +80,6 @@ func readResolvedChunks(chunks []*filer_pb.FileChunk) (visibles []VisibleInterva
return 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 { func addToVisibles(visibles []VisibleInterval, prevX int64, startPoint *Point, point *Point) []VisibleInterval {
if prevX < point.x { if prevX < point.x {
chunk := startPoint.chunk chunk := startPoint.chunk

View file

@ -44,6 +44,33 @@ func TestReadResolvedChunks(t *testing.T) {
visibles := readResolvedChunks(chunks) 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 { for _, visible := range visibles {
fmt.Printf("[%d,%d) %s %d\n", visible.start, visible.stop, visible.fileId, visible.modifiedTsNs) fmt.Printf("[%d,%d) %s %d\n", visible.start, visible.stop, visible.fileId, visible.modifiedTsNs)
} }