Use slice instead of list, no map
benchmark old ns/op new ns/op delta BenchmarkJobQueueBump 345 154498 +44682.03% BenchmarkJobQueuePushPopDone10k 9437373 3258204 -65.48% benchmark old allocs new allocs delta BenchmarkJobQueueBump 0 0 +0.00% BenchmarkJobQueuePushPopDone10k 10565 22 -99.79% benchmark old bytes new bytes delta BenchmarkJobQueueBump 0 0 +0.00% BenchmarkJobQueuePushPopDone10k 1452498 385869 -73.43%
This commit is contained in:
parent
8f72ae9da2
commit
34deb82aea
@ -16,7 +16,6 @@
|
|||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"container/list"
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/syncthing/syncthing/internal/protocol"
|
"github.com/syncthing/syncthing/internal/protocol"
|
||||||
@ -24,38 +23,31 @@ import (
|
|||||||
|
|
||||||
type JobQueue struct {
|
type JobQueue struct {
|
||||||
progress []*protocol.FileInfo
|
progress []*protocol.FileInfo
|
||||||
|
queued []*protocol.FileInfo
|
||||||
queued *list.List
|
mut sync.Mutex
|
||||||
lookup map[string]*list.Element // O(1) lookups
|
|
||||||
|
|
||||||
mut sync.Mutex
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewJobQueue() *JobQueue {
|
func NewJobQueue() *JobQueue {
|
||||||
return &JobQueue{
|
return &JobQueue{}
|
||||||
progress: []*protocol.FileInfo{},
|
|
||||||
queued: list.New(),
|
|
||||||
lookup: make(map[string]*list.Element),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *JobQueue) Push(file *protocol.FileInfo) {
|
func (q *JobQueue) Push(file *protocol.FileInfo) {
|
||||||
q.mut.Lock()
|
q.mut.Lock()
|
||||||
defer q.mut.Unlock()
|
q.queued = append(q.queued, file)
|
||||||
|
q.mut.Unlock()
|
||||||
q.lookup[file.Name] = q.queued.PushBack(file)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *JobQueue) Pop() *protocol.FileInfo {
|
func (q *JobQueue) Pop() *protocol.FileInfo {
|
||||||
q.mut.Lock()
|
q.mut.Lock()
|
||||||
defer q.mut.Unlock()
|
defer q.mut.Unlock()
|
||||||
|
|
||||||
if q.queued.Len() == 0 {
|
if len(q.queued) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
f := q.queued.Remove(q.queued.Front()).(*protocol.FileInfo)
|
var f *protocol.FileInfo
|
||||||
delete(q.lookup, f.Name)
|
f, q.queued[0] = q.queued[0], nil
|
||||||
|
q.queued = q.queued[1:]
|
||||||
q.progress = append(q.progress, f)
|
q.progress = append(q.progress, f)
|
||||||
|
|
||||||
return f
|
return f
|
||||||
@ -65,9 +57,11 @@ func (q *JobQueue) Bump(filename string) {
|
|||||||
q.mut.Lock()
|
q.mut.Lock()
|
||||||
defer q.mut.Unlock()
|
defer q.mut.Unlock()
|
||||||
|
|
||||||
ele, ok := q.lookup[filename]
|
for i := range q.queued {
|
||||||
if ok {
|
if q.queued[i].Name == filename {
|
||||||
q.queued.MoveToFront(ele)
|
q.queued[0], q.queued[i] = q.queued[i], q.queued[0]
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,12 +88,9 @@ func (q *JobQueue) Jobs() ([]protocol.FileInfoTruncated, []protocol.FileInfoTrun
|
|||||||
progress[i] = q.progress[i].ToTruncated()
|
progress[i] = q.progress[i].ToTruncated()
|
||||||
}
|
}
|
||||||
|
|
||||||
queued := make([]protocol.FileInfoTruncated, q.queued.Len())
|
queued := make([]protocol.FileInfoTruncated, len(q.queued))
|
||||||
i := 0
|
for i := range q.queued {
|
||||||
for e := q.queued.Front(); e != nil; e = e.Next() {
|
queued[i] = q.queued[i].ToTruncated()
|
||||||
fi := e.Value.(*protocol.FileInfo)
|
|
||||||
queued[i] = fi.ToTruncated()
|
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return progress, queued
|
return progress, queued
|
||||||
|
|||||||
@ -72,7 +72,7 @@ func TestJobQueue(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(q.progress) > 0 || q.queued.Len() != 4 {
|
if len(q.progress) > 0 || len(q.queued) != 4 {
|
||||||
t.Fatal("Wrong length")
|
t.Fatal("Wrong length")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user