Merge pull request #11 from gammazero/bitmath
Bitwise math for speed
Evan Huus authored 7 years ago
GitHub committed 7 years ago
6 | 6 | */ |
7 | 7 | package queue |
8 | 8 | |
9 | // minQueueLen is smallest capacity that queue may have. | |
10 | // Must be power of 2 for bitwise modulus: x % n == x & (n - 1). | |
9 | 11 | const minQueueLen = 16 |
10 | 12 | |
11 | 13 | // Queue represents a single instance of the queue data structure. |
29 | 31 | // resizes the queue to fit exactly twice its current contents |
30 | 32 | // this can result in shrinking if the queue is less than half-full |
31 | 33 | func (q *Queue) resize() { |
32 | newBuf := make([]interface{}, q.count*2) | |
34 | newBuf := make([]interface{}, q.count<<1) | |
33 | 35 | |
34 | 36 | if q.tail > q.head { |
35 | 37 | copy(newBuf, q.buf[q.head:q.tail]) |
50 | 52 | } |
51 | 53 | |
52 | 54 | q.buf[q.tail] = elem |
53 | q.tail = (q.tail + 1) % len(q.buf) | |
55 | // bitwise modulus | |
56 | q.tail = (q.tail + 1) & (len(q.buf) - 1) | |
54 | 57 | q.count++ |
55 | 58 | } |
56 | 59 | |
75 | 78 | if i < 0 || i >= q.count { |
76 | 79 | panic("queue: Get() called with index out of range") |
77 | 80 | } |
78 | return q.buf[(q.head+i)%len(q.buf)] | |
81 | // bitwise modulus | |
82 | return q.buf[(q.head+i)&(len(q.buf)-1)] | |
79 | 83 | } |
80 | 84 | |
81 | 85 | // Remove removes the element from the front of the queue. If you actually |
85 | 89 | panic("queue: Remove() called on empty queue") |
86 | 90 | } |
87 | 91 | q.buf[q.head] = nil |
88 | q.head = (q.head + 1) % len(q.buf) | |
92 | // bitwise modulus | |
93 | q.head = (q.head + 1) & (len(q.buf) - 1) | |
89 | 94 | q.count-- |
90 | if len(q.buf) > minQueueLen && q.count*4 == len(q.buf) { | |
95 | // Resize down if buffer 1/4 full. | |
96 | if len(q.buf) > minQueueLen && (q.count<<2) == len(q.buf) { | |
91 | 97 | q.resize() |
92 | 98 | } |
93 | 99 | } |