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
// 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,

View file

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

View file

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