Commit 8c7d0016 authored by Robert Griesemer's avatar Robert Griesemer

Replace container/vector with exp/vector (faster).

Manual changes to the following files:
src/pkg/Makefile
src/pkg/exp/vector/Makefile (now: src/pkg/container/vector/Makefile)

R=rsc, r
CC=golang-dev
https://golang.org/cl/181041
parent 36d645f5
...@@ -57,7 +57,6 @@ DIRS=\ ...@@ -57,7 +57,6 @@ DIRS=\
exp/exception\ exp/exception\
exp/iterable\ exp/iterable\
exp/parser\ exp/parser\
exp/vector\
expvar\ expvar\
flag\ flag\
fmt\ fmt\
......
...@@ -6,8 +6,67 @@ include ../../../Make.$(GOARCH) ...@@ -6,8 +6,67 @@ include ../../../Make.$(GOARCH)
TARG=container/vector TARG=container/vector
GOFILES=\ GOFILES=\
defs.go\
intvector.go\ intvector.go\
stringvector.go\ stringvector.go\
vector.go\ vector.go\
generate: vector.go vector_test.go
< vector.go cat\
| gofmt -r='Vector -> IntVector'\
| gofmt -r='interface{} -> int'\
> intvector.go\
< vector.go cat\
| gofmt -r='Vector -> StringVector'\
| gofmt -r='interface{} -> string'\
> stringvector.go\
< vector_test.go cat\
| gofmt -r='Vector -> IntVector'\
| gofmt -r='zero -> intzero'\
| gofmt -r='elem2Value -> elem2IntValue'\
| gofmt -r='intf2Value -> intf2IntValue'\
| gofmt -r='int2Value -> int2IntValue'\
| gofmt -r='TestZeroLenExp -> TestIntZeroLenExp'\
| gofmt -r='TestResizeExp -> TestIntResizeExp'\
| gofmt -r='TestResize2Exp -> TestIntResize2Exp'\
| gofmt -r='checkZeroExp -> checkIntZeroExp'\
| gofmt -r='TestTrailingElementsExp -> TestIntTrailingElementsExp'\
| gofmt -r='TestAccessExp -> TestIntAccessExp'\
| gofmt -r='TestInsertDeleteClearExp -> TestIntInsertDeleteClearExp'\
| gofmt -r='verify_sliceExp -> verify_sliceIntExp'\
| gofmt -r='verify_patternExp -> verify_patternIntExp'\
| gofmt -r='make_vectorExp -> make_vectorIntExp'\
| gofmt -r='TestInsertVectorExp -> TestIntInsertVectorExp'\
| gofmt -r='TestDoExp -> TestIntDoExp'\
| gofmt -r='TestIterExp -> TestIntIterExp'\
| gofmt -r='TestVectorData -> TestIntVectorData'\
> intvector_test.go\
< vector_test.go cat\
| gofmt -r='Vector -> StringVector'\
| gofmt -r='zero -> strzero'\
| gofmt -r='int2Value -> int2StrValue'\
| gofmt -r='intf2Value -> intf2StrValue'\
| gofmt -r='elem2Value -> elem2StrValue'\
| gofmt -r='TestZeroLenExp -> TestStrZeroLenExp'\
| gofmt -r='TestResizeExp -> TestStrResizeExp'\
| gofmt -r='TestResize2Exp -> TestStrResize2Exp'\
| gofmt -r='checkZeroExp -> checkStrZeroExp'\
| gofmt -r='TestTrailingElementsExp -> TestStrTrailingElementsExp'\
| gofmt -r='TestAccessExp -> TestStrAccessExp'\
| gofmt -r='TestInsertDeleteClearExp -> TestStrInsertDeleteClearExp'\
| gofmt -r='verify_sliceExp -> verify_sliceStrExp'\
| gofmt -r='verify_patternExp -> verify_patternStrExp'\
| gofmt -r='make_vectorExp -> make_vectorStrExp'\
| gofmt -r='TestInsertVectorExp -> TestStrInsertVectorExp'\
| gofmt -r='TestDoExp -> TestStrDoExp'\
| gofmt -r='TestIterExp -> TestStrIterExp'\
| gofmt -r='TestVectorData -> TestStrVectorData'\
> stringvector_test.go
bench:
gotest -v -match Nums -benchmarks Nums
include ../../../Make.pkg include ../../../Make.pkg
...@@ -2,94 +2,206 @@ ...@@ -2,94 +2,206 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// CAUTION: If this file is not vector.go, it was generated
// automatically from vector.go - DO NOT EDIT in that case!
package vector package vector
// IntVector is a specialization of Vector that hides the wrapping of Elements around ints. func (p *IntVector) realloc(length, capacity int) (b []int) {
type IntVector struct { if capacity < initialSize {
Vector capacity = initialSize
}
b = make(IntVector, length, capacity)
copy(b, *p)
*p = b
return
}
// Insert n elements at position i.
func (p *IntVector) Expand(i, n int) {
a := *p
// make sure we have enough space
len0 := len(a)
len1 := len0 + n
if len1 <= cap(a) {
// enough space - just expand
a = a[0:len1]
} else {
// not enough space - double capacity
capb := cap(a) * 2
if capb < len1 {
// still not enough - use required length
capb = len1
}
// capb >= len1
a = p.realloc(len1, capb)
}
// make a hole
for j := len0 - 1; j >= i; j-- {
a[j+n] = a[j]
}
*p = a
} }
// Insert n elements at the end of a vector.
func (p *IntVector) Extend(n int) { p.Expand(len(*p), n) }
// Resize changes the length and capacity of a vector. // Resize changes the length and capacity of a vector.
// If the new length is shorter than the current length, Resize discards // If the new length is shorter than the current length, Resize discards
// trailing elements. If the new length is longer than the current length, // trailing elements. If the new length is longer than the current length,
// Resize adds 0 elements. The capacity parameter is ignored unless the // Resize adds the respective zero values for the additional elements. The capacity
// new length or capacity is longer that the current capacity. // parameter is ignored unless the new length or capacity is longer than the current
// capacity. The resized vector's capacity may be larger than the requested capacity.
func (p *IntVector) Resize(length, capacity int) *IntVector { func (p *IntVector) Resize(length, capacity int) *IntVector {
i := p.Len() a := *p
p.Vector.Resize(length, capacity)
for a := p.a; i < len(a); i++ { if length > cap(a) || capacity > cap(a) {
a[i] = 0 // not enough space or larger capacity requested explicitly
a = p.realloc(length, capacity)
} else if length < len(a) {
// clear trailing elements
for i := range a[length:] {
var zero int
a[length+i] = zero
}
} }
*p = a[0:length]
return p return p
} }
// Len returns the number of elements in the vector.
// Same as len(*p).
func (p *IntVector) Len() int { return len(*p) }
// Cap returns the capacity of the vector; that is, the
// maximum length the vector can grow without resizing.
// Same as cap(*p).
func (p *IntVector) Cap() int { return cap(*p) }
// At returns the i'th element of the vector. // At returns the i'th element of the vector.
func (p *IntVector) At(i int) int { return p.Vector.At(i).(int) } func (p *IntVector) At(i int) int { return (*p)[i] }
// Set sets the i'th element of the vector to value x. // Set sets the i'th element of the vector to value x.
func (p *IntVector) Set(i int, x int) { p.a[i] = x } func (p *IntVector) Set(i int, x int) { (*p)[i] = x }
// Last returns the element in the vector of highest index. // Last returns the element in the vector of highest index.
func (p *IntVector) Last() int { return p.Vector.Last().(int) } func (p *IntVector) Last() int { return (*p)[len(*p)-1] }
// Data returns all the elements as a slice. // Data returns all the elements as a slice.
func (p *IntVector) Data() []int { func (p *IntVector) Data() []int {
arr := make([]int, p.Len()) arr := make(IntVector, len(*p))
for i, v := range p.a { copy(arr, *p)
arr[i] = v.(int)
}
return arr return arr
} }
// Insert inserts into the vector an element of value x before // Insert inserts into the vector an element of value x before
// the current element at index i. // the current element at index i.
func (p *IntVector) Insert(i int, x int) { p.Vector.Insert(i, x) } func (p *IntVector) Insert(i int, x int) {
p.Expand(i, 1)
(*p)[i] = x
}
// Delete deletes the i'th element of the vector. The gap is closed so the old
// element at index i+1 has index i afterwards.
func (p *IntVector) Delete(i int) {
a := *p
n := len(a)
copy(a[i:n-1], a[i+1:n])
var zero int
a[n-1] = zero // support GC, zero out entry
*p = a[0 : n-1]
}
// InsertVector inserts into the vector the contents of the Vector // InsertVector inserts into the vector the contents of the vector
// x such that the 0th element of x appears at index i after insertion. // x such that the 0th element of x appears at index i after insertion.
func (p *IntVector) InsertVector(i int, x *IntVector) { func (p *IntVector) InsertVector(i int, x *IntVector) {
p.Vector.InsertVector(i, &x.Vector) b := *x
p.Expand(i, len(b))
copy((*p)[i:i+len(b)], b)
}
// Cut deletes elements i through j-1, inclusive.
func (p *IntVector) Cut(i, j int) {
a := *p
n := len(a)
m := n - (j - i)
copy(a[i:m], a[j:n])
for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector.
var zero int
a[k] = zero // support GC, zero out entries
}
*p = a[0:m]
} }
// Slice returns a new IntVector by slicing the old one to extract slice [i:j]. // Slice returns a new sub-vector by slicing the old one to extract slice [i:j].
// The elements are copied. The original vector is unchanged. // The elements are copied. The original vector is unchanged.
func (p *IntVector) Slice(i, j int) *IntVector { func (p *IntVector) Slice(i, j int) *IntVector {
return &IntVector{*p.Vector.Slice(i, j)} var s IntVector
s.realloc(j-i, 0) // will fail in Init() if j < i
copy(s, (*p)[i:j])
return &s
} }
// Convenience wrappers
// Push appends x to the end of the vector. // Push appends x to the end of the vector.
func (p *IntVector) Push(x int) { p.Vector.Push(x) } func (p *IntVector) Push(x int) { p.Insert(len(*p), x) }
// Pop deletes the last element of the vector.
func (p *IntVector) Pop() int {
a := *p
// Pop deletes and returns the last element of the vector. i := len(a) - 1
func (p *IntVector) Pop() int { return p.Vector.Pop().(int) } x := a[i]
var zero int
a[i] = zero // support GC, zero out entry
*p = a[0:i]
return x
}
// AppendVector appends the entire IntVector x to the end of this vector. // AppendVector appends the entire vector x to the end of this vector.
func (p *IntVector) AppendVector(x *IntVector) { func (p *IntVector) AppendVector(x *IntVector) {
p.Vector.InsertVector(len(p.a), &x.Vector) p.InsertVector(len(*p), x)
} }
// sort.Interface support // Swap exchanges the elements at indexes i and j.
// Less returns a boolean denoting whether the i'th element is less than the j'th element. func (p *IntVector) Swap(i, j int) {
func (p *IntVector) Less(i, j int) bool { return p.At(i) < p.At(j) } a := *p
a[i], a[j] = a[j], a[i]
}
// Iterate over all elements; driver for range // Iterate over all elements; driver for range
func (p *IntVector) iterate(c chan<- int) { func (p *IntVector) iterate(c chan<- int) {
for _, v := range p.a { for _, v := range *p {
c <- v.(int) c <- v
} }
close(c) close(c)
} }
......
...@@ -2,47 +2,109 @@ ...@@ -2,47 +2,109 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// CAUTION: If this file is not vector.go, it was generated
// automatically from vector.go - DO NOT EDIT in that case!
package vector package vector
// StringVector is a specialization of Vector that hides the wrapping of Elements around strings.
type StringVector struct { func (p *StringVector) realloc(length, capacity int) (b []string) {
Vector if capacity < initialSize {
capacity = initialSize
}
b = make(StringVector, length, capacity)
copy(b, *p)
*p = b
return
} }
// Insert n elements at position i.
func (p *StringVector) Expand(i, n int) {
a := *p
// make sure we have enough space
len0 := len(a)
len1 := len0 + n
if len1 <= cap(a) {
// enough space - just expand
a = a[0:len1]
} else {
// not enough space - double capacity
capb := cap(a) * 2
if capb < len1 {
// still not enough - use required length
capb = len1
}
// capb >= len1
a = p.realloc(len1, capb)
}
// make a hole
for j := len0 - 1; j >= i; j-- {
a[j+n] = a[j]
}
*p = a
}
// Insert n elements at the end of a vector.
func (p *StringVector) Extend(n int) { p.Expand(len(*p), n) }
// Resize changes the length and capacity of a vector. // Resize changes the length and capacity of a vector.
// If the new length is shorter than the current length, Resize discards // If the new length is shorter than the current length, Resize discards
// trailing elements. If the new length is longer than the current length, // trailing elements. If the new length is longer than the current length,
// Resize adds "" elements. The capacity parameter is ignored unless the // Resize adds the respective zero values for the additional elements. The capacity
// new length or capacity is longer that the current capacity. // parameter is ignored unless the new length or capacity is longer than the current
// capacity. The resized vector's capacity may be larger than the requested capacity.
func (p *StringVector) Resize(length, capacity int) *StringVector { func (p *StringVector) Resize(length, capacity int) *StringVector {
i := p.Len() a := *p
p.Vector.Resize(length, capacity)
for a := p.a; i < len(a); i++ { if length > cap(a) || capacity > cap(a) {
a[i] = "" // not enough space or larger capacity requested explicitly
a = p.realloc(length, capacity)
} else if length < len(a) {
// clear trailing elements
for i := range a[length:] {
var zero string
a[length+i] = zero
}
} }
*p = a[0:length]
return p return p
} }
// Len returns the number of elements in the vector.
// Same as len(*p).
func (p *StringVector) Len() int { return len(*p) }
// Cap returns the capacity of the vector; that is, the
// maximum length the vector can grow without resizing.
// Same as cap(*p).
func (p *StringVector) Cap() int { return cap(*p) }
// At returns the i'th element of the vector. // At returns the i'th element of the vector.
func (p *StringVector) At(i int) string { return p.Vector.At(i).(string) } func (p *StringVector) At(i int) string { return (*p)[i] }
// Set sets the i'th element of the vector to value x. // Set sets the i'th element of the vector to value x.
func (p *StringVector) Set(i int, x string) { p.a[i] = x } func (p *StringVector) Set(i int, x string) { (*p)[i] = x }
// Last returns the element in the vector of highest index. // Last returns the element in the vector of highest index.
func (p *StringVector) Last() string { return p.Vector.Last().(string) } func (p *StringVector) Last() string { return (*p)[len(*p)-1] }
// Data returns all the elements as a slice. // Data returns all the elements as a slice.
func (p *StringVector) Data() []string { func (p *StringVector) Data() []string {
arr := make([]string, p.Len()) arr := make(StringVector, len(*p))
for i, v := range p.a { copy(arr, *p)
arr[i] = v.(string)
}
return arr return arr
} }
...@@ -50,47 +112,96 @@ func (p *StringVector) Data() []string { ...@@ -50,47 +112,96 @@ func (p *StringVector) Data() []string {
// Insert inserts into the vector an element of value x before // Insert inserts into the vector an element of value x before
// the current element at index i. // the current element at index i.
func (p *StringVector) Insert(i int, x string) { func (p *StringVector) Insert(i int, x string) {
p.Vector.Insert(i, x) p.Expand(i, 1)
(*p)[i] = x
}
// Delete deletes the i'th element of the vector. The gap is closed so the old
// element at index i+1 has index i afterwards.
func (p *StringVector) Delete(i int) {
a := *p
n := len(a)
copy(a[i:n-1], a[i+1:n])
var zero string
a[n-1] = zero // support GC, zero out entry
*p = a[0 : n-1]
} }
// InsertVector inserts into the vector the contents of the Vector // InsertVector inserts into the vector the contents of the vector
// x such that the 0th element of x appears at index i after insertion. // x such that the 0th element of x appears at index i after insertion.
func (p *StringVector) InsertVector(i int, x *StringVector) { func (p *StringVector) InsertVector(i int, x *StringVector) {
p.Vector.InsertVector(i, &x.Vector) b := *x
p.Expand(i, len(b))
copy((*p)[i:i+len(b)], b)
}
// Cut deletes elements i through j-1, inclusive.
func (p *StringVector) Cut(i, j int) {
a := *p
n := len(a)
m := n - (j - i)
copy(a[i:m], a[j:n])
for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector.
var zero string
a[k] = zero // support GC, zero out entries
}
*p = a[0:m]
} }
// Slice returns a new StringVector by slicing the old one to extract slice [i:j]. // Slice returns a new sub-vector by slicing the old one to extract slice [i:j].
// The elements are copied. The original vector is unchanged. // The elements are copied. The original vector is unchanged.
func (p *StringVector) Slice(i, j int) *StringVector { func (p *StringVector) Slice(i, j int) *StringVector {
return &StringVector{*p.Vector.Slice(i, j)} var s StringVector
s.realloc(j-i, 0) // will fail in Init() if j < i
copy(s, (*p)[i:j])
return &s
} }
// Convenience wrappers
// Push appends x to the end of the vector. // Push appends x to the end of the vector.
func (p *StringVector) Push(x string) { p.Vector.Push(x) } func (p *StringVector) Push(x string) { p.Insert(len(*p), x) }
// Pop deletes the last element of the vector.
func (p *StringVector) Pop() string {
a := *p
// Pop deletes and returns the last element of the vector. i := len(a) - 1
func (p *StringVector) Pop() string { return p.Vector.Pop().(string) } x := a[i]
var zero string
a[i] = zero // support GC, zero out entry
*p = a[0:i]
return x
}
// AppendVector appends the entire StringVector x to the end of this vector. // AppendVector appends the entire vector x to the end of this vector.
func (p *StringVector) AppendVector(x *StringVector) { func (p *StringVector) AppendVector(x *StringVector) {
p.Vector.InsertVector(len(p.a), &x.Vector) p.InsertVector(len(*p), x)
} }
// sort.Interface support // Swap exchanges the elements at indexes i and j.
// Less returns a boolean denoting whether the i'th element is less than the j'th element. func (p *StringVector) Swap(i, j int) {
func (p *StringVector) Less(i, j int) bool { return p.At(i) < p.At(j) } a := *p
a[i], a[j] = a[j], a[i]
}
// Iterate over all elements; driver for range // Iterate over all elements; driver for range
func (p *StringVector) iterate(c chan<- string) { func (p *StringVector) iterate(c chan<- string) {
for _, v := range p.a { for _, v := range *p {
c <- v.(string) c <- v
} }
close(c) close(c)
} }
......
...@@ -2,34 +2,26 @@ ...@@ -2,34 +2,26 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// The vector package implements a container for managing sequences // CAUTION: If this file is not vector.go, it was generated
// of elements. Vectors grow and shrink dynamically as necessary. // automatically from vector.go - DO NOT EDIT in that case!
package vector
// Vector is the container itself. package vector
// The zero value for Vector is an empty vector ready to use.
type Vector struct {
a []interface{}
bootstrap [8]interface{}
}
func (p *Vector) realloc(length, capacity int) (b []interface{}) { func (p *Vector) realloc(length, capacity int) (b []interface{}) {
if length <= cap(p.bootstrap) && capacity <= cap(p.bootstrap) { if capacity < initialSize {
// don't allocate; use pre-allocated bootstrap array capacity = initialSize
b = p.bootstrap[0:length]
} else {
b = make([]interface{}, length, capacity)
} }
copy(b, p.a) b = make(Vector, length, capacity)
p.a = b copy(b, *p)
*p = b
return return
} }
// Insert n elements at position i. // Insert n elements at position i.
func (p *Vector) expand(i, n int) { func (p *Vector) Expand(i, n int) {
a := p.a a := *p
// make sure we have enough space // make sure we have enough space
len0 := len(a) len0 := len(a)
...@@ -53,18 +45,22 @@ func (p *Vector) expand(i, n int) { ...@@ -53,18 +45,22 @@ func (p *Vector) expand(i, n int) {
a[j+n] = a[j] a[j+n] = a[j]
} }
p.a = a *p = a
} }
// Insert n elements at the end of a vector.
func (p *Vector) Extend(n int) { p.Expand(len(*p), n) }
// Resize changes the length and capacity of a vector. // Resize changes the length and capacity of a vector.
// If the new length is shorter than the current length, Resize discards // If the new length is shorter than the current length, Resize discards
// trailing elements. If the new length is longer than the current length, // trailing elements. If the new length is longer than the current length,
// Resize adds nil elements. The capacity parameter is ignored unless the // Resize adds the respective zero values for the additional elements. The capacity
// new length or capacity is longer that the current capacity. The resized // parameter is ignored unless the new length or capacity is longer than the current
// vector's capacity may be larger than the requested capacity. // capacity. The resized vector's capacity may be larger than the requested capacity.
func (p *Vector) Resize(length, capacity int) *Vector { func (p *Vector) Resize(length, capacity int) *Vector {
a := p.a a := *p
if length > cap(a) || capacity > cap(a) { if length > cap(a) || capacity > cap(a) {
// not enough space or larger capacity requested explicitly // not enough space or larger capacity requested explicitly
...@@ -72,42 +68,43 @@ func (p *Vector) Resize(length, capacity int) *Vector { ...@@ -72,42 +68,43 @@ func (p *Vector) Resize(length, capacity int) *Vector {
} else if length < len(a) { } else if length < len(a) {
// clear trailing elements // clear trailing elements
for i := range a[length:] { for i := range a[length:] {
a[length+i] = nil var zero interface{}
a[length+i] = zero
} }
} }
p.a = a[0:length] *p = a[0:length]
return p return p
} }
// Len returns the number of elements in the vector. // Len returns the number of elements in the vector.
func (p *Vector) Len() int { return len(p.a) } // Same as len(*p).
func (p *Vector) Len() int { return len(*p) }
// Cap returns the capacity of the vector; that is, the // Cap returns the capacity of the vector; that is, the
// maximum length the vector can grow without resizing. // maximum length the vector can grow without resizing.
func (p *Vector) Cap() int { return cap(p.a) } // Same as cap(*p).
func (p *Vector) Cap() int { return cap(*p) }
// At returns the i'th element of the vector. // At returns the i'th element of the vector.
func (p *Vector) At(i int) interface{} { return p.a[i] } func (p *Vector) At(i int) interface{} { return (*p)[i] }
// Set sets the i'th element of the vector to value x. // Set sets the i'th element of the vector to value x.
func (p *Vector) Set(i int, x interface{}) { p.a[i] = x } func (p *Vector) Set(i int, x interface{}) { (*p)[i] = x }
// Last returns the element in the vector of highest index. // Last returns the element in the vector of highest index.
func (p *Vector) Last() interface{} { return p.a[len(p.a)-1] } func (p *Vector) Last() interface{} { return (*p)[len(*p)-1] }
// Data returns all the elements as a slice. // Data returns all the elements as a slice.
func (p *Vector) Data() []interface{} { func (p *Vector) Data() []interface{} {
arr := make([]interface{}, p.Len()) arr := make(Vector, len(*p))
for i, v := range p.a { copy(arr, *p)
arr[i] = v
}
return arr return arr
} }
...@@ -115,106 +112,93 @@ func (p *Vector) Data() []interface{} { ...@@ -115,106 +112,93 @@ func (p *Vector) Data() []interface{} {
// Insert inserts into the vector an element of value x before // Insert inserts into the vector an element of value x before
// the current element at index i. // the current element at index i.
func (p *Vector) Insert(i int, x interface{}) { func (p *Vector) Insert(i int, x interface{}) {
p.expand(i, 1) p.Expand(i, 1)
p.a[i] = x (*p)[i] = x
} }
// Delete deletes the i'th element of the vector. The gap is closed so the old // Delete deletes the i'th element of the vector. The gap is closed so the old
// element at index i+1 has index i afterwards. // element at index i+1 has index i afterwards.
func (p *Vector) Delete(i int) { func (p *Vector) Delete(i int) {
a := p.a a := *p
n := len(a) n := len(a)
copy(a[i:n-1], a[i+1:n]) copy(a[i:n-1], a[i+1:n])
a[n-1] = nil // support GC, nil out entry var zero interface{}
p.a = a[0 : n-1] a[n-1] = zero // support GC, zero out entry
*p = a[0 : n-1]
} }
// InsertVector inserts into the vector the contents of the Vector // InsertVector inserts into the vector the contents of the vector
// x such that the 0th element of x appears at index i after insertion. // x such that the 0th element of x appears at index i after insertion.
func (p *Vector) InsertVector(i int, x *Vector) { func (p *Vector) InsertVector(i int, x *Vector) {
p.expand(i, len(x.a)) b := *x
copy(p.a[i:i+len(x.a)], x.a)
p.Expand(i, len(b))
copy((*p)[i:i+len(b)], b)
} }
// Cut deletes elements i through j-1, inclusive. // Cut deletes elements i through j-1, inclusive.
func (p *Vector) Cut(i, j int) { func (p *Vector) Cut(i, j int) {
a := p.a a := *p
n := len(a) n := len(a)
m := n - (j - i) m := n - (j - i)
copy(a[i:m], a[j:n]) copy(a[i:m], a[j:n])
for k := m; k < n; k++ { for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector.
a[k] = nil // support GC, nil out entries var zero interface{}
a[k] = zero // support GC, zero out entries
} }
p.a = a[0:m] *p = a[0:m]
} }
// Slice returns a new Vector by slicing the old one to extract slice [i:j]. // Slice returns a new sub-vector by slicing the old one to extract slice [i:j].
// The elements are copied. The original vector is unchanged. // The elements are copied. The original vector is unchanged.
func (p *Vector) Slice(i, j int) *Vector { func (p *Vector) Slice(i, j int) *Vector {
s := new(Vector).Resize(j-i, 0) // will fail in Init() if j < i var s Vector
copy(s.a, p.a[i:j]) s.realloc(j-i, 0) // will fail in Init() if j < i
return s copy(s, (*p)[i:j])
} return &s
// Do calls function f for each element of the vector, in order.
// The function should not change the indexing of the vector underfoot.
func (p *Vector) Do(f func(elem interface{})) {
for i := 0; i < len(p.a); i++ {
f(p.a[i]) // not too safe if f changes the Vector
}
} }
// Convenience wrappers // Convenience wrappers
// Push appends x to the end of the vector. // Push appends x to the end of the vector.
func (p *Vector) Push(x interface{}) { p.Insert(len(p.a), x) } func (p *Vector) Push(x interface{}) { p.Insert(len(*p), x) }
// Pop deletes the last element of the vector. // Pop deletes the last element of the vector.
func (p *Vector) Pop() interface{} { func (p *Vector) Pop() interface{} {
i := len(p.a) - 1 a := *p
x := p.a[i]
p.a[i] = nil // support GC, nil out entry
p.a = p.a[0:i]
return x
}
// AppendVector appends the entire Vector x to the end of this vector. i := len(a) - 1
func (p *Vector) AppendVector(x *Vector) { p.InsertVector(len(p.a), x) } x := a[i]
var zero interface{}
a[i] = zero // support GC, zero out entry
// Partial sort.Interface support *p = a[0:i]
return x
// LessInterface provides partial support of the sort.Interface.
type LessInterface interface {
Less(y interface{}) bool
} }
// Less returns a boolean denoting whether the i'th element is less than the j'th element. // AppendVector appends the entire vector x to the end of this vector.
func (p *Vector) Less(i, j int) bool { return p.a[i].(LessInterface).Less(p.a[j]) } func (p *Vector) AppendVector(x *Vector) { p.InsertVector(len(*p), x) }
// Swap exchanges the elements at indexes i and j. // Swap exchanges the elements at indexes i and j.
func (p *Vector) Swap(i, j int) { func (p *Vector) Swap(i, j int) {
a := p.a a := *p
a[i], a[j] = a[j], a[i] a[i], a[j] = a[j], a[i]
} }
// Iterate over all elements; driver for range // Iterate over all elements; driver for range
func (p *Vector) iterate(c chan<- interface{}) { func (p *Vector) iterate(c chan<- interface{}) {
for _, v := range p.a { for _, v := range *p {
c <- v c <- v
} }
close(c) close(c)
......
This diff is collapsed.
# Copyright 2009 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
include ../../../Make.$(GOARCH)
TARG=exp/vector
GOFILES=\
defs.go\
intvector.go\
stringvector.go\
vector.go\
generate: vector.go vector_test.go
< vector.go cat\
| gofmt -r='Vector -> IntVector'\
| gofmt -r='interface{} -> int'\
> intvector.go\
< vector.go cat\
| gofmt -r='Vector -> StringVector'\
| gofmt -r='interface{} -> string'\
> stringvector.go\
< vector_test.go cat\
| gofmt -r='Vector -> IntVector'\
| gofmt -r='zero -> intzero'\
| gofmt -r='elem2Value -> elem2IntValue'\
| gofmt -r='intf2Value -> intf2IntValue'\
| gofmt -r='int2Value -> int2IntValue'\
| gofmt -r='TestZeroLenExp -> TestIntZeroLenExp'\
| gofmt -r='TestResizeExp -> TestIntResizeExp'\
| gofmt -r='TestResize2Exp -> TestIntResize2Exp'\
| gofmt -r='checkZeroExp -> checkIntZeroExp'\
| gofmt -r='TestTrailingElementsExp -> TestIntTrailingElementsExp'\
| gofmt -r='TestAccessExp -> TestIntAccessExp'\
| gofmt -r='TestInsertDeleteClearExp -> TestIntInsertDeleteClearExp'\
| gofmt -r='verify_sliceExp -> verify_sliceIntExp'\
| gofmt -r='verify_patternExp -> verify_patternIntExp'\
| gofmt -r='make_vectorExp -> make_vectorIntExp'\
| gofmt -r='TestInsertVectorExp -> TestIntInsertVectorExp'\
| gofmt -r='TestDoExp -> TestIntDoExp'\
| gofmt -r='TestIterExp -> TestIntIterExp'\
| gofmt -r='TestVectorData -> TestIntVectorData'\
> intvector_test.go\
< vector_test.go cat\
| gofmt -r='Vector -> StringVector'\
| gofmt -r='zero -> strzero'\
| gofmt -r='int2Value -> int2StrValue'\
| gofmt -r='intf2Value -> intf2StrValue'\
| gofmt -r='elem2Value -> elem2StrValue'\
| gofmt -r='TestZeroLenExp -> TestStrZeroLenExp'\
| gofmt -r='TestResizeExp -> TestStrResizeExp'\
| gofmt -r='TestResize2Exp -> TestStrResize2Exp'\
| gofmt -r='checkZeroExp -> checkStrZeroExp'\
| gofmt -r='TestTrailingElementsExp -> TestStrTrailingElementsExp'\
| gofmt -r='TestAccessExp -> TestStrAccessExp'\
| gofmt -r='TestInsertDeleteClearExp -> TestStrInsertDeleteClearExp'\
| gofmt -r='verify_sliceExp -> verify_sliceStrExp'\
| gofmt -r='verify_patternExp -> verify_patternStrExp'\
| gofmt -r='make_vectorExp -> make_vectorStrExp'\
| gofmt -r='TestInsertVectorExp -> TestStrInsertVectorExp'\
| gofmt -r='TestDoExp -> TestStrDoExp'\
| gofmt -r='TestIterExp -> TestStrIterExp'\
| gofmt -r='TestVectorData -> TestStrVectorData'\
> stringvector_test.go
include ../../../Make.pkg
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// CAUTION: If this file is not vector.go, it was generated
// automatically from vector.go - DO NOT EDIT in that case!
package vector
func (p *IntVector) realloc(length, capacity int) (b []int) {
if capacity < initialSize {
capacity = initialSize
}
b = make(IntVector, length, capacity)
copy(b, *p)
*p = b
return
}
// Insert n elements at position i.
func (p *IntVector) Expand(i, n int) {
a := *p
// make sure we have enough space
len0 := len(a)
len1 := len0 + n
if len1 <= cap(a) {
// enough space - just expand
a = a[0:len1]
} else {
// not enough space - double capacity
capb := cap(a) * 2
if capb < len1 {
// still not enough - use required length
capb = len1
}
// capb >= len1
a = p.realloc(len1, capb)
}
// make a hole
for j := len0 - 1; j >= i; j-- {
a[j+n] = a[j]
}
*p = a
}
// Insert n elements at the end of a vector.
func (p *IntVector) Extend(n int) { p.Expand(len(*p), n) }
// Resize changes the length and capacity of a vector.
// If the new length is shorter than the current length, Resize discards
// trailing elements. If the new length is longer than the current length,
// Resize adds the respective zero values for the additional elements. The capacity
// parameter is ignored unless the new length or capacity is longer than the current
// capacity. The resized vector's capacity may be larger than the requested capacity.
func (p *IntVector) Resize(length, capacity int) *IntVector {
a := *p
if length > cap(a) || capacity > cap(a) {
// not enough space or larger capacity requested explicitly
a = p.realloc(length, capacity)
} else if length < len(a) {
// clear trailing elements
for i := range a[length:] {
var zero int
a[length+i] = zero
}
}
*p = a[0:length]
return p
}
// Len returns the number of elements in the vector.
// Same as len(*p).
func (p *IntVector) Len() int { return len(*p) }
// Cap returns the capacity of the vector; that is, the
// maximum length the vector can grow without resizing.
// Same as cap(*p).
func (p *IntVector) Cap() int { return cap(*p) }
// At returns the i'th element of the vector.
func (p *IntVector) At(i int) int { return (*p)[i] }
// Set sets the i'th element of the vector to value x.
func (p *IntVector) Set(i int, x int) { (*p)[i] = x }
// Last returns the element in the vector of highest index.
func (p *IntVector) Last() int { return (*p)[len(*p)-1] }
// Data returns all the elements as a slice.
func (p *IntVector) Data() []int {
arr := make(IntVector, len(*p))
copy(arr, *p)
return arr
}
// Insert inserts into the vector an element of value x before
// the current element at index i.
func (p *IntVector) Insert(i int, x int) {
p.Expand(i, 1)
(*p)[i] = x
}
// Delete deletes the i'th element of the vector. The gap is closed so the old
// element at index i+1 has index i afterwards.
func (p *IntVector) Delete(i int) {
a := *p
n := len(a)
copy(a[i:n-1], a[i+1:n])
var zero int
a[n-1] = zero // support GC, zero out entry
*p = a[0 : n-1]
}
// InsertVector inserts into the vector the contents of the vector
// x such that the 0th element of x appears at index i after insertion.
func (p *IntVector) InsertVector(i int, x *IntVector) {
b := *x
p.Expand(i, len(b))
copy((*p)[i:i+len(b)], b)
}
// Cut deletes elements i through j-1, inclusive.
func (p *IntVector) Cut(i, j int) {
a := *p
n := len(a)
m := n - (j - i)
copy(a[i:m], a[j:n])
for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector.
var zero int
a[k] = zero // support GC, zero out entries
}
*p = a[0:m]
}
// Slice returns a new sub-vector by slicing the old one to extract slice [i:j].
// The elements are copied. The original vector is unchanged.
func (p *IntVector) Slice(i, j int) *IntVector {
var s IntVector
s.realloc(j-i, 0) // will fail in Init() if j < i
copy(s, (*p)[i:j])
return &s
}
// Convenience wrappers
// Push appends x to the end of the vector.
func (p *IntVector) Push(x int) { p.Insert(len(*p), x) }
// Pop deletes the last element of the vector.
func (p *IntVector) Pop() int {
a := *p
i := len(a) - 1
x := a[i]
var zero int
a[i] = zero // support GC, zero out entry
*p = a[0:i]
return x
}
// AppendVector appends the entire vector x to the end of this vector.
func (p *IntVector) AppendVector(x *IntVector) {
p.InsertVector(len(*p), x)
}
// Swap exchanges the elements at indexes i and j.
func (p *IntVector) Swap(i, j int) {
a := *p
a[i], a[j] = a[j], a[i]
}
// Iterate over all elements; driver for range
func (p *IntVector) iterate(c chan<- int) {
for _, v := range *p {
c <- v
}
close(c)
}
// Channel iterator for range.
func (p *IntVector) Iter() <-chan int {
c := make(chan int)
go p.iterate(c)
return c
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// CAUTION: If this file is not vector.go, it was generated
// automatically from vector.go - DO NOT EDIT in that case!
package vector
func (p *StringVector) realloc(length, capacity int) (b []string) {
if capacity < initialSize {
capacity = initialSize
}
b = make(StringVector, length, capacity)
copy(b, *p)
*p = b
return
}
// Insert n elements at position i.
func (p *StringVector) Expand(i, n int) {
a := *p
// make sure we have enough space
len0 := len(a)
len1 := len0 + n
if len1 <= cap(a) {
// enough space - just expand
a = a[0:len1]
} else {
// not enough space - double capacity
capb := cap(a) * 2
if capb < len1 {
// still not enough - use required length
capb = len1
}
// capb >= len1
a = p.realloc(len1, capb)
}
// make a hole
for j := len0 - 1; j >= i; j-- {
a[j+n] = a[j]
}
*p = a
}
// Insert n elements at the end of a vector.
func (p *StringVector) Extend(n int) { p.Expand(len(*p), n) }
// Resize changes the length and capacity of a vector.
// If the new length is shorter than the current length, Resize discards
// trailing elements. If the new length is longer than the current length,
// Resize adds the respective zero values for the additional elements. The capacity
// parameter is ignored unless the new length or capacity is longer than the current
// capacity. The resized vector's capacity may be larger than the requested capacity.
func (p *StringVector) Resize(length, capacity int) *StringVector {
a := *p
if length > cap(a) || capacity > cap(a) {
// not enough space or larger capacity requested explicitly
a = p.realloc(length, capacity)
} else if length < len(a) {
// clear trailing elements
for i := range a[length:] {
var zero string
a[length+i] = zero
}
}
*p = a[0:length]
return p
}
// Len returns the number of elements in the vector.
// Same as len(*p).
func (p *StringVector) Len() int { return len(*p) }
// Cap returns the capacity of the vector; that is, the
// maximum length the vector can grow without resizing.
// Same as cap(*p).
func (p *StringVector) Cap() int { return cap(*p) }
// At returns the i'th element of the vector.
func (p *StringVector) At(i int) string { return (*p)[i] }
// Set sets the i'th element of the vector to value x.
func (p *StringVector) Set(i int, x string) { (*p)[i] = x }
// Last returns the element in the vector of highest index.
func (p *StringVector) Last() string { return (*p)[len(*p)-1] }
// Data returns all the elements as a slice.
func (p *StringVector) Data() []string {
arr := make(StringVector, len(*p))
copy(arr, *p)
return arr
}
// Insert inserts into the vector an element of value x before
// the current element at index i.
func (p *StringVector) Insert(i int, x string) {
p.Expand(i, 1)
(*p)[i] = x
}
// Delete deletes the i'th element of the vector. The gap is closed so the old
// element at index i+1 has index i afterwards.
func (p *StringVector) Delete(i int) {
a := *p
n := len(a)
copy(a[i:n-1], a[i+1:n])
var zero string
a[n-1] = zero // support GC, zero out entry
*p = a[0 : n-1]
}
// InsertVector inserts into the vector the contents of the vector
// x such that the 0th element of x appears at index i after insertion.
func (p *StringVector) InsertVector(i int, x *StringVector) {
b := *x
p.Expand(i, len(b))
copy((*p)[i:i+len(b)], b)
}
// Cut deletes elements i through j-1, inclusive.
func (p *StringVector) Cut(i, j int) {
a := *p
n := len(a)
m := n - (j - i)
copy(a[i:m], a[j:n])
for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector.
var zero string
a[k] = zero // support GC, zero out entries
}
*p = a[0:m]
}
// Slice returns a new sub-vector by slicing the old one to extract slice [i:j].
// The elements are copied. The original vector is unchanged.
func (p *StringVector) Slice(i, j int) *StringVector {
var s StringVector
s.realloc(j-i, 0) // will fail in Init() if j < i
copy(s, (*p)[i:j])
return &s
}
// Convenience wrappers
// Push appends x to the end of the vector.
func (p *StringVector) Push(x string) { p.Insert(len(*p), x) }
// Pop deletes the last element of the vector.
func (p *StringVector) Pop() string {
a := *p
i := len(a) - 1
x := a[i]
var zero string
a[i] = zero // support GC, zero out entry
*p = a[0:i]
return x
}
// AppendVector appends the entire vector x to the end of this vector.
func (p *StringVector) AppendVector(x *StringVector) {
p.InsertVector(len(*p), x)
}
// Swap exchanges the elements at indexes i and j.
func (p *StringVector) Swap(i, j int) {
a := *p
a[i], a[j] = a[j], a[i]
}
// Iterate over all elements; driver for range
func (p *StringVector) iterate(c chan<- string) {
for _, v := range *p {
c <- v
}
close(c)
}
// Channel iterator for range.
func (p *StringVector) Iter() <-chan string {
c := make(chan string)
go p.iterate(c)
return c
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// CAUTION: If this file is not vector.go, it was generated
// automatically from vector.go - DO NOT EDIT in that case!
package vector
func (p *Vector) realloc(length, capacity int) (b []interface{}) {
if capacity < initialSize {
capacity = initialSize
}
b = make(Vector, length, capacity)
copy(b, *p)
*p = b
return
}
// Insert n elements at position i.
func (p *Vector) Expand(i, n int) {
a := *p
// make sure we have enough space
len0 := len(a)
len1 := len0 + n
if len1 <= cap(a) {
// enough space - just expand
a = a[0:len1]
} else {
// not enough space - double capacity
capb := cap(a) * 2
if capb < len1 {
// still not enough - use required length
capb = len1
}
// capb >= len1
a = p.realloc(len1, capb)
}
// make a hole
for j := len0 - 1; j >= i; j-- {
a[j+n] = a[j]
}
*p = a
}
// Insert n elements at the end of a vector.
func (p *Vector) Extend(n int) { p.Expand(len(*p), n) }
// Resize changes the length and capacity of a vector.
// If the new length is shorter than the current length, Resize discards
// trailing elements. If the new length is longer than the current length,
// Resize adds the respective zero values for the additional elements. The capacity
// parameter is ignored unless the new length or capacity is longer than the current
// capacity. The resized vector's capacity may be larger than the requested capacity.
func (p *Vector) Resize(length, capacity int) *Vector {
a := *p
if length > cap(a) || capacity > cap(a) {
// not enough space or larger capacity requested explicitly
a = p.realloc(length, capacity)
} else if length < len(a) {
// clear trailing elements
for i := range a[length:] {
var zero interface{}
a[length+i] = zero
}
}
*p = a[0:length]
return p
}
// Len returns the number of elements in the vector.
// Same as len(*p).
func (p *Vector) Len() int { return len(*p) }
// Cap returns the capacity of the vector; that is, the
// maximum length the vector can grow without resizing.
// Same as cap(*p).
func (p *Vector) Cap() int { return cap(*p) }
// At returns the i'th element of the vector.
func (p *Vector) At(i int) interface{} { return (*p)[i] }
// Set sets the i'th element of the vector to value x.
func (p *Vector) Set(i int, x interface{}) { (*p)[i] = x }
// Last returns the element in the vector of highest index.
func (p *Vector) Last() interface{} { return (*p)[len(*p)-1] }
// Data returns all the elements as a slice.
func (p *Vector) Data() []interface{} {
arr := make(Vector, len(*p))
copy(arr, *p)
return arr
}
// Insert inserts into the vector an element of value x before
// the current element at index i.
func (p *Vector) Insert(i int, x interface{}) {
p.Expand(i, 1)
(*p)[i] = x
}
// Delete deletes the i'th element of the vector. The gap is closed so the old
// element at index i+1 has index i afterwards.
func (p *Vector) Delete(i int) {
a := *p
n := len(a)
copy(a[i:n-1], a[i+1:n])
var zero interface{}
a[n-1] = zero // support GC, zero out entry
*p = a[0 : n-1]
}
// InsertVector inserts into the vector the contents of the vector
// x such that the 0th element of x appears at index i after insertion.
func (p *Vector) InsertVector(i int, x *Vector) {
b := *x
p.Expand(i, len(b))
copy((*p)[i:i+len(b)], b)
}
// Cut deletes elements i through j-1, inclusive.
func (p *Vector) Cut(i, j int) {
a := *p
n := len(a)
m := n - (j - i)
copy(a[i:m], a[j:n])
for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector.
var zero interface{}
a[k] = zero // support GC, zero out entries
}
*p = a[0:m]
}
// Slice returns a new sub-vector by slicing the old one to extract slice [i:j].
// The elements are copied. The original vector is unchanged.
func (p *Vector) Slice(i, j int) *Vector {
var s Vector
s.realloc(j-i, 0) // will fail in Init() if j < i
copy(s, (*p)[i:j])
return &s
}
// Convenience wrappers
// Push appends x to the end of the vector.
func (p *Vector) Push(x interface{}) { p.Insert(len(*p), x) }
// Pop deletes the last element of the vector.
func (p *Vector) Pop() interface{} {
a := *p
i := len(a) - 1
x := a[i]
var zero interface{}
a[i] = zero // support GC, zero out entry
*p = a[0:i]
return x
}
// AppendVector appends the entire vector x to the end of this vector.
func (p *Vector) AppendVector(x *Vector) { p.InsertVector(len(*p), x) }
// Swap exchanges the elements at indexes i and j.
func (p *Vector) Swap(i, j int) {
a := *p
a[i], a[j] = a[j], a[i]
}
// Iterate over all elements; driver for range
func (p *Vector) iterate(c chan<- interface{}) {
for _, v := range *p {
c <- v
}
close(c)
}
// Channel iterator for range.
func (p *Vector) Iter() <-chan interface{} {
c := make(chan interface{})
go p.iterate(c)
return c
}
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// CAUTION: If this file is not vector_test.go, it was generated
// automatically from vector_test.go - DO NOT EDIT in that case!
package vector
import "testing"
func TestZeroLenExp(t *testing.T) {
a := new(Vector)
if a.Len() != 0 {
t.Errorf("%T: B1) expected 0, got %d", a, a.Len())
}
if len(*a) != 0 {
t.Errorf("%T: B2) expected 0, got %d", a, len(*a))
}
var b Vector
if b.Len() != 0 {
t.Errorf("%T: B3) expected 0, got %d", b, b.Len())
}
if len(b) != 0 {
t.Errorf("%T: B4) expected 0, got %d", b, len(b))
}
}
func TestResizeExp(t *testing.T) {
var a Vector
checkSizeExp(t, &a, 0, 0)
checkSizeExp(t, a.Resize(0, 5), 0, 5)
checkSizeExp(t, a.Resize(1, 0), 1, 5)
checkSizeExp(t, a.Resize(10, 0), 10, 10)
checkSizeExp(t, a.Resize(5, 0), 5, 10)
checkSizeExp(t, a.Resize(3, 8), 3, 10)
checkSizeExp(t, a.Resize(0, 100), 0, 100)
checkSizeExp(t, a.Resize(11, 100), 11, 100)
}
func TestResize2Exp(t *testing.T) {
var a Vector
checkSizeExp(t, &a, 0, 0)
a.Push(int2Value(1))
a.Push(int2Value(2))
a.Push(int2Value(3))
a.Push(int2Value(4))
checkSizeExp(t, &a, 4, 4)
checkSizeExp(t, a.Resize(10, 0), 10, 10)
for i := 4; i < a.Len(); i++ {
if a.At(i) != zero {
t.Errorf("%T: expected a.At(%d) == %v; found %v!", a, i, zero, a.At(i))
}
}
for i := 4; i < len(a); i++ {
if a[i] != zero {
t.Errorf("%T: expected a[%d] == %v; found %v", a, i, zero, a[i])
}
}
}
func checkZeroExp(t *testing.T, a *Vector, i int) {
for j := 0; j < i; j++ {
if a.At(j) == zero {
t.Errorf("%T: 1 expected a.At(%d) == %d; found %v", a, j, j, a.At(j))
}
if (*a)[j] == zero {
t.Errorf("%T: 2 expected (*a)[%d] == %d; found %v", a, j, j, (*a)[j])
}
}
for ; i < a.Len(); i++ {
if a.At(i) != zero {
t.Errorf("%T: 3 expected a.At(%d) == %v; found %v", a, i, zero, a.At(i))
}
if (*a)[i] != zero {
t.Errorf("%T: 4 expected (*a)[%d] == %v; found %v", a, i, zero, (*a)[i])
}
}
}
func TestTrailingElementsExp(t *testing.T) {
var a Vector
for i := 0; i < 10; i++ {
a.Push(int2Value(i + 1))
}
checkZeroExp(t, &a, 10)
checkSizeExp(t, &a, 10, 16)
checkSizeExp(t, a.Resize(5, 0), 5, 16)
checkSizeExp(t, a.Resize(10, 0), 10, 16)
checkZeroExp(t, &a, 5)
}
func TestAccessExp(t *testing.T) {
const n = 100
var a Vector
a.Resize(n, 0)
for i := 0; i < n; i++ {
a.Set(i, int2Value(valExp(i)))
}
for i := 0; i < n; i++ {
if elem2Value(a.At(i)) != int2Value(valExp(i)) {
t.Error(i)
}
}
var b Vector
b.Resize(n, 0)
for i := 0; i < n; i++ {
b[i] = int2Value(valExp(i))
}
for i := 0; i < n; i++ {
if elem2Value(b[i]) != int2Value(valExp(i)) {
t.Error(i)
}
}
}
func TestInsertDeleteClearExp(t *testing.T) {
const n = 100
var a Vector
for i := 0; i < n; i++ {
if a.Len() != i {
t.Errorf("T%: A) wrong Len() %d (expected %d)", a, a.Len(), i)
}
if len(a) != i {
t.Errorf("T%: A) wrong len() %d (expected %d)", a, len(a), i)
}
a.Insert(0, int2Value(valExp(i)))
if elem2Value(a.Last()) != int2Value(valExp(0)) {
t.Error("T%: B", a)
}
}
for i := n - 1; i >= 0; i-- {
if elem2Value(a.Last()) != int2Value(valExp(0)) {
t.Error("T%: C", a)
}
if elem2Value(a.At(0)) != int2Value(valExp(i)) {
t.Error("T%: D", a)
}
if elem2Value(a[0]) != int2Value(valExp(i)) {
t.Error("T%: D2", a)
}
a.Delete(0)
if a.Len() != i {
t.Errorf("T%: E) wrong Len() %d (expected %d)", a, a.Len(), i)
}
if len(a) != i {
t.Errorf("T%: E) wrong len() %d (expected %d)", a, len(a), i)
}
}
if a.Len() != 0 {
t.Errorf("T%: F) wrong Len() %d (expected 0)", a, a.Len())
}
if len(a) != 0 {
t.Errorf("T%: F) wrong len() %d (expected 0)", a, len(a))
}
for i := 0; i < n; i++ {
a.Push(int2Value(valExp(i)))
if a.Len() != i+1 {
t.Errorf("T%: G) wrong Len() %d (expected %d)", a, a.Len(), i+1)
}
if len(a) != i+1 {
t.Errorf("T%: G) wrong len() %d (expected %d)", a, len(a), i+1)
}
if elem2Value(a.Last()) != int2Value(valExp(i)) {
t.Error("T%: H", a)
}
}
a.Resize(0, 0)
if a.Len() != 0 {
t.Errorf("T%: I wrong Len() %d (expected 0)", a, a.Len())
}
if len(a) != 0 {
t.Errorf("T%: I wrong len() %d (expected 0)", a, len(a))
}
const m = 5
for j := 0; j < m; j++ {
a.Push(int2Value(j))
for i := 0; i < n; i++ {
x := valExp(i)
a.Push(int2Value(x))
if elem2Value(a.Pop()) != int2Value(x) {
t.Error("T%: J", a)
}
if a.Len() != j+1 {
t.Errorf("T%: K) wrong Len() %d (expected %d)", a, a.Len(), j+1)
}
if len(a) != j+1 {
t.Errorf("T%: K) wrong len() %d (expected %d)", a, len(a), j+1)
}
}
}
if a.Len() != m {
t.Errorf("T%: L) wrong Len() %d (expected %d)", a, a.Len(), m)
}
if len(a) != m {
t.Errorf("T%: L) wrong len() %d (expected %d)", a, len(a), m)
}
}
func verify_sliceExp(t *testing.T, x *Vector, elt, i, j int) {
for k := i; k < j; k++ {
if elem2Value(x.At(k)) != int2Value(elt) {
t.Errorf("T%: M) wrong [%d] element %v (expected %v)", x, k, elem2Value(x.At(k)), int2Value(elt))
}
}
s := x.Slice(i, j)
for k, n := 0, j-i; k < n; k++ {
if elem2Value(s.At(k)) != int2Value(elt) {
t.Errorf("T%: N) wrong [%d] element %v (expected %v)", x, k, elem2Value(x.At(k)), int2Value(elt))
}
}
}
func verify_patternExp(t *testing.T, x *Vector, a, b, c int) {
n := a + b + c
if x.Len() != n {
t.Errorf("T%: O) wrong Len() %d (expected %d)", x, x.Len(), n)
}
if len(*x) != n {
t.Errorf("T%: O) wrong len() %d (expected %d)", x, len(*x), n)
}
verify_sliceExp(t, x, 0, 0, a)
verify_sliceExp(t, x, 1, a, a+b)
verify_sliceExp(t, x, 0, a+b, n)
}
func make_vectorExp(elt, len int) *Vector {
x := new(Vector).Resize(len, 0)
for i := 0; i < len; i++ {
x.Set(i, int2Value(elt))
}
return x
}
func TestInsertVectorExp(t *testing.T) {
// 1
a := make_vectorExp(0, 0)
b := make_vectorExp(1, 10)
a.InsertVector(0, b)
verify_patternExp(t, a, 0, 10, 0)
// 2
a = make_vectorExp(0, 10)
b = make_vectorExp(1, 0)
a.InsertVector(5, b)
verify_patternExp(t, a, 5, 0, 5)
// 3
a = make_vectorExp(0, 10)
b = make_vectorExp(1, 3)
a.InsertVector(3, b)
verify_patternExp(t, a, 3, 3, 7)
// 4
a = make_vectorExp(0, 10)
b = make_vectorExp(1, 1000)
a.InsertVector(8, b)
verify_patternExp(t, a, 8, 1000, 2)
}
func TestDoExp(t *testing.T) {
const n = 25
const salt = 17
a := new(Vector).Resize(n, 0)
for i := 0; i < n; i++ {
a.Set(i, int2Value(salt*i))
}
count := 0
a.Do(func(e interface{}) {
i := intf2Value(e)
if i != int2Value(count*salt) {
t.Error(tname(a), "value at", count, "should be", count*salt, "not", i)
}
count++
})
if count != n {
t.Error(tname(a), "should visit", n, "values; did visit", count)
}
b := new(Vector).Resize(n, 0)
for i := 0; i < n; i++ {
(*b)[i] = int2Value(salt * i)
}
count = 0
b.Do(func(e interface{}) {
i := intf2Value(e)
if i != int2Value(count*salt) {
t.Error(tname(b), "b) value at", count, "should be", count*salt, "not", i)
}
count++
})
if count != n {
t.Error(tname(b), "b) should visit", n, "values; did visit", count)
}
var c Vector
c.Resize(n, 0)
for i := 0; i < n; i++ {
c[i] = int2Value(salt * i)
}
count = 0
c.Do(func(e interface{}) {
i := intf2Value(e)
if i != int2Value(count*salt) {
t.Error(tname(c), "c) value at", count, "should be", count*salt, "not", i)
}
count++
})
if count != n {
t.Error(tname(c), "c) should visit", n, "values; did visit", count)
}
}
func TestIterExp(t *testing.T) {
const Len = 100
x := new(Vector).Resize(Len, 0)
for i := 0; i < Len; i++ {
x.Set(i, int2Value(i*i))
}
i := 0
for v := range x.Iter() {
if elem2Value(v) != int2Value(i*i) {
t.Error(tname(x), "Iter expected", i*i, "got", elem2Value(v))
}
i++
}
if i != Len {
t.Error(tname(x), "Iter stopped at", i, "not", Len)
}
y := new(Vector).Resize(Len, 0)
for i := 0; i < Len; i++ {
(*y)[i] = int2Value(i * i)
}
i = 0
for v := range y.Iter() {
if elem2Value(v) != int2Value(i*i) {
t.Error(tname(y), "y, Iter expected", i*i, "got", elem2Value(v))
}
i++
}
if i != Len {
t.Error(tname(y), "y, Iter stopped at", i, "not", Len)
}
var z Vector
z.Resize(Len, 0)
for i := 0; i < Len; i++ {
z[i] = int2Value(i * i)
}
i = 0
for v := range z.Iter() {
if elem2Value(v) != int2Value(i*i) {
t.Error(tname(z), "z, Iter expected", i*i, "got", elem2Value(v))
}
i++
}
if i != Len {
t.Error(tname(z), "z, Iter stopped at", i, "not", Len)
}
}
func TestVectorData(t *testing.T) {
// verify Data() returns a slice of a copy, not a slice of the original vector
const Len = 10
var src Vector
for i := 0; i < Len; i++ {
src.Push(int2Value(i * i))
}
dest := src.Data()
for i := 0; i < Len; i++ {
src[i] = int2Value(-1)
v := elem2Value(dest[i])
if v != int2Value(i*i) {
t.Error(tname(src), "expected", i*i, "got", v)
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment