ring.go 912 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. package collection
  2. import "sync"
  3. // A Ring can be used as fixed size ring.
  4. type Ring struct {
  5. elements []interface{}
  6. index int
  7. lock sync.Mutex
  8. }
  9. // NewRing returns a Ring object with the given size n.
  10. func NewRing(n int) *Ring {
  11. if n < 1 {
  12. panic("n should be greater than 0")
  13. }
  14. return &Ring{
  15. elements: make([]interface{}, n),
  16. }
  17. }
  18. // Add adds v into r.
  19. func (r *Ring) Add(v interface{}) {
  20. r.lock.Lock()
  21. defer r.lock.Unlock()
  22. r.elements[r.index%len(r.elements)] = v
  23. r.index++
  24. }
  25. // Take takes all items from r.
  26. func (r *Ring) Take() []interface{} {
  27. r.lock.Lock()
  28. defer r.lock.Unlock()
  29. var size int
  30. var start int
  31. if r.index > len(r.elements) {
  32. size = len(r.elements)
  33. start = r.index % len(r.elements)
  34. } else {
  35. size = r.index
  36. }
  37. elements := make([]interface{}, size)
  38. for i := 0; i < size; i++ {
  39. elements[i] = r.elements[(start+i)%len(r.elements)]
  40. }
  41. return elements
  42. }