Browse Source

more efficient readResolvedChunks with linked list

pull/4089/head
chrislu 2 years ago
parent
commit
86b9aa3173
  1. 59
      weed/filer/filechunks_read.go
  2. 27
      weed/filer/filechunks_read_test.go

59
weed/filer/filechunks_read.go

@ -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 {
lastIndex := len(queue) - 1
lastPoint := queue[lastIndex]
if lastPoint != nil {
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 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 { } 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 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 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

27
weed/filer/filechunks_read_test.go

@ -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)
} }

Loading…
Cancel
Save