prque: pass compare function directly to queue/stack

This commit is contained in:
Zsolt Felfoldi 2018-04-15 00:49:30 +02:00
parent e7f57c57e7
commit 1f9709e1a2
3 changed files with 25 additions and 25 deletions

View file

@ -50,8 +50,8 @@ type rcQueueItem struct {
// //
// Note: intValue is interpreted as mod 2^64, the difference between the highest // 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. // and lowest value at any moment is always less than 2^63.
func (rcq rcQueueItem) Before(j interface{}) bool { func rcQueueCompare(i, j interface{}) bool {
return (j.(rcQueueItem).intValue - rcq.intValue) > 0 return (j.(rcQueueItem).intValue - i.(rcQueueItem).intValue) > 0
} }
// Note: valid is called under client manager mutex lock // Note: valid is called under client manager mutex lock
@ -66,8 +66,8 @@ type servingQueueItem struct {
} }
// Before implements prque.item // Before implements prque.item
func (sq servingQueueItem) Before(j interface{}) bool { func servingQueueCompare(i, j interface{}) bool {
return sq.priority > j.(servingQueueItem).priority return i.(servingQueueItem).priority > j.(servingQueueItem).priority
} }
// ClientManager controls the bandwidth assigned to the clients of a server. // 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, clock: clock,
nodes: make(map[*ClientNode]struct{}), nodes: make(map[*ClientNode]struct{}),
child: child, child: child,
servingQueue: prque.New(), servingQueue: prque.New(servingQueueCompare),
rcQueue: prque.New(), rcQueue: prque.New(rcQueueCompare),
maxParallelReqs: maxParallelReqs, maxParallelReqs: maxParallelReqs,
targetParallelReqs: targetParallelReqs, targetParallelReqs: targetParallelReqs,

View file

@ -12,19 +12,19 @@ type Prque struct {
} }
// Creates a new priority queue. // Creates a new priority queue.
func New() *Prque { func New(compare compareFn) *Prque {
return &Prque{newSstack()} return &Prque{newSstack(compare)}
} }
// Pushes a value with a given priority into the queue, expanding if necessary. // 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) heap.Push(p.cont, i)
} }
// Pops the value with the greates priority off the stack and returns it. // Pops the value with the greates priority off the stack and returns it.
// Currently no shrinking is done. // Currently no shrinking is done.
func (p *Prque) Pop() item { func (p *Prque) Pop() interface{} {
return heap.Pop(p.cont).(item) return heap.Pop(p.cont)
} }
// Checks whether the priority queue is empty. // Checks whether the priority queue is empty.
@ -39,5 +39,5 @@ func (p *Prque) Size() int {
// Clears the contents of the priority queue. // Clears the contents of the priority queue.
func (p *Prque) Reset() { func (p *Prque) Reset() {
*p = *New() *p = *New(p.cont.compare)
} }

View file

@ -5,28 +5,28 @@ package prque
// The size of a block of data // The size of a block of data
const blockSize = 4096 const blockSize = 4096
// A prioritized item in the sorted stack. // returns true if a comes before b
type item interface { type compareFn func(a, b interface{}) bool
Before(interface{}) bool
}
// Internal sortable stack data structure. Implements the Push and Pop ops for // 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 // the stack (heap) functionality and the Len, Less and Swap methods for the
// sortability requirements of the heaps. // sortability requirements of the heaps.
type sstack struct { type sstack struct {
compare compareFn
size int size int
capacity int capacity int
offset int offset int
blocks [][]item blocks [][]interface{}
active []item active []interface{}
} }
// Creates a new, empty stack. // Creates a new, empty stack.
func newSstack() *sstack { func newSstack(compare compareFn) *sstack {
result := new(sstack) result := new(sstack)
result.active = make([]item, blockSize) result.compare = compare
result.blocks = [][]item{result.active} result.active = make([]interface{}, blockSize)
result.blocks = [][]interface{}{result.active}
result.capacity = blockSize result.capacity = blockSize
return result return result
} }
@ -35,7 +35,7 @@ func newSstack() *sstack {
// heap.Interface. // heap.Interface.
func (s *sstack) Push(data interface{}) { func (s *sstack) Push(data interface{}) {
if s.size == s.capacity { if s.size == s.capacity {
s.active = make([]item, blockSize) s.active = make([]interface{}, blockSize)
s.blocks = append(s.blocks, s.active) s.blocks = append(s.blocks, s.active)
s.capacity += blockSize s.capacity += blockSize
s.offset = 0 s.offset = 0
@ -43,7 +43,7 @@ func (s *sstack) Push(data interface{}) {
s.active = s.blocks[s.size/blockSize] s.active = s.blocks[s.size/blockSize]
s.offset = 0 s.offset = 0
} }
s.active[s.offset] = data.(item) s.active[s.offset] = data
s.offset++ s.offset++
s.size++ s.size++
} }
@ -69,7 +69,7 @@ func (s *sstack) Len() int {
// Compares the priority of two elements of the stack (higher is first). // Compares the priority of two elements of the stack (higher is first).
// Required by sort.Interface. // Required by sort.Interface.
func (s *sstack) Less(i, j int) bool { 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. // 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. // Resets the stack, effectively clearing its contents.
func (s *sstack) Reset() { func (s *sstack) Reset() {
*s = *newSstack() *s = *newSstack(s.compare)
} }