queue.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright (c) 2013-2017, Peter H. Froehlich. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license
  3. // that can be found in the LICENSE file.
  4. // Package queue implements a double-ended queue (aka "deque") on top of a
  5. // slice. All operations are (amortized) constant time. Benchmarks compare
  6. // favorably to container/list as well as to Go's channels. Not safe for
  7. // concurrent use.
  8. package queue
  9. import (
  10. "bytes"
  11. "fmt"
  12. )
  13. // Queue represents a double-ended queue.
  14. // The zero value is an empty queue ready to use.
  15. type Queue struct {
  16. // PushBack writes to rep[back] then increments back; PushFront
  17. // decrements front then writes to rep[front]; len(rep) is a power
  18. // of two; unused slots are nil and not garbage.
  19. rep []interface{}
  20. front int
  21. back int
  22. length int
  23. }
  24. // New returns an initialized empty queue.
  25. func New() *Queue {
  26. return new(Queue).Init()
  27. }
  28. // Init initializes or clears queue q.
  29. func (q *Queue) Init() *Queue {
  30. q.rep = make([]interface{}, 1)
  31. q.front, q.back, q.length = 0, 0, 0
  32. return q
  33. }
  34. // lazyInit lazily initializes a zero Queue value.
  35. //
  36. // I am mostly doing this because container/list does the same thing.
  37. // Personally I think it's a little wasteful because every single
  38. // PushFront/PushBack is going to pay the overhead of calling this.
  39. // But that's the price for making zero values useful immediately.
  40. func (q *Queue) lazyInit() {
  41. if q.rep == nil {
  42. q.Init()
  43. }
  44. }
  45. // Len returns the number of elements of queue q.
  46. func (q *Queue) Len() int {
  47. return q.length
  48. }
  49. // empty returns true if the queue q has no elements.
  50. func (q *Queue) empty() bool {
  51. return q.length == 0
  52. }
  53. // full returns true if the queue q is at capacity.
  54. func (q *Queue) full() bool {
  55. return q.length == len(q.rep)
  56. }
  57. // sparse returns true if the queue q has excess capacity.
  58. func (q *Queue) sparse() bool {
  59. return 1 < q.length && q.length < len(q.rep)/4
  60. }
  61. // resize adjusts the size of queue q's underlying slice.
  62. func (q *Queue) resize(size int) {
  63. adjusted := make([]interface{}, size)
  64. if q.front < q.back {
  65. // rep not "wrapped" around, one copy suffices
  66. copy(adjusted, q.rep[q.front:q.back])
  67. } else {
  68. // rep is "wrapped" around, need two copies
  69. n := copy(adjusted, q.rep[q.front:])
  70. copy(adjusted[n:], q.rep[:q.back])
  71. }
  72. q.rep = adjusted
  73. q.front = 0
  74. q.back = q.length
  75. }
  76. // lazyGrow grows the underlying slice if necessary.
  77. func (q *Queue) lazyGrow() {
  78. if q.full() {
  79. q.resize(len(q.rep) * 2)
  80. }
  81. }
  82. // lazyShrink shrinks the underlying slice if advisable.
  83. func (q *Queue) lazyShrink() {
  84. if q.sparse() {
  85. q.resize(len(q.rep) / 2)
  86. }
  87. }
  88. // String returns a string representation of queue q formatted
  89. // from front to back.
  90. func (q *Queue) String() string {
  91. var result bytes.Buffer
  92. result.WriteByte('[')
  93. j := q.front
  94. for i := 0; i < q.length; i++ {
  95. result.WriteString(fmt.Sprintf("%v", q.rep[j]))
  96. if i < q.length-1 {
  97. result.WriteByte(' ')
  98. }
  99. j = q.inc(j)
  100. }
  101. result.WriteByte(']')
  102. return result.String()
  103. }
  104. // inc returns the next integer position wrapping around queue q.
  105. func (q *Queue) inc(i int) int {
  106. return (i + 1) & (len(q.rep) - 1) // requires l = 2^n
  107. }
  108. // dec returns the previous integer position wrapping around queue q.
  109. func (q *Queue) dec(i int) int {
  110. return (i - 1) & (len(q.rep) - 1) // requires l = 2^n
  111. }
  112. // Front returns the first element of queue q or nil.
  113. func (q *Queue) Front() interface{} {
  114. // no need to check q.empty(), unused slots are nil
  115. return q.rep[q.front]
  116. }
  117. // Back returns the last element of queue q or nil.
  118. func (q *Queue) Back() interface{} {
  119. // no need to check q.empty(), unused slots are nil
  120. return q.rep[q.dec(q.back)]
  121. }
  122. // PushFront inserts a new value v at the front of queue q.
  123. func (q *Queue) PushFront(v interface{}) {
  124. q.lazyInit()
  125. q.lazyGrow()
  126. q.front = q.dec(q.front)
  127. q.rep[q.front] = v
  128. q.length++
  129. }
  130. // PushBack inserts a new value v at the back of queue q.
  131. func (q *Queue) PushBack(v interface{}) {
  132. q.lazyInit()
  133. q.lazyGrow()
  134. q.rep[q.back] = v
  135. q.back = q.inc(q.back)
  136. q.length++
  137. }
  138. // PopFront removes and returns the first element of queue q or nil.
  139. func (q *Queue) PopFront() interface{} {
  140. if q.empty() {
  141. return nil
  142. }
  143. v := q.rep[q.front]
  144. q.rep[q.front] = nil // unused slots must be nil
  145. q.front = q.inc(q.front)
  146. q.length--
  147. q.lazyShrink()
  148. return v
  149. }
  150. // PopBack removes and returns the last element of queue q or nil.
  151. func (q *Queue) PopBack() interface{} {
  152. if q.empty() {
  153. return nil
  154. }
  155. q.back = q.dec(q.back)
  156. v := q.rep[q.back]
  157. q.rep[q.back] = nil // unused slots must be nil
  158. q.length--
  159. q.lazyShrink()
  160. return v
  161. }