pax_global_header00006660000000000000000000000064125345574370014531gustar00rootroot0000000000000052 comment=ded5959c0d4e360646dc9e9908cff48666781367 golang-gopkg-eapache-queue.v1-1.0.2/000077500000000000000000000000001253455743700171405ustar00rootroot00000000000000golang-gopkg-eapache-queue.v1-1.0.2/.gitignore000066400000000000000000000004031253455743700211250ustar00rootroot00000000000000# Compiled Object files, Static and Dynamic libs (Shared Objects) *.o *.a *.so # Folders _obj _test # Architecture specific extensions/prefixes *.[568vq] [568vq].out *.cgo1.go *.cgo2.c _cgo_defun.c _cgo_gotypes.go _cgo_export.* _testmain.go *.exe *.test golang-gopkg-eapache-queue.v1-1.0.2/.travis.yml000066400000000000000000000000661253455743700212530ustar00rootroot00000000000000language: go sudo: false go: - 1.2 - 1.3 - 1.4 golang-gopkg-eapache-queue.v1-1.0.2/LICENSE000066400000000000000000000020631253455743700201460ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2014 Evan Huus Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.golang-gopkg-eapache-queue.v1-1.0.2/README.md000066400000000000000000000015211253455743700204160ustar00rootroot00000000000000Queue ===== [![Build Status](https://travis-ci.org/eapache/queue.svg)](https://travis-ci.org/eapache/queue) [![GoDoc](https://godoc.org/github.com/eapache/queue?status.png)](https://godoc.org/github.com/eapache/queue) [![Code of Conduct](https://img.shields.io/badge/code%20of%20conduct-active-blue.svg)](https://eapache.github.io/conduct.html) A fast Golang queue using a ring-buffer, based on the version suggested by Dariusz Górecki. Using this instead of other, simpler, queue implementations (slice+append or linked list) provides substantial memory and time benefits, and fewer GC pauses. The queue implemented here is as fast as it is in part because it is *not* thread-safe. Follows semantic versioning using https://gopkg.in/ - import from [`gopkg.in/eapache/queue.v1`](https://gopkg.in/eapache/queue.v1) for guaranteed API stability. golang-gopkg-eapache-queue.v1-1.0.2/queue.go000066400000000000000000000043571253455743700206240ustar00rootroot00000000000000/* Package queue provides a fast, ring-buffer queue based on the version suggested by Dariusz Górecki. Using this instead of other, simpler, queue implementations (slice+append or linked list) provides substantial memory and time benefits, and fewer GC pauses. The queue implemented here is as fast as it is for an additional reason: it is *not* thread-safe. */ package queue const minQueueLen = 16 // Queue represents a single instance of the queue data structure. type Queue struct { buf []interface{} head, tail, count int } // New constructs and returns a new Queue. func New() *Queue { return &Queue{ buf: make([]interface{}, minQueueLen), } } // Length returns the number of elements currently stored in the queue. func (q *Queue) Length() int { return q.count } // 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) if q.tail > q.head { copy(newBuf, q.buf[q.head:q.tail]) } else { n := copy(newBuf, q.buf[q.head:]) copy(newBuf[n:], q.buf[:q.tail]) } q.head = 0 q.tail = q.count q.buf = newBuf } // Add puts an element on the end of the queue. func (q *Queue) Add(elem interface{}) { if q.count == len(q.buf) { q.resize() } q.buf[q.tail] = elem q.tail = (q.tail + 1) % len(q.buf) q.count++ } // Peek returns the element at the head of the queue. This call panics // if the queue is empty. func (q *Queue) Peek() interface{} { if q.count <= 0 { panic("queue: Peek() called on empty queue") } return q.buf[q.head] } // Get returns the element at index i in the queue. If the index is // invalid, the call will panic. 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)] } // Remove removes the element from the front of the queue. If you actually // want the element, call Peek first. This call panics if the queue is empty. func (q *Queue) Remove() { if q.count <= 0 { panic("queue: Remove() called on empty queue") } q.buf[q.head] = nil q.head = (q.head + 1) % len(q.buf) q.count-- if len(q.buf) > minQueueLen && q.count*4 == len(q.buf) { q.resize() } } golang-gopkg-eapache-queue.v1-1.0.2/queue_test.go000066400000000000000000000056171253455743700216630ustar00rootroot00000000000000package queue import "testing" func TestQueueSimple(t *testing.T) { q := New() for i := 0; i < minQueueLen; i++ { q.Add(i) } for i := 0; i < minQueueLen; i++ { if q.Peek().(int) != i { t.Error("peek", i, "had value", q.Peek()) } q.Remove() } } func TestQueueWrapping(t *testing.T) { q := New() for i := 0; i < minQueueLen; i++ { q.Add(i) } for i := 0; i < 3; i++ { q.Remove() q.Add(minQueueLen + i) } for i := 0; i < minQueueLen; i++ { if q.Peek().(int) != i+3 { t.Error("peek", i, "had value", q.Peek()) } q.Remove() } } func TestQueueLength(t *testing.T) { q := New() if q.Length() != 0 { t.Error("empty queue length not 0") } for i := 0; i < 1000; i++ { q.Add(i) if q.Length() != i+1 { t.Error("adding: queue with", i, "elements has length", q.Length()) } } for i := 0; i < 1000; i++ { q.Remove() if q.Length() != 1000-i-1 { t.Error("removing: queue with", 1000-i-i, "elements has length", q.Length()) } } } func TestQueueGet(t *testing.T) { q := New() for i := 0; i < 1000; i++ { q.Add(i) for j := 0; j < q.Length(); j++ { if q.Get(j).(int) != j { t.Errorf("index %d doesn't contain %d", j, j) } } } } func TestQueueGetOutOfRangePanics(t *testing.T) { q := New() q.Add(1) q.Add(2) q.Add(3) assertPanics(t, "should panic when negative index", func() { q.Get(-1) }) assertPanics(t, "should panic when index greater than length", func() { q.Get(4) }) } func TestQueuePeekOutOfRangePanics(t *testing.T) { q := New() assertPanics(t, "should panic when peeking empty queue", func() { q.Peek() }) q.Add(1) q.Remove() assertPanics(t, "should panic when peeking emptied queue", func() { q.Peek() }) } func TestQueueRemoveOutOfRangePanics(t *testing.T) { q := New() assertPanics(t, "should panic when removing empty queue", func() { q.Remove() }) q.Add(1) q.Remove() assertPanics(t, "should panic when removing emptied queue", func() { q.Remove() }) } func assertPanics(t *testing.T, name string, f func()) { defer func() { if r := recover(); r == nil { t.Errorf("%s: didn't panic as expected", name) } }() f() } // General warning: Go's benchmark utility (go test -bench .) increases the number of // iterations until the benchmarks take a reasonable amount of time to run; memory usage // is *NOT* considered. On my machine, these benchmarks hit around ~1GB before they've had // enough, but if you have less than that available and start swapping, then all bets are off. func BenchmarkQueueSerial(b *testing.B) { q := New() for i := 0; i < b.N; i++ { q.Add(nil) } for i := 0; i < b.N; i++ { q.Peek() q.Remove() } } func BenchmarkQueueGet(b *testing.B) { q := New() for i := 0; i < b.N; i++ { q.Add(i) } b.ResetTimer() for i := 0; i < b.N; i++ { q.Get(i) } } func BenchmarkQueueTickTock(b *testing.B) { q := New() for i := 0; i < b.N; i++ { q.Add(nil) q.Peek() q.Remove() } }