diff options
Diffstat (limited to 'vendor/github.com/zfjagann/golang-ring/ring.go')
-rw-r--r-- | vendor/github.com/zfjagann/golang-ring/ring.go | 65 |
1 files changed, 55 insertions, 10 deletions
diff --git a/vendor/github.com/zfjagann/golang-ring/ring.go b/vendor/github.com/zfjagann/golang-ring/ring.go index 2214c4ba..6d2a7e24 100644 --- a/vendor/github.com/zfjagann/golang-ring/ring.go +++ b/vendor/github.com/zfjagann/golang-ring/ring.go @@ -3,6 +3,8 @@ Package ring provides a simple implementation of a ring buffer. */ package ring +import "sync" + /* The DefaultCapacity of an uninitialized Ring buffer. @@ -15,6 +17,7 @@ Type Ring implements a Circular Buffer. The default value of the Ring struct is a valid (empty) Ring buffer with capacity DefaultCapacify. */ type Ring struct { + sync.Mutex head int // the most recent value written tail int // the least recent value written buff []interface{} @@ -24,6 +27,9 @@ type Ring struct { Set the maximum size of the ring buffer. */ func (r *Ring) SetCapacity(size int) { + r.Lock() + defer r.Unlock() + r.checkInit() r.extend(size) } @@ -31,14 +37,38 @@ func (r *Ring) SetCapacity(size int) { /* Capacity returns the current capacity of the ring buffer. */ -func (r Ring) Capacity() int { - return len(r.buff) +func (r *Ring) Capacity() int { + r.Lock() + defer r.Unlock() + + return r.capacity() +} + +/* +ContentSize returns the current number of elements inside the ring buffer. +*/ +func (r *Ring) ContentSize() int { + r.Lock() + defer r.Unlock() + + if r.head == -1 { + return 0 + } else { + difference := (r.head - r.tail) + if difference < 0 { + difference = -difference + } + return difference + 1 + } } /* Enqueue a value into the Ring buffer. */ func (r *Ring) Enqueue(i interface{}) { + r.Lock() + defer r.Unlock() + r.checkInit() r.set(r.head+1, i) old := r.head @@ -54,6 +84,9 @@ Dequeue a value from the Ring buffer. Returns nil if the ring buffer is empty. */ func (r *Ring) Dequeue() interface{} { + r.Lock() + defer r.Unlock() + r.checkInit() if r.head == -1 { return nil @@ -74,6 +107,9 @@ Read the value that Dequeue would have dequeued without actually dequeuing it. Returns nil if the ring buffer is empty. */ func (r *Ring) Peek() interface{} { + r.Lock() + defer r.Unlock() + r.checkInit() if r.head == -1 { return nil @@ -87,11 +123,14 @@ The returned slice can be modified independently of the circular buffer. However are shared between the slice and circular buffer. */ func (r *Ring) Values() []interface{} { + r.Lock() + defer r.Unlock() + if r.head == -1 { return []interface{}{} } - arr := make([]interface{}, 0, r.Capacity()) - for i := 0; i < r.Capacity(); i++ { + arr := make([]interface{}, 0, r.capacity()) + for i := 0; i < r.capacity(); i++ { idx := r.mod(i + r.tail) arr = append(arr, r.get(idx)) if idx == r.head { @@ -105,6 +144,10 @@ func (r *Ring) Values() []interface{} { *** Unexported methods beyond this point. **/ +func (r *Ring) capacity() int { + return len(r.buff) +} + // sets a value at the given unmodified index and returns the modified index of the value func (r *Ring) set(p int, v interface{}) { r.buff[r.mod(p)] = v @@ -121,13 +164,15 @@ func (r *Ring) mod(p int) int { } func (r *Ring) checkInit() { - if r.buff == nil { - r.buff = make([]interface{}, DefaultCapacity) - for i := range r.buff { - r.buff[i] = nil - } - r.head, r.tail = -1, 0 + if r.buff != nil { + return + } + + r.buff = make([]interface{}, DefaultCapacity) + for i := range r.buff { + r.buff[i] = nil } + r.head, r.tail = -1, 0 } func (r *Ring) extend(size int) { |