gitlab.com/beacon-software/gadget@v0.0.0-20181217202115-54565ea1ed5e/collection/specialized/priorityqueue.go (about)

     1  package specialized
     2  
     3  import "gitlab.com/beacon-software/gadget/collection"
     4  
     5  // Priority is for use in collections that require elements to resolve
     6  // their own priority.
     7  type Priority interface {
     8  	// GetPriority of this element as an int where lower priority < higher priority
     9  	GetPriority() int
    10  }
    11  
    12  // PriorityQueue for queueing elements that implement priority and returning
    13  // elements in the order of highest to lowest priority.
    14  type PriorityQueue interface {
    15  	// Size of this queue
    16  	Size() int
    17  	// Push the passed element onto this queue
    18  	Push(element Priority)
    19  	// Pop the highest priority element off the queue
    20  	Pop() (Priority, bool)
    21  	// Peek at the highest priority element without modifying the queue
    22  	Peek() (Priority, bool)
    23  }
    24  
    25  type priorityQueue struct {
    26  	list collection.DList
    27  }
    28  
    29  // NewPriorityQueue for queueing elements according to their priority
    30  func NewPriorityQueue() PriorityQueue {
    31  	return &priorityQueue{list: collection.NewDList()}
    32  }
    33  
    34  func (q *priorityQueue) Size() int {
    35  	return q.list.Size()
    36  }
    37  
    38  func (q *priorityQueue) Push(p Priority) {
    39  	var e *collection.DListElement
    40  	for elm := q.list.Head(); elm != nil; elm = elm.Next() {
    41  		d := q.convert(elm.Data())
    42  		if d.GetPriority() > p.GetPriority() {
    43  			e = elm
    44  		}
    45  	}
    46  	if nil == e {
    47  		q.list.InsertPrevious(q.list.Head(), p)
    48  	} else {
    49  		q.list.InsertNext(e, p)
    50  	}
    51  }
    52  
    53  func (q *priorityQueue) nextElement(remove bool) (Priority, bool) {
    54  	var p Priority
    55  	success := false
    56  	if q.list.Head() != nil {
    57  		success = true
    58  		p = q.convert(q.list.Head().Data())
    59  		if remove {
    60  			q.list.Remove(q.list.Head())
    61  		}
    62  	}
    63  	return p, success
    64  }
    65  
    66  func (q *priorityQueue) Pop() (Priority, bool) {
    67  	return q.nextElement(true)
    68  }
    69  
    70  func (q *priorityQueue) Peek() (Priority, bool) {
    71  	return q.nextElement(false)
    72  }
    73  
    74  func (q *priorityQueue) convert(data interface{}) Priority {
    75  	p, _ := data.(Priority)
    76  	return p
    77  }