From 1f9709e1a20c5d499968454aa3d355b811d190da Mon Sep 17 00:00:00 2001 From: Zsolt Felfoldi Date: Sun, 15 Apr 2018 00:49:30 +0200 Subject: [PATCH] prque: pass compare function directly to queue/stack --- les/flowcontrol/manager.go | 12 ++++++------ les/flowcontrol/prque/prque.go | 12 ++++++------ les/flowcontrol/prque/sstack.go | 26 +++++++++++++------------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/les/flowcontrol/manager.go b/les/flowcontrol/manager.go index ee7405e2fc..242b07ad2a 100644 --- a/les/flowcontrol/manager.go +++ b/les/flowcontrol/manager.go @@ -50,8 +50,8 @@ type rcQueueItem struct { // // Note: intValue is interpreted as mod 2^64, the difference between the highest // and lowest value at any moment is always less than 2^63. -func (rcq rcQueueItem) Before(j interface{}) bool { - return (j.(rcQueueItem).intValue - rcq.intValue) > 0 +func rcQueueCompare(i, j interface{}) bool { + return (j.(rcQueueItem).intValue - i.(rcQueueItem).intValue) > 0 } // Note: valid is called under client manager mutex lock @@ -66,8 +66,8 @@ type servingQueueItem struct { } // Before implements prque.item -func (sq servingQueueItem) Before(j interface{}) bool { - return sq.priority > j.(servingQueueItem).priority +func servingQueueCompare(i, j interface{}) bool { + return i.(servingQueueItem).priority > j.(servingQueueItem).priority } // ClientManager controls the bandwidth assigned to the clients of a server. @@ -105,8 +105,8 @@ func NewClientManager(maxParallelReqs int, targetParallelReqs float64, clock mcl clock: clock, nodes: make(map[*ClientNode]struct{}), child: child, - servingQueue: prque.New(), - rcQueue: prque.New(), + servingQueue: prque.New(servingQueueCompare), + rcQueue: prque.New(rcQueueCompare), maxParallelReqs: maxParallelReqs, targetParallelReqs: targetParallelReqs, diff --git a/les/flowcontrol/prque/prque.go b/les/flowcontrol/prque/prque.go index 542e59f98c..acfa8bf9a3 100755 --- a/les/flowcontrol/prque/prque.go +++ b/les/flowcontrol/prque/prque.go @@ -12,19 +12,19 @@ type Prque struct { } // Creates a new priority queue. -func New() *Prque { - return &Prque{newSstack()} +func New(compare compareFn) *Prque { + return &Prque{newSstack(compare)} } // Pushes a value with a given priority into the queue, expanding if necessary. -func (p *Prque) Push(i item) { +func (p *Prque) Push(i interface{}) { heap.Push(p.cont, i) } // Pops the value with the greates priority off the stack and returns it. // Currently no shrinking is done. -func (p *Prque) Pop() item { - return heap.Pop(p.cont).(item) +func (p *Prque) Pop() interface{} { + return heap.Pop(p.cont) } // Checks whether the priority queue is empty. @@ -39,5 +39,5 @@ func (p *Prque) Size() int { // Clears the contents of the priority queue. func (p *Prque) Reset() { - *p = *New() + *p = *New(p.cont.compare) } diff --git a/les/flowcontrol/prque/sstack.go b/les/flowcontrol/prque/sstack.go index 026ddeffe1..b018c735df 100755 --- a/les/flowcontrol/prque/sstack.go +++ b/les/flowcontrol/prque/sstack.go @@ -5,28 +5,28 @@ package prque // The size of a block of data const blockSize = 4096 -// A prioritized item in the sorted stack. -type item interface { - Before(interface{}) bool -} +// returns true if a comes before b +type compareFn func(a, b interface{}) bool // Internal sortable stack data structure. Implements the Push and Pop ops for // the stack (heap) functionality and the Len, Less and Swap methods for the // sortability requirements of the heaps. type sstack struct { + compare compareFn size int capacity int offset int - blocks [][]item - active []item + blocks [][]interface{} + active []interface{} } // Creates a new, empty stack. -func newSstack() *sstack { +func newSstack(compare compareFn) *sstack { result := new(sstack) - result.active = make([]item, blockSize) - result.blocks = [][]item{result.active} + result.compare = compare + result.active = make([]interface{}, blockSize) + result.blocks = [][]interface{}{result.active} result.capacity = blockSize return result } @@ -35,7 +35,7 @@ func newSstack() *sstack { // heap.Interface. func (s *sstack) Push(data interface{}) { if s.size == s.capacity { - s.active = make([]item, blockSize) + s.active = make([]interface{}, blockSize) s.blocks = append(s.blocks, s.active) s.capacity += blockSize s.offset = 0 @@ -43,7 +43,7 @@ func (s *sstack) Push(data interface{}) { s.active = s.blocks[s.size/blockSize] s.offset = 0 } - s.active[s.offset] = data.(item) + s.active[s.offset] = data s.offset++ s.size++ } @@ -69,7 +69,7 @@ func (s *sstack) Len() int { // Compares the priority of two elements of the stack (higher is first). // Required by sort.Interface. func (s *sstack) Less(i, j int) bool { - return (s.blocks[i/blockSize][i%blockSize].Before(s.blocks[j/blockSize][j%blockSize])) + return s.compare(s.blocks[i/blockSize][i%blockSize], s.blocks[j/blockSize][j%blockSize]) } // Swaps two elements in the stack. Required by sort.Interface. @@ -80,5 +80,5 @@ func (s *sstack) Swap(i, j int) { // Resets the stack, effectively clearing its contents. func (s *sstack) Reset() { - *s = *newSstack() + *s = *newSstack(s.compare) }