Skip to content

Commit 5652cbe

Browse files
committed
Updated copyright and commentary, now uses copy() builtin.
1 parent f6832ca commit 5652cbe

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

queue/queue.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
// Copyright (c) 2013, Peter H. Froehlich. All rights reserved.
1+
// Copyright (c) 2013-2017, Peter H. Froehlich. All rights reserved.
22
// Use of this source code is governed by a BSD-style license
33
// that can be found in the LICENSE file.
44

55
// Package queue implements a double-ended queue abstraction on
66
// top of a slice/array. All operations are constant time except
77
// for PushFront and PushBack which are amortized constant time.
88
//
9-
// We are about 60%-90% faster than container/list would be at
10-
// the price of potentially wasting some memory because we grow
11-
// our slice by amortized doubling.
9+
// We are about 15%-45% faster than container/list at the price
10+
// of potentially wasting some memory because we grow by doubling.
11+
// We seem to even beat Go's channels by a small margin.
1212
package queue
1313

1414
import "fmt"
@@ -55,7 +55,7 @@ func (q *Queue) Init() *Queue {
5555
// Personally I think it's a little wasteful because every single
5656
// PushFront/PushBack is going to pay the overhead of calling this.
5757
// But that's the price for making zero values useful immediately,
58-
// something Go apparently likes a lot.
58+
// something Go folks apparently like a lot.
5959
func (q *Queue) lazyInit() {
6060
if q.rep == nil {
6161
q.Init()
@@ -79,13 +79,17 @@ func (q *Queue) full() bool {
7979

8080
// grow doubles the size of queue q's underlying slice/array.
8181
func (q *Queue) grow() {
82-
big := make([]interface{}, q.length*2)
83-
j := q.front
84-
for i := 0; i < q.length; i++ {
85-
big[i] = q.rep[j]
86-
j = q.inc(j)
87-
}
88-
q.rep = big
82+
bigger := make([]interface{}, q.length*2)
83+
// Kudos to Rodrigo Moraes, see https://gist.github.com/moraes/2141121
84+
copy(bigger, q.rep[q.front:])
85+
copy(bigger[q.length-q.front:], q.rep[:q.front])
86+
// The above replaced the "obvious" for loop and is a bit tricky.
87+
// First note that q.front == q.back if we're full; if that wasn't
88+
// true, things would be more complicated. Second recall that for
89+
// a slice [lo:hi] the lo bound is inclusive whereas the hi bound
90+
// is exclusive. If that doesn't convince you that the above works
91+
// maybe drawing out some pictures for a concrete example will?
92+
q.rep = bigger
8993
q.front = 0
9094
q.back = q.length
9195
}

0 commit comments

Comments
 (0)