diff options
author | David Symonds <dsymonds@golang.org> | 2009-08-31 14:43:27 -0700 |
---|---|---|
committer | David Symonds <dsymonds@golang.org> | 2009-08-31 14:43:27 -0700 |
commit | 95fed509a66e8655e8bcaf780cfdd95dc9a2864b (patch) | |
tree | a1cf307c042f2b2fb2497b3f6a4debc0be9f8862 | |
parent | 363ea3df345b3421a1cafcaf3496b5163e82b59d (diff) | |
download | golang-95fed509a66e8655e8bcaf780cfdd95dc9a2864b.tar.gz |
Consistency changes to container/* packages for iteration.
container/list:
- change Iter to go over the list values
container/ring:
- add Iter, drop Forward/Backward
container/vector:
- add channel direction constraints
R=rsc,gri
APPROVED=rsc
DELTA=86 (23 added, 40 deleted, 23 changed)
OCL=33935
CL=34132
-rwxr-xr-x | src/pkg/container/list/list.go | 23 | ||||
-rwxr-xr-x | src/pkg/container/list/list_test.go | 15 | ||||
-rw-r--r-- | src/pkg/container/ring/ring.go | 31 | ||||
-rw-r--r-- | src/pkg/container/ring/ring_test.go | 28 | ||||
-rw-r--r-- | src/pkg/container/vector/intvector.go | 4 | ||||
-rw-r--r-- | src/pkg/container/vector/stringvector.go | 4 | ||||
-rw-r--r-- | src/pkg/container/vector/vector.go | 4 |
7 files changed, 46 insertions, 63 deletions
diff --git a/src/pkg/container/list/list.go b/src/pkg/container/list/list.go index 3b77ced59..64000e463 100755 --- a/src/pkg/container/list/list.go +++ b/src/pkg/container/list/list.go @@ -18,6 +18,16 @@ type Element struct { Value interface {}; } +// Next returns the next list element or nil. +func (e *Element) Next() *Element { + return e.next +} + +// Prev returns the previous list element or nil. +func (e *Element) Prev() *Element { + return e.prev +} + // List represents a doubly linked list. type List struct { front, back *Element; @@ -181,18 +191,15 @@ func (l *List) Len() int { return l.len } -func (l *List) iterate(c chan <- *Element) { - var next *Element; - for e := l.front; e != nil; e = next { - // Save next in case reader of c changes e. - next = e.next; - c <- e; +func (l *List) iterate(c chan<- interface {}) { + for e := l.front; e != nil; e = e.next { + c <- e.Value; } close(c); } -func (l *List) Iter() <-chan *Element { - c := make(chan *Element); +func (l *List) Iter() <-chan interface {} { + c := make(chan interface {}); go l.iterate(c); return c } diff --git a/src/pkg/container/list/list_test.go b/src/pkg/container/list/list_test.go index 4a291e918..741aa5516 100755 --- a/src/pkg/container/list/list_test.go +++ b/src/pkg/container/list/list_test.go @@ -114,8 +114,21 @@ func TestList(t *testing.T) { checkListPointers(t, l, []*Element{ e1, e4, e3, e2 }); l.Remove(e2); - // Clear all elements by iterating + // Check standard iteration. + sum := 0; for e := range l.Iter() { + if i, ok := e.(int); ok { + sum += i; + } + } + if sum != 4 { + t.Errorf("sum over l.Iter() = %d, want 4", sum); + } + + // Clear all elements by iterating + var next *Element; + for e := l.Front(); e != nil; e = next { + next = e.Next(); l.Remove(e); } checkListPointers(t, l, []*Element{}); diff --git a/src/pkg/container/ring/ring.go b/src/pkg/container/ring/ring.go index 0cd41cb41..fc1aef96d 100644 --- a/src/pkg/container/ring/ring.go +++ b/src/pkg/container/ring/ring.go @@ -138,37 +138,16 @@ func (r *Ring) Len() int { } -// Forward returns a channel for forward iteration through a ring. -// Iteration is undefined if the ring is changed during iteration. -// -func (r *Ring) Forward() <-chan *Ring { - c := make(chan *Ring); +func (r *Ring) Iter() <-chan interface {} { + c := make(chan interface {}); go func() { if r != nil { - c <- r; + c <- r.Value; for p := r.Next(); p != r; p = p.next { - c <- p; - } - } - close(c); - }(); - return c; -} - - -// Backward returns a channel for backward iteration through a ring. -// Iteration is undefined if the ring is changed during iteration. -// -func (r *Ring) Backward() <-chan *Ring { - c := make(chan *Ring); - go func() { - if r != nil { - c <- r; - for p := r.Prev(); p != r; p = p.prev { - c <- p; + c <- p.Value; } } close(c); }(); - return c; + return c } diff --git a/src/pkg/container/ring/ring_test.go b/src/pkg/container/ring/ring_test.go index 8ecbacd14..4f81d55aa 100644 --- a/src/pkg/container/ring/ring_test.go +++ b/src/pkg/container/ring/ring_test.go @@ -32,13 +32,13 @@ func verify(t *testing.T, r *Ring, N int, sum int) { t.Errorf("r.Len() == %d; expected %d", n, N); } - // forward iteration + // iteration n = 0; s := 0; - for p := range r.Forward() { + for p := range r.Iter() { n++; - if p.Value != nil { - s += p.Value.(int); + if p != nil { + s += p.(int); } } if n != N { @@ -48,22 +48,6 @@ func verify(t *testing.T, r *Ring, N int, sum int) { t.Errorf("forward ring sum = %d; expected %d", s, sum); } - // backward iteration - n = 0; - s = 0; - for p := range r.Backward() { - n++; - if p.Value != nil { - s += p.Value.(int); - } - } - if n != N { - t.Errorf("number of backward iterations == %d; expected %d", n, N); - } - if sum >= 0 && s != sum { - t.Errorf("backward ring sum = %d; expected %d", s, sum); - } - if r == nil { return; } @@ -147,8 +131,8 @@ func makeN(n int) *Ring { func sum(r *Ring) int { s := 0; - for p := range r.Forward() { - s += p.Value.(int); + for p := range r.Iter() { + s += p.(int); } return s; } diff --git a/src/pkg/container/vector/intvector.go b/src/pkg/container/vector/intvector.go index f599ce185..076f9982d 100644 --- a/src/pkg/container/vector/intvector.go +++ b/src/pkg/container/vector/intvector.go @@ -101,7 +101,7 @@ func (p *IntVector) Less(i, j int) bool { // Iterate over all elements; driver for range -func (p *IntVector) iterate(c chan int) { +func (p *IntVector) iterate(c chan<- int) { for i, v := range p.a { c <- v.(int) } @@ -110,7 +110,7 @@ func (p *IntVector) iterate(c chan int) { // Channel iterator for range. -func (p *IntVector) Iter() chan int { +func (p *IntVector) Iter() <-chan int { c := make(chan int); go p.iterate(c); return c; diff --git a/src/pkg/container/vector/stringvector.go b/src/pkg/container/vector/stringvector.go index 4f6d74e29..2ead95c70 100644 --- a/src/pkg/container/vector/stringvector.go +++ b/src/pkg/container/vector/stringvector.go @@ -100,7 +100,7 @@ func (p *StringVector) Less(i, j int) bool { // Iterate over all elements; driver for range -func (p *StringVector) iterate(c chan string) { +func (p *StringVector) iterate(c chan<- string) { for i, v := range p.a { c <- v.(string) } @@ -109,7 +109,7 @@ func (p *StringVector) iterate(c chan string) { // Channel iterator for range. -func (p *StringVector) Iter() chan string { +func (p *StringVector) Iter() <-chan string { c := make(chan string); go p.iterate(c); return c; diff --git a/src/pkg/container/vector/vector.go b/src/pkg/container/vector/vector.go index 5b5cad21c..ba5e881d1 100644 --- a/src/pkg/container/vector/vector.go +++ b/src/pkg/container/vector/vector.go @@ -228,7 +228,7 @@ func (p *Vector) Swap(i, j int) { // Iterate over all elements; driver for range -func (p *Vector) iterate(c chan Element) { +func (p *Vector) iterate(c chan<- Element) { for i, v := range p.a { c <- v } @@ -237,7 +237,7 @@ func (p *Vector) iterate(c chan Element) { // Channel iterator for range. -func (p *Vector) Iter() chan Element { +func (p *Vector) Iter() <-chan Element { c := make(chan Element); go p.iterate(c); return c; |