|
5 | 5 | "sync" |
6 | 6 | ) |
7 | 7 |
|
8 | | -// Ensure Priority implements the Queue interface. |
| 8 | +// Ensure Circular implements the Queue interface. |
9 | 9 | var _ Queue[any] = (*Circular[any])(nil) |
10 | 10 |
|
11 | 11 | // Circular is a Queue implementation. |
@@ -189,18 +189,29 @@ func (q *Circular[T]) Contains(elem T) bool { |
189 | 189 | defer q.lock.RUnlock() |
190 | 190 |
|
191 | 191 | if q.isEmpty() { |
192 | | - return false // queue is empty, item not found |
| 192 | + return false |
193 | 193 | } |
194 | 194 |
|
195 | | - for i := 0; i < q.size; i++ { |
196 | | - idx := (q.head + i) % len(q.elems) |
| 195 | + // Walk head..end, then wrap to 0..tail. Avoids a modulo per |
| 196 | + // iteration in the hot path. |
| 197 | + firstChunk := len(q.elems) - q.head |
| 198 | + if firstChunk > q.size { |
| 199 | + firstChunk = q.size |
| 200 | + } |
197 | 201 |
|
198 | | - if q.elems[idx] == elem { |
199 | | - return true // item found |
| 202 | + for i := 0; i < firstChunk; i++ { |
| 203 | + if q.elems[q.head+i] == elem { |
| 204 | + return true |
200 | 205 | } |
201 | 206 | } |
202 | 207 |
|
203 | | - return false // item not found |
| 208 | + for i := 0; i < q.size-firstChunk; i++ { |
| 209 | + if q.elems[i] == elem { |
| 210 | + return true |
| 211 | + } |
| 212 | + } |
| 213 | + |
| 214 | + return false |
204 | 215 | } |
205 | 216 |
|
206 | 217 | // Peek returns the element at the head of the queue. |
@@ -274,14 +285,18 @@ func (q *Circular[T]) MarshalJSON() ([]byte, error) { |
274 | 285 | return []byte("[]"), nil |
275 | 286 | } |
276 | 287 |
|
277 | | - // Collect elements in logical order from head to tail. |
| 288 | + // Collect elements in logical order: head..end of array, then |
| 289 | + // wrap to 0..tail. Two contiguous copies, no per-element modulo. |
278 | 290 | elements := make([]T, q.size) |
279 | 291 |
|
280 | | - for i := 0; i < q.size; i++ { |
281 | | - index := (q.head + i) % len(q.elems) |
282 | | - elements[i] = q.elems[index] |
| 292 | + firstChunk := len(q.elems) - q.head |
| 293 | + if firstChunk > q.size { |
| 294 | + firstChunk = q.size |
283 | 295 | } |
284 | 296 |
|
| 297 | + copy(elements, q.elems[q.head:q.head+firstChunk]) |
| 298 | + copy(elements[firstChunk:], q.elems[:q.size-firstChunk]) |
| 299 | + |
285 | 300 | q.lock.RUnlock() |
286 | 301 |
|
287 | 302 | return json.Marshal(elements) |
|
0 commit comments