|
|
@@ -7,6 +7,8 @@ The queue implemented here is as fast as it is for an additional reason: it is *
|
|
|
*/
|
|
|
package queue
|
|
|
|
|
|
+// minQueueLen is smallest capacity that queue may have.
|
|
|
+// Must be power of 2 for bitwise modulus: x % n == x & (n - 1).
|
|
|
const minQueueLen = 16
|
|
|
|
|
|
// Queue represents a single instance of the queue data structure.
|
|
|
@@ -30,7 +32,7 @@ func (q *Queue) Length() int {
|
|
|
// resizes the queue to fit exactly twice its current contents
|
|
|
// this can result in shrinking if the queue is less than half-full
|
|
|
func (q *Queue) resize() {
|
|
|
- newBuf := make([]interface{}, q.count*2)
|
|
|
+ newBuf := make([]interface{}, q.count<<1)
|
|
|
|
|
|
if q.tail > q.head {
|
|
|
copy(newBuf, q.buf[q.head:q.tail])
|
|
|
@@ -51,7 +53,8 @@ func (q *Queue) Add(elem interface{}) {
|
|
|
}
|
|
|
|
|
|
q.buf[q.tail] = elem
|
|
|
- q.tail = (q.tail + 1) % len(q.buf)
|
|
|
+ // bitwise modulus
|
|
|
+ q.tail = (q.tail + 1) & (len(q.buf) - 1)
|
|
|
q.count++
|
|
|
}
|
|
|
|
|
|
@@ -76,7 +79,8 @@ func (q *Queue) Get(i int) interface{} {
|
|
|
if i < 0 || i >= q.count {
|
|
|
panic("queue: Get() called with index out of range")
|
|
|
}
|
|
|
- return q.buf[(q.head+i)%len(q.buf)]
|
|
|
+ // bitwise modulus
|
|
|
+ return q.buf[(q.head+i)&(len(q.buf)-1)]
|
|
|
}
|
|
|
|
|
|
// Remove removes the element from the front of the queue. If you actually
|
|
|
@@ -86,9 +90,11 @@ func (q *Queue) Remove() {
|
|
|
panic("queue: Remove() called on empty queue")
|
|
|
}
|
|
|
q.buf[q.head] = nil
|
|
|
- q.head = (q.head + 1) % len(q.buf)
|
|
|
+ // bitwise modulus
|
|
|
+ q.head = (q.head + 1) & (len(q.buf) - 1)
|
|
|
q.count--
|
|
|
- if len(q.buf) > minQueueLen && q.count*4 == len(q.buf) {
|
|
|
+ // Resize down if buffer 1/4 full.
|
|
|
+ if len(q.buf) > minQueueLen && (q.count<<2) == len(q.buf) {
|
|
|
q.resize()
|
|
|
}
|
|
|
}
|