Package list golang-gopkg-eapache-queue.v1 / e423872
Merge pull request #1 from aybabtme/get-index Add a mean to get an index, allowing iterations of the queue. Evan Huus 7 years ago
2 changed file(s) with 105 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
22 Using this instead of other, simpler, queue implementations (slice+append or linked list) provides
33 substantial memory and time benefits, and fewer GC pauses.
44
5 The queue implemented here is as fast as it is for two additional reasons: it is *not* thread-safe, and it
6 intentionally does not follow go best-practices regarding errors - if you make a mistake with this
7 queue (such as trying to remove an element from an empty queue) then who knows what will happen.
5 The queue implemented here is as fast as it is for an additional reason: it is *not* thread-safe.
86 */
97 package queue
108
5250 q.count++
5351 }
5452
55 // Peek returns the element at the head of the queue. If the queue is empty (Length == 0),
56 // Peek does not panic, it simply returns garbage.
53 // Peek returns the element at the head of the queue. This call panics
54 // if the queue is empty.
5755 func (q *Queue) Peek() interface{} {
56 if q.Length() <= 0 {
57 panic("queue: empty queue")
58 }
5859 return q.buf[q.head]
5960 }
6061
61 // Remove removes the element from the front of the queue. If you actually want the element,
62 // call Peek first. If the queue is empty (Length == 0), Remove will put the queue in a bad
63 // state and all further operations will be undefined.
62 // Get returns the element at index i in the queue. If the index is
63 // invalid, the call will panic.
64 func (q *Queue) Get(i int) interface{} {
65 if i >= q.Length() || i < 0 {
66 panic("queue: index out of range")
67 }
68 modi := (q.head + i) % len(q.buf)
69 return q.buf[modi]
70 }
71
72 // Remove removes the element from the front of the queue. If you actually
73 // want the element, call Peek first. This call panics if the queue is empty.
6474 func (q *Queue) Remove() {
75 if q.Length() <= 0 {
76 panic("queue: empty queue")
77 }
6578 q.buf[q.head] = nil
6679 q.head = (q.head + 1) % len(q.buf)
6780 q.count--
1111 for i := 0; i < 1000; i++ {
1212 q.Add(i)
1313 if q.Length() != i+1 {
14 t.Error("adding: queue with", i , "elements has length", q.Length())
14 t.Error("adding: queue with", i, "elements has length", q.Length())
1515 }
1616 }
1717 for i := 0; i < 1000; i++ {
1818 q.Remove()
1919 if q.Length() != 1000-i-1 {
20 t.Error("removing: queue with", 1000-i-i , "elements has length", q.Length())
20 t.Error("removing: queue with", 1000-i-i, "elements has length", q.Length())
2121 }
2222 }
23 }
24
25 func TestQueueGet(t *testing.T) {
26 q := New()
27
28 for i := 0; i < 1000; i++ {
29 q.Add(i)
30 for j := 0; j < q.Length(); j++ {
31 if q.Get(j).(int) != j {
32 t.Errorf("index %d doesn't contain %d", j, j)
33 }
34 }
35 }
36 }
37
38 func TestQueueGetOutOfRangePanics(t *testing.T) {
39 q := New()
40
41 q.Add(1)
42 q.Add(2)
43 q.Add(3)
44
45 assertPanics(t, "should panic when negative index", func() {
46 q.Get(-1)
47 })
48
49 assertPanics(t, "should panic when index greater than length", func() {
50 q.Get(4)
51 })
52 }
53
54 func TestQueuePeekOutOfRangePanics(t *testing.T) {
55 q := New()
56
57 assertPanics(t, "should panic when peeking empty queue", func() {
58 q.Peek()
59 })
60
61 q.Add(1)
62 q.Remove()
63
64 assertPanics(t, "should panic when peeking emptied queue", func() {
65 q.Peek()
66 })
67 }
68
69 func TestQueueRemoveOutOfRangePanics(t *testing.T) {
70 q := New()
71
72 assertPanics(t, "should panic when removing empty queue", func() {
73 q.Remove()
74 })
75
76 q.Add(1)
77 q.Remove()
78
79 assertPanics(t, "should panic when removing emptied queue", func() {
80 q.Remove()
81 })
82 }
83
84 func assertPanics(t *testing.T, name string, f func()) {
85 defer func() {
86 if r := recover(); r == nil {
87 t.Errorf("%s: didn't panic as expected", name)
88 } else {
89 t.Logf("%s: got panic as expected: %v", name, r)
90 }
91 }()
92
93 f()
2394 }
2495
2596 // General warning: Go's benchmark utility (go test -bench .) increases the number of
37108 }
38109 }
39110
111 func BenchmarkQueueGet(b *testing.B) {
112 q := New()
113 for i := 0; i < b.N; i++ {
114 q.Add(i)
115 }
116 b.ResetTimer()
117 for i := 0; i < b.N; i++ {
118 q.Get(i)
119 }
120 }
121
40122 func BenchmarkQueueTickTock(b *testing.B) {
41123 q := New()
42124 for i := 0; i < b.N; i++ {