summaryrefslogtreecommitdiff
path: root/priority_queue/binary_heap.go
diff options
context:
space:
mode:
Diffstat (limited to 'priority_queue/binary_heap.go')
-rw-r--r--priority_queue/binary_heap.go125
1 files changed, 0 insertions, 125 deletions
diff --git a/priority_queue/binary_heap.go b/priority_queue/binary_heap.go
deleted file mode 100644
index fc043927..00000000
--- a/priority_queue/binary_heap.go
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-binary heap (min-heap) algorithm used as a core for the priority queue
-*/
-
-package priorityqueue
-
-import (
- "sync"
- "sync/atomic"
-)
-
-type BinHeap struct {
- items []Item
- // find a way to use pointer to the raw data
- len uint64
- maxLen uint64
- cond sync.Cond
-}
-
-func NewBinHeap(maxLen uint64) *BinHeap {
- return &BinHeap{
- items: make([]Item, 0, 1000),
- len: 0,
- maxLen: maxLen,
- cond: sync.Cond{L: &sync.Mutex{}},
- }
-}
-
-func (bh *BinHeap) fixUp() {
- k := bh.len - 1
- p := (k - 1) >> 1 // k-1 / 2
-
- for k > 0 {
- cur, par := (bh.items)[k], (bh.items)[p]
-
- if cur.Priority() < par.Priority() {
- bh.swap(k, p)
- k = p
- p = (k - 1) >> 1
- } else {
- return
- }
- }
-}
-
-func (bh *BinHeap) swap(i, j uint64) {
- (bh.items)[i], (bh.items)[j] = (bh.items)[j], (bh.items)[i]
-}
-
-func (bh *BinHeap) fixDown(curr, end int) {
- cOneIdx := (curr << 1) + 1
- for cOneIdx <= end {
- cTwoIdx := -1
- if (curr<<1)+2 <= end {
- cTwoIdx = (curr << 1) + 2
- }
-
- idxToSwap := cOneIdx
- if cTwoIdx > -1 && (bh.items)[cTwoIdx].Priority() < (bh.items)[cOneIdx].Priority() {
- idxToSwap = cTwoIdx
- }
- if (bh.items)[idxToSwap].Priority() < (bh.items)[curr].Priority() {
- bh.swap(uint64(curr), uint64(idxToSwap))
- curr = idxToSwap
- cOneIdx = (curr << 1) + 1
- } else {
- return
- }
- }
-}
-
-func (bh *BinHeap) Len() uint64 {
- return atomic.LoadUint64(&bh.len)
-}
-
-func (bh *BinHeap) Insert(item Item) {
- bh.cond.L.Lock()
-
- // check the binary heap len before insertion
- if bh.Len() > bh.maxLen {
- // unlock the mutex to proceed to get-max
- bh.cond.L.Unlock()
-
- // signal waiting goroutines
- for bh.Len() > 0 {
- // signal waiting goroutines
- bh.cond.Signal()
- }
- // lock mutex to proceed inserting into the empty slice
- bh.cond.L.Lock()
- }
-
- bh.items = append(bh.items, item)
-
- // add len to the slice
- atomic.AddUint64(&bh.len, 1)
-
- // fix binary heap up
- bh.fixUp()
- bh.cond.L.Unlock()
-
- // signal the goroutine on wait
- bh.cond.Signal()
-}
-
-func (bh *BinHeap) ExtractMin() Item {
- bh.cond.L.Lock()
-
- // if len == 0, wait for the signal
- for bh.Len() == 0 {
- bh.cond.Wait()
- }
-
- bh.swap(0, bh.len-1)
-
- item := (bh.items)[int(bh.len)-1]
- bh.items = (bh).items[0 : int(bh.len)-1]
- bh.fixDown(0, int(bh.len-2))
-
- // reduce len
- atomic.AddUint64(&bh.len, ^uint64(0))
-
- bh.cond.L.Unlock()
- return item
-}