queue.go 4.4 KB

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