fifo.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package collection
  2. import "sync"
  3. // A Queue is a FIFO queue.
  4. type Queue struct {
  5. lock sync.Mutex
  6. elements []interface{}
  7. size int
  8. head int
  9. tail int
  10. count int
  11. }
  12. // NewQueue returns a Queue object.
  13. func NewQueue(size int) *Queue {
  14. return &Queue{
  15. elements: make([]interface{}, size),
  16. size: size,
  17. }
  18. }
  19. // Empty checks if q is empty.
  20. func (q *Queue) Empty() bool {
  21. q.lock.Lock()
  22. empty := q.count == 0
  23. q.lock.Unlock()
  24. return empty
  25. }
  26. // Put puts element into q at the last position.
  27. func (q *Queue) Put(element interface{}) {
  28. q.lock.Lock()
  29. defer q.lock.Unlock()
  30. if q.head == q.tail && q.count > 0 {
  31. nodes := make([]interface{}, len(q.elements)+q.size)
  32. copy(nodes, q.elements[q.head:])
  33. copy(nodes[len(q.elements)-q.head:], q.elements[:q.head])
  34. q.head = 0
  35. q.tail = len(q.elements)
  36. q.elements = nodes
  37. }
  38. q.elements[q.tail] = element
  39. q.tail = (q.tail + 1) % len(q.elements)
  40. q.count++
  41. }
  42. // Take takes the first element out of q if not empty.
  43. func (q *Queue) Take() (interface{}, bool) {
  44. q.lock.Lock()
  45. defer q.lock.Unlock()
  46. if q.count == 0 {
  47. return nil, false
  48. }
  49. element := q.elements[q.head]
  50. q.head = (q.head + 1) % len(q.elements)
  51. q.count--
  52. return element, true
  53. }