Przeglądaj źródła

Some cleanup and refactoring.

Peter H. Froehlich 12 lat temu
rodzic
commit
cbb87826e6
1 zmienionych plików z 22 dodań i 13 usunięć
  1. 22 13
      queue.go

+ 22 - 13
queue.go

@@ -5,6 +5,10 @@
 // Package queue implements a double-ended queue abstraction on
 // top of a slice/array. All operations are constant time except
 // for PushFront and PushBack which are amortized constant time.
+//
+// We are about 60%-90% faster than container/list would be at
+// the price of potentially wasting some memory because we grow
+// our slice by amortized doubling.
 package queue
 
 import "fmt"
@@ -30,7 +34,7 @@ func New() *Queue {
 func (q *Queue) Init() *Queue {
 	// start with a slice of length 2 even if that "wastes"
 	// some memory; we do front/back arithmetic modulo the
-	// length, so starting at 1 requires special cases
+	// length, so starting at 1 would require special cases
 	q.rep = make([]interface{}, 2)
 	// for some time I considered reusing the existing slice
 	// if all a client does is re-initialize the queue; the
@@ -86,10 +90,16 @@ func (q *Queue) grow() {
 	q.back = q.length
 }
 
-// TODO: leave this in or not?
+// lazyGrow grows the underlying slice/array if necessary.
+func (q *Queue) lazyGrow() {
+	if q.full() {
+		q.grow()
+	}
+}
 
+// String returns a string representation of queue q formatted
+// from front to back.
 func (q *Queue) String() string {
-	//	result := fmt.Sprintf("(f: %d b: %d l:%d c:%d)", q.front, q.back, q.length, len(q.rep))
 	result := ""
 	result = result + "["
 	j := q.front
@@ -135,10 +145,8 @@ func (q *Queue) Back() interface{} {
 
 // PushFront inserts a new value v at the front of queue q.
 func (q *Queue) PushFront(v interface{}) {
-	q.lazyInit() // TODO: keep?
-	if q.full() {
-		q.grow()
-	}
+	q.lazyInit()
+	q.lazyGrow()
 	q.front = q.dec(q.front)
 	q.rep[q.front] = v
 	q.length++
@@ -146,22 +154,23 @@ func (q *Queue) PushFront(v interface{}) {
 
 // PushBack inserts a new value v at the back of queue q.
 func (q *Queue) PushBack(v interface{}) {
-	q.lazyInit() // TODO: keep?
-	if q.full() {
-		q.grow()
-	}
+	q.lazyInit()
+	q.lazyGrow()
 	q.rep[q.back] = v
 	q.back = q.inc(q.back)
 	q.length++
 }
 
+// Both PopFront and PopBack set the newly free slot to nil
+// in an attempt to be nice to the garbage collector.
+
 // PopFront removes and returns the first element of queue q or nil.
 func (q *Queue) PopFront() interface{} {
 	if q.empty() {
 		return nil
 	}
 	v := q.rep[q.front]
-	q.rep[q.front] = nil // nice to GC?
+	q.rep[q.front] = nil
 	q.front = q.inc(q.front)
 	q.length--
 	return v
@@ -174,7 +183,7 @@ func (q *Queue) PopBack() interface{} {
 	}
 	q.back = q.dec(q.back)
 	v := q.rep[q.back]
-	q.rep[q.back] = nil // nice to GC?
+	q.rep[q.back] = nil
 	q.length--
 	return v
 }