aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md62
-rw-r--r--deps.mk180
-rw-r--r--src/pds.go403
l---------tests/benchmarks/vector-append/main.go (renamed from tests/benchmarks/list-append/main.go)0
-rw-r--r--tests/benchmarks/vector-append/pds.go (renamed from tests/benchmarks/list-append/pds.go)2
l---------tests/benchmarks/vector-builder-append/main.go (renamed from tests/benchmarks/list-builder-append/main.go)0
-rw-r--r--tests/benchmarks/vector-builder-append/pds.go (renamed from tests/benchmarks/list-builder-append/pds.go)2
l---------tests/benchmarks/vector-builder-prepend/main.go (renamed from tests/benchmarks/list-builder-prepend/main.go)0
-rw-r--r--tests/benchmarks/vector-builder-prepend/pds.go (renamed from tests/benchmarks/list-builder-prepend/pds.go)2
l---------tests/benchmarks/vector-builder-set/main.go (renamed from tests/benchmarks/list-builder-set/main.go)0
-rw-r--r--tests/benchmarks/vector-builder-set/pds.go (renamed from tests/benchmarks/list-builder-set/pds.go)2
l---------tests/benchmarks/vector-iterator-backward/main.go (renamed from tests/benchmarks/list-iterator-backward/main.go)0
-rw-r--r--tests/benchmarks/vector-iterator-backward/pds.go (renamed from tests/benchmarks/list-iterator-backward/pds.go)2
l---------tests/benchmarks/vector-iterator-forward/main.go (renamed from tests/benchmarks/list-iterator-forward/main.go)0
-rw-r--r--tests/benchmarks/vector-iterator-forward/pds.go (renamed from tests/benchmarks/list-iterator-forward/pds.go)2
l---------tests/benchmarks/vector-prepend/main.go (renamed from tests/benchmarks/list-prepend/main.go)0
-rw-r--r--tests/benchmarks/vector-prepend/pds.go (renamed from tests/benchmarks/list-prepend/pds.go)2
l---------tests/benchmarks/vector-set/main.go (renamed from tests/benchmarks/list-set/main.go)0
-rw-r--r--tests/benchmarks/vector-set/pds.go (renamed from tests/benchmarks/list-set/pds.go)2
l---------tests/functional/vector-api/main.go (renamed from tests/functional/list-api/main.go)0
-rw-r--r--tests/functional/vector-api/pds.go (renamed from tests/functional/list-api/pds.go)8
l---------tests/functional/vector-builder-api/main.go (renamed from tests/functional/list-builder-api/main.go)0
-rw-r--r--tests/functional/vector-builder-api/pds.go (renamed from tests/functional/list-builder-api/pds.go)16
-rw-r--r--tests/pds.go172
24 files changed, 437 insertions, 420 deletions
diff --git a/README.md b/README.md
index 7e36cd3..7bcc851 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@ Immutable [![release](https://img.shields.io/github/release/benbjohnson/immutabl
=========
This repository contains *generic* immutable collection types for Go. It includes
-`List`, `Map`, `SortedMap`, `Set` and `SortedSet` implementations. Immutable collections can
+`Vector`, `Map`, `SortedMap`, `Set` and `SortedSet` implementations. Immutable collections can
provide efficient, lock free sharing of data by requiring that edits to the
collections return new collections.
@@ -16,25 +16,25 @@ additional CPU and memory overhead. Please evaluate the cost/benefit for your
particular project.
Special thanks to the [Immutable.js](https://immutable-js.github.io/immutable-js/)
-team as the `List` & `Map` implementations are loose ports from that project.
+team as the `Vector` & `Map` implementations are loose ports from that project.
-## List
+## Vector
-The `List` type represents a sorted, indexed collection of values and operates
+The `Vector` type represents a sorted, indexed collection of values and operates
similarly to a Go slice. It supports efficient append, prepend, update, and
slice operations.
-### Adding list elements
+### Adding vector elements
-Elements can be added to the end of the list with the `Append()` method or added
-to the beginning of the list with the `Prepend()` method. Unlike Go slices,
+Elements can be added to the end of the vector with the `Append()` method or added
+to the beginning of the vector with the `Prepend()` method. Unlike Go slices,
prepending is as efficient as appending.
```go
-// Create a list with 3 elements.
-l := immutable.NewList[string]()
+// Create a vector with 3 elements.
+l := immutable.NewVector[string]()
l = l.Append("foo")
l = l.Append("bar")
l = l.Prepend("baz")
@@ -45,30 +45,30 @@ fmt.Println(l.Get(1)) // "foo"
fmt.Println(l.Get(2)) // "bar"
```
-Note that each change to the list results in a new list being created. These
-lists are all snapshots at that point in time and cannot be changed so they
+Note that each change to the vector results in a new vector being created. These
+vectors are all snapshots at that point in time and cannot be changed so they
are safe to share between multiple goroutines.
-### Updating list elements
+### Updating vector elements
You can also overwrite existing elements by using the `Set()` method. In the
-following example, we'll update the third element in our list and return the
-new list to a new variable. You can see that our old `l` variable retains a
+following example, we'll update the third element in our vector and return the
+new vector to a new variable. You can see that our old `l` variable retains a
snapshot of the original value.
```go
-l := immutable.NewList[string]()
+l := immutable.NewVector[string]()
l = l.Append("foo")
l = l.Append("bar")
-newList := l.Set(2, "baz")
+newVector := l.Set(2, "baz")
fmt.Println(l.Get(1)) // "bar"
-fmt.Println(newList.Get(1)) // "baz"
+fmt.Println(newVector.Get(1)) // "baz"
```
-### Deriving sublists
+### Deriving subvectors
-You can create a sublist by using the `Slice()` method. This method works with
+You can create a subvector by using the `Slice()` method. This method works with
the same rules as subslicing a Go slice:
```go
@@ -79,18 +79,18 @@ fmt.Println(l.Get(0)) // "baz"
fmt.Println(l.Get(1)) // "foo"
```
-Please note that since `List` follows the same rules as slices, it will panic if
+Please note that since `Vector` follows the same rules as slices, it will panic if
you try to `Get()`, `Set()`, or `Slice()` with indexes that are outside of
-the range of the `List`.
+the range of the `Vector`.
-### Iterating lists
+### Iterating vectors
-Iterators provide a clean, simple way to iterate over the elements of the list
+Iterators provide a clean, simple way to iterate over the elements of the vector
in order. This is more efficient than simply calling `Get()` for each index.
-Below is an example of iterating over all elements of our list from above:
+Below is an example of iterating over all elements of our vector from above:
```go
itr := l.Iterator()
@@ -107,25 +107,25 @@ By default iterators start from index zero, however, the `Seek()` method can be
used to jump to a given index.
-### Efficiently building lists
+### Efficiently building vectors
-If you are building large lists, it is significantly more efficient to use the
-`ListBuilder`. It uses nearly the same API as `List` except that it updates
-a list in-place until you are ready to use it. This can improve bulk list
+If you are building large vectors, it is significantly more efficient to use the
+`VectorBuilder`. It uses nearly the same API as `Vector` except that it updates
+a vector in-place until you are ready to use it. This can improve bulk vector
building by 10x or more.
```go
-b := immutable.NewListBuilder[string]()
+b := immutable.NewVectorBuilder[string]()
b.Append("foo")
b.Append("bar")
b.Set(2, "baz")
-l := b.List()
+l := b.Vector()
fmt.Println(l.Get(0)) // "foo"
fmt.Println(l.Get(1)) // "baz"
```
-Builders are invalid after the call to `List()`.
+Builders are invalid after the call to `Vector()`.
## Map
diff --git a/deps.mk b/deps.mk
index 64a7968..be04d7b 100644
--- a/deps.mk
+++ b/deps.mk
@@ -4,14 +4,14 @@ libs.go = \
tests/benchmarks/builtin-map-set/pds.go \
tests/benchmarks/builtin-slice-append-int/pds.go \
tests/benchmarks/builtin-slice-append-interface/pds.go \
- tests/benchmarks/list-append/pds.go \
- tests/benchmarks/list-builder-append/pds.go \
- tests/benchmarks/list-builder-prepend/pds.go \
- tests/benchmarks/list-builder-set/pds.go \
- tests/benchmarks/list-iterator-backward/pds.go \
- tests/benchmarks/list-iterator-forward/pds.go \
- tests/benchmarks/list-prepend/pds.go \
- tests/benchmarks/list-set/pds.go \
+ tests/benchmarks/vector-append/pds.go \
+ tests/benchmarks/vector-builder-append/pds.go \
+ tests/benchmarks/vector-builder-prepend/pds.go \
+ tests/benchmarks/vector-builder-set/pds.go \
+ tests/benchmarks/vector-iterator-backward/pds.go \
+ tests/benchmarks/vector-iterator-forward/pds.go \
+ tests/benchmarks/vector-prepend/pds.go \
+ tests/benchmarks/vector-set/pds.go \
tests/benchmarks/map-builder-delete/pds.go \
tests/benchmarks/map-builder-set/pds.go \
tests/benchmarks/map-delete/pds.go \
@@ -23,8 +23,8 @@ libs.go = \
tests/benchmarks/sortedmap-iterator-backward/pds.go \
tests/benchmarks/sortedmap-iterator-forward/pds.go \
tests/benchmarks/sortedmap-set/pds.go \
- tests/functional/list-api/pds.go \
- tests/functional/list-builder-api/pds.go \
+ tests/functional/vector-api/pds.go \
+ tests/functional/vector-builder-api/pds.go \
tests/functional/map-api/pds.go \
tests/functional/map-builder-api/pds.go \
tests/functional/sortedmap-api/pds.go \
@@ -36,14 +36,14 @@ mains.go = \
tests/benchmarks/builtin-map-set/main.go \
tests/benchmarks/builtin-slice-append-int/main.go \
tests/benchmarks/builtin-slice-append-interface/main.go \
- tests/benchmarks/list-append/main.go \
- tests/benchmarks/list-builder-append/main.go \
- tests/benchmarks/list-builder-prepend/main.go \
- tests/benchmarks/list-builder-set/main.go \
- tests/benchmarks/list-iterator-backward/main.go \
- tests/benchmarks/list-iterator-forward/main.go \
- tests/benchmarks/list-prepend/main.go \
- tests/benchmarks/list-set/main.go \
+ tests/benchmarks/vector-append/main.go \
+ tests/benchmarks/vector-builder-append/main.go \
+ tests/benchmarks/vector-builder-prepend/main.go \
+ tests/benchmarks/vector-builder-set/main.go \
+ tests/benchmarks/vector-iterator-backward/main.go \
+ tests/benchmarks/vector-iterator-forward/main.go \
+ tests/benchmarks/vector-prepend/main.go \
+ tests/benchmarks/vector-set/main.go \
tests/benchmarks/map-builder-delete/main.go \
tests/benchmarks/map-builder-set/main.go \
tests/benchmarks/map-delete/main.go \
@@ -55,8 +55,8 @@ mains.go = \
tests/benchmarks/sortedmap-iterator-backward/main.go \
tests/benchmarks/sortedmap-iterator-forward/main.go \
tests/benchmarks/sortedmap-set/main.go \
- tests/functional/list-api/main.go \
- tests/functional/list-builder-api/main.go \
+ tests/functional/vector-api/main.go \
+ tests/functional/vector-builder-api/main.go \
tests/functional/map-api/main.go \
tests/functional/map-builder-api/main.go \
tests/functional/sortedmap-api/main.go \
@@ -64,16 +64,16 @@ mains.go = \
tests/main.go \
functional-tests/lib.go = \
- tests/functional/list-api/pds.go \
- tests/functional/list-builder-api/pds.go \
+ tests/functional/vector-api/pds.go \
+ tests/functional/vector-builder-api/pds.go \
tests/functional/map-api/pds.go \
tests/functional/map-builder-api/pds.go \
tests/functional/sortedmap-api/pds.go \
tests/functional/sortedmap-builder-api/pds.go \
functional-tests/main.go = \
- tests/functional/list-api/main.go \
- tests/functional/list-builder-api/main.go \
+ tests/functional/vector-api/main.go \
+ tests/functional/vector-builder-api/main.go \
tests/functional/map-api/main.go \
tests/functional/map-builder-api/main.go \
tests/functional/sortedmap-api/main.go \
@@ -88,14 +88,14 @@ benchmarks/lib.go = \
tests/benchmarks/builtin-map-set/pds.go \
tests/benchmarks/builtin-slice-append-int/pds.go \
tests/benchmarks/builtin-slice-append-interface/pds.go \
- tests/benchmarks/list-append/pds.go \
- tests/benchmarks/list-builder-append/pds.go \
- tests/benchmarks/list-builder-prepend/pds.go \
- tests/benchmarks/list-builder-set/pds.go \
- tests/benchmarks/list-iterator-backward/pds.go \
- tests/benchmarks/list-iterator-forward/pds.go \
- tests/benchmarks/list-prepend/pds.go \
- tests/benchmarks/list-set/pds.go \
+ tests/benchmarks/vector-append/pds.go \
+ tests/benchmarks/vector-builder-append/pds.go \
+ tests/benchmarks/vector-builder-prepend/pds.go \
+ tests/benchmarks/vector-builder-set/pds.go \
+ tests/benchmarks/vector-iterator-backward/pds.go \
+ tests/benchmarks/vector-iterator-forward/pds.go \
+ tests/benchmarks/vector-prepend/pds.go \
+ tests/benchmarks/vector-set/pds.go \
tests/benchmarks/map-builder-delete/pds.go \
tests/benchmarks/map-builder-set/pds.go \
tests/benchmarks/map-delete/pds.go \
@@ -113,14 +113,14 @@ benchmarks/main.go = \
tests/benchmarks/builtin-map-set/main.go \
tests/benchmarks/builtin-slice-append-int/main.go \
tests/benchmarks/builtin-slice-append-interface/main.go \
- tests/benchmarks/list-append/main.go \
- tests/benchmarks/list-builder-append/main.go \
- tests/benchmarks/list-builder-prepend/main.go \
- tests/benchmarks/list-builder-set/main.go \
- tests/benchmarks/list-iterator-backward/main.go \
- tests/benchmarks/list-iterator-forward/main.go \
- tests/benchmarks/list-prepend/main.go \
- tests/benchmarks/list-set/main.go \
+ tests/benchmarks/vector-append/main.go \
+ tests/benchmarks/vector-builder-append/main.go \
+ tests/benchmarks/vector-builder-prepend/main.go \
+ tests/benchmarks/vector-builder-set/main.go \
+ tests/benchmarks/vector-iterator-backward/main.go \
+ tests/benchmarks/vector-iterator-forward/main.go \
+ tests/benchmarks/vector-prepend/main.go \
+ tests/benchmarks/vector-set/main.go \
tests/benchmarks/map-builder-delete/main.go \
tests/benchmarks/map-builder-set/main.go \
tests/benchmarks/map-delete/main.go \
@@ -142,22 +142,22 @@ tests/benchmarks/builtin-slice-append-int/main.a: tests/benchmarks/builtin-slice
tests/benchmarks/builtin-slice-append-int/pds.a: tests/benchmarks/builtin-slice-append-int/pds.go
tests/benchmarks/builtin-slice-append-interface/main.a: tests/benchmarks/builtin-slice-append-interface/main.go
tests/benchmarks/builtin-slice-append-interface/pds.a: tests/benchmarks/builtin-slice-append-interface/pds.go
-tests/benchmarks/list-append/main.a: tests/benchmarks/list-append/main.go
-tests/benchmarks/list-append/pds.a: tests/benchmarks/list-append/pds.go
-tests/benchmarks/list-builder-append/main.a: tests/benchmarks/list-builder-append/main.go
-tests/benchmarks/list-builder-append/pds.a: tests/benchmarks/list-builder-append/pds.go
-tests/benchmarks/list-builder-prepend/main.a: tests/benchmarks/list-builder-prepend/main.go
-tests/benchmarks/list-builder-prepend/pds.a: tests/benchmarks/list-builder-prepend/pds.go
-tests/benchmarks/list-builder-set/main.a: tests/benchmarks/list-builder-set/main.go
-tests/benchmarks/list-builder-set/pds.a: tests/benchmarks/list-builder-set/pds.go
-tests/benchmarks/list-iterator-backward/main.a: tests/benchmarks/list-iterator-backward/main.go
-tests/benchmarks/list-iterator-backward/pds.a: tests/benchmarks/list-iterator-backward/pds.go
-tests/benchmarks/list-iterator-forward/main.a: tests/benchmarks/list-iterator-forward/main.go
-tests/benchmarks/list-iterator-forward/pds.a: tests/benchmarks/list-iterator-forward/pds.go
-tests/benchmarks/list-prepend/main.a: tests/benchmarks/list-prepend/main.go
-tests/benchmarks/list-prepend/pds.a: tests/benchmarks/list-prepend/pds.go
-tests/benchmarks/list-set/main.a: tests/benchmarks/list-set/main.go
-tests/benchmarks/list-set/pds.a: tests/benchmarks/list-set/pds.go
+tests/benchmarks/vector-append/main.a: tests/benchmarks/vector-append/main.go
+tests/benchmarks/vector-append/pds.a: tests/benchmarks/vector-append/pds.go
+tests/benchmarks/vector-builder-append/main.a: tests/benchmarks/vector-builder-append/main.go
+tests/benchmarks/vector-builder-append/pds.a: tests/benchmarks/vector-builder-append/pds.go
+tests/benchmarks/vector-builder-prepend/main.a: tests/benchmarks/vector-builder-prepend/main.go
+tests/benchmarks/vector-builder-prepend/pds.a: tests/benchmarks/vector-builder-prepend/pds.go
+tests/benchmarks/vector-builder-set/main.a: tests/benchmarks/vector-builder-set/main.go
+tests/benchmarks/vector-builder-set/pds.a: tests/benchmarks/vector-builder-set/pds.go
+tests/benchmarks/vector-iterator-backward/main.a: tests/benchmarks/vector-iterator-backward/main.go
+tests/benchmarks/vector-iterator-backward/pds.a: tests/benchmarks/vector-iterator-backward/pds.go
+tests/benchmarks/vector-iterator-forward/main.a: tests/benchmarks/vector-iterator-forward/main.go
+tests/benchmarks/vector-iterator-forward/pds.a: tests/benchmarks/vector-iterator-forward/pds.go
+tests/benchmarks/vector-prepend/main.a: tests/benchmarks/vector-prepend/main.go
+tests/benchmarks/vector-prepend/pds.a: tests/benchmarks/vector-prepend/pds.go
+tests/benchmarks/vector-set/main.a: tests/benchmarks/vector-set/main.go
+tests/benchmarks/vector-set/pds.a: tests/benchmarks/vector-set/pds.go
tests/benchmarks/map-builder-delete/main.a: tests/benchmarks/map-builder-delete/main.go
tests/benchmarks/map-builder-delete/pds.a: tests/benchmarks/map-builder-delete/pds.go
tests/benchmarks/map-builder-set/main.a: tests/benchmarks/map-builder-set/main.go
@@ -180,10 +180,10 @@ tests/benchmarks/sortedmap-iterator-forward/main.a: tests/benchmarks/sortedmap-i
tests/benchmarks/sortedmap-iterator-forward/pds.a: tests/benchmarks/sortedmap-iterator-forward/pds.go
tests/benchmarks/sortedmap-set/main.a: tests/benchmarks/sortedmap-set/main.go
tests/benchmarks/sortedmap-set/pds.a: tests/benchmarks/sortedmap-set/pds.go
-tests/functional/list-api/main.a: tests/functional/list-api/main.go
-tests/functional/list-api/pds.a: tests/functional/list-api/pds.go
-tests/functional/list-builder-api/main.a: tests/functional/list-builder-api/main.go
-tests/functional/list-builder-api/pds.a: tests/functional/list-builder-api/pds.go
+tests/functional/vector-api/main.a: tests/functional/vector-api/main.go
+tests/functional/vector-api/pds.a: tests/functional/vector-api/pds.go
+tests/functional/vector-builder-api/main.a: tests/functional/vector-builder-api/main.go
+tests/functional/vector-builder-api/pds.a: tests/functional/vector-builder-api/pds.go
tests/functional/map-api/main.a: tests/functional/map-api/main.go
tests/functional/map-api/pds.a: tests/functional/map-api/pds.go
tests/functional/map-builder-api/main.a: tests/functional/map-builder-api/main.go
@@ -198,14 +198,14 @@ tests/benchmarks/builtin-map-delete/main.bin: tests/benchmarks/builtin-map-delet
tests/benchmarks/builtin-map-set/main.bin: tests/benchmarks/builtin-map-set/main.a
tests/benchmarks/builtin-slice-append-int/main.bin: tests/benchmarks/builtin-slice-append-int/main.a
tests/benchmarks/builtin-slice-append-interface/main.bin: tests/benchmarks/builtin-slice-append-interface/main.a
-tests/benchmarks/list-append/main.bin: tests/benchmarks/list-append/main.a
-tests/benchmarks/list-builder-append/main.bin: tests/benchmarks/list-builder-append/main.a
-tests/benchmarks/list-builder-prepend/main.bin: tests/benchmarks/list-builder-prepend/main.a
-tests/benchmarks/list-builder-set/main.bin: tests/benchmarks/list-builder-set/main.a
-tests/benchmarks/list-iterator-backward/main.bin: tests/benchmarks/list-iterator-backward/main.a
-tests/benchmarks/list-iterator-forward/main.bin: tests/benchmarks/list-iterator-forward/main.a
-tests/benchmarks/list-prepend/main.bin: tests/benchmarks/list-prepend/main.a
-tests/benchmarks/list-set/main.bin: tests/benchmarks/list-set/main.a
+tests/benchmarks/vector-append/main.bin: tests/benchmarks/vector-append/main.a
+tests/benchmarks/vector-builder-append/main.bin: tests/benchmarks/vector-builder-append/main.a
+tests/benchmarks/vector-builder-prepend/main.bin: tests/benchmarks/vector-builder-prepend/main.a
+tests/benchmarks/vector-builder-set/main.bin: tests/benchmarks/vector-builder-set/main.a
+tests/benchmarks/vector-iterator-backward/main.bin: tests/benchmarks/vector-iterator-backward/main.a
+tests/benchmarks/vector-iterator-forward/main.bin: tests/benchmarks/vector-iterator-forward/main.a
+tests/benchmarks/vector-prepend/main.bin: tests/benchmarks/vector-prepend/main.a
+tests/benchmarks/vector-set/main.bin: tests/benchmarks/vector-set/main.a
tests/benchmarks/map-builder-delete/main.bin: tests/benchmarks/map-builder-delete/main.a
tests/benchmarks/map-builder-set/main.bin: tests/benchmarks/map-builder-set/main.a
tests/benchmarks/map-delete/main.bin: tests/benchmarks/map-delete/main.a
@@ -217,8 +217,8 @@ tests/benchmarks/sortedmap-delete/main.bin: tests/benchmarks/sortedmap-delete/ma
tests/benchmarks/sortedmap-iterator-backward/main.bin: tests/benchmarks/sortedmap-iterator-backward/main.a
tests/benchmarks/sortedmap-iterator-forward/main.bin: tests/benchmarks/sortedmap-iterator-forward/main.a
tests/benchmarks/sortedmap-set/main.bin: tests/benchmarks/sortedmap-set/main.a
-tests/functional/list-api/main.bin: tests/functional/list-api/main.a
-tests/functional/list-builder-api/main.bin: tests/functional/list-builder-api/main.a
+tests/functional/vector-api/main.bin: tests/functional/vector-api/main.a
+tests/functional/vector-builder-api/main.bin: tests/functional/vector-builder-api/main.a
tests/functional/map-api/main.bin: tests/functional/map-api/main.a
tests/functional/map-builder-api/main.bin: tests/functional/map-builder-api/main.a
tests/functional/sortedmap-api/main.bin: tests/functional/sortedmap-api/main.a
@@ -228,14 +228,14 @@ tests/benchmarks/builtin-map-delete/main.bin-check: tests/benchmarks/builtin-map
tests/benchmarks/builtin-map-set/main.bin-check: tests/benchmarks/builtin-map-set/main.bin
tests/benchmarks/builtin-slice-append-int/main.bin-check: tests/benchmarks/builtin-slice-append-int/main.bin
tests/benchmarks/builtin-slice-append-interface/main.bin-check: tests/benchmarks/builtin-slice-append-interface/main.bin
-tests/benchmarks/list-append/main.bin-check: tests/benchmarks/list-append/main.bin
-tests/benchmarks/list-builder-append/main.bin-check: tests/benchmarks/list-builder-append/main.bin
-tests/benchmarks/list-builder-prepend/main.bin-check: tests/benchmarks/list-builder-prepend/main.bin
-tests/benchmarks/list-builder-set/main.bin-check: tests/benchmarks/list-builder-set/main.bin
-tests/benchmarks/list-iterator-backward/main.bin-check: tests/benchmarks/list-iterator-backward/main.bin
-tests/benchmarks/list-iterator-forward/main.bin-check: tests/benchmarks/list-iterator-forward/main.bin
-tests/benchmarks/list-prepend/main.bin-check: tests/benchmarks/list-prepend/main.bin
-tests/benchmarks/list-set/main.bin-check: tests/benchmarks/list-set/main.bin
+tests/benchmarks/vector-append/main.bin-check: tests/benchmarks/vector-append/main.bin
+tests/benchmarks/vector-builder-append/main.bin-check: tests/benchmarks/vector-builder-append/main.bin
+tests/benchmarks/vector-builder-prepend/main.bin-check: tests/benchmarks/vector-builder-prepend/main.bin
+tests/benchmarks/vector-builder-set/main.bin-check: tests/benchmarks/vector-builder-set/main.bin
+tests/benchmarks/vector-iterator-backward/main.bin-check: tests/benchmarks/vector-iterator-backward/main.bin
+tests/benchmarks/vector-iterator-forward/main.bin-check: tests/benchmarks/vector-iterator-forward/main.bin
+tests/benchmarks/vector-prepend/main.bin-check: tests/benchmarks/vector-prepend/main.bin
+tests/benchmarks/vector-set/main.bin-check: tests/benchmarks/vector-set/main.bin
tests/benchmarks/map-builder-delete/main.bin-check: tests/benchmarks/map-builder-delete/main.bin
tests/benchmarks/map-builder-set/main.bin-check: tests/benchmarks/map-builder-set/main.bin
tests/benchmarks/map-delete/main.bin-check: tests/benchmarks/map-delete/main.bin
@@ -247,8 +247,8 @@ tests/benchmarks/sortedmap-delete/main.bin-check: tests/benchmarks/sortedmap-del
tests/benchmarks/sortedmap-iterator-backward/main.bin-check: tests/benchmarks/sortedmap-iterator-backward/main.bin
tests/benchmarks/sortedmap-iterator-forward/main.bin-check: tests/benchmarks/sortedmap-iterator-forward/main.bin
tests/benchmarks/sortedmap-set/main.bin-check: tests/benchmarks/sortedmap-set/main.bin
-tests/functional/list-api/main.bin-check: tests/functional/list-api/main.bin
-tests/functional/list-builder-api/main.bin-check: tests/functional/list-builder-api/main.bin
+tests/functional/vector-api/main.bin-check: tests/functional/vector-api/main.bin
+tests/functional/vector-builder-api/main.bin-check: tests/functional/vector-builder-api/main.bin
tests/functional/map-api/main.bin-check: tests/functional/map-api/main.bin
tests/functional/map-builder-api/main.bin-check: tests/functional/map-builder-api/main.bin
tests/functional/sortedmap-api/main.bin-check: tests/functional/sortedmap-api/main.bin
@@ -258,14 +258,14 @@ tests/benchmarks/builtin-map-delete/main.a: tests/benchmarks/builtin-map-delete/
tests/benchmarks/builtin-map-set/main.a: tests/benchmarks/builtin-map-set/$(NAME).a
tests/benchmarks/builtin-slice-append-int/main.a: tests/benchmarks/builtin-slice-append-int/$(NAME).a
tests/benchmarks/builtin-slice-append-interface/main.a: tests/benchmarks/builtin-slice-append-interface/$(NAME).a
-tests/benchmarks/list-append/main.a: tests/benchmarks/list-append/$(NAME).a
-tests/benchmarks/list-builder-append/main.a: tests/benchmarks/list-builder-append/$(NAME).a
-tests/benchmarks/list-builder-prepend/main.a: tests/benchmarks/list-builder-prepend/$(NAME).a
-tests/benchmarks/list-builder-set/main.a: tests/benchmarks/list-builder-set/$(NAME).a
-tests/benchmarks/list-iterator-backward/main.a: tests/benchmarks/list-iterator-backward/$(NAME).a
-tests/benchmarks/list-iterator-forward/main.a: tests/benchmarks/list-iterator-forward/$(NAME).a
-tests/benchmarks/list-prepend/main.a: tests/benchmarks/list-prepend/$(NAME).a
-tests/benchmarks/list-set/main.a: tests/benchmarks/list-set/$(NAME).a
+tests/benchmarks/vector-append/main.a: tests/benchmarks/vector-append/$(NAME).a
+tests/benchmarks/vector-builder-append/main.a: tests/benchmarks/vector-builder-append/$(NAME).a
+tests/benchmarks/vector-builder-prepend/main.a: tests/benchmarks/vector-builder-prepend/$(NAME).a
+tests/benchmarks/vector-builder-set/main.a: tests/benchmarks/vector-builder-set/$(NAME).a
+tests/benchmarks/vector-iterator-backward/main.a: tests/benchmarks/vector-iterator-backward/$(NAME).a
+tests/benchmarks/vector-iterator-forward/main.a: tests/benchmarks/vector-iterator-forward/$(NAME).a
+tests/benchmarks/vector-prepend/main.a: tests/benchmarks/vector-prepend/$(NAME).a
+tests/benchmarks/vector-set/main.a: tests/benchmarks/vector-set/$(NAME).a
tests/benchmarks/map-builder-delete/main.a: tests/benchmarks/map-builder-delete/$(NAME).a
tests/benchmarks/map-builder-set/main.a: tests/benchmarks/map-builder-set/$(NAME).a
tests/benchmarks/map-delete/main.a: tests/benchmarks/map-delete/$(NAME).a
@@ -277,8 +277,8 @@ tests/benchmarks/sortedmap-delete/main.a: tests/benchmarks/sortedmap-delete/$(NA
tests/benchmarks/sortedmap-iterator-backward/main.a: tests/benchmarks/sortedmap-iterator-backward/$(NAME).a
tests/benchmarks/sortedmap-iterator-forward/main.a: tests/benchmarks/sortedmap-iterator-forward/$(NAME).a
tests/benchmarks/sortedmap-set/main.a: tests/benchmarks/sortedmap-set/$(NAME).a
-tests/functional/list-api/main.a: tests/functional/list-api/$(NAME).a
-tests/functional/list-builder-api/main.a: tests/functional/list-builder-api/$(NAME).a
+tests/functional/vector-api/main.a: tests/functional/vector-api/$(NAME).a
+tests/functional/vector-builder-api/main.a: tests/functional/vector-builder-api/$(NAME).a
tests/functional/map-api/main.a: tests/functional/map-api/$(NAME).a
tests/functional/map-builder-api/main.a: tests/functional/map-builder-api/$(NAME).a
tests/functional/sortedmap-api/main.a: tests/functional/sortedmap-api/$(NAME).a
diff --git a/src/pds.go b/src/pds.go
index 0ce9ade..564afbd 100644
--- a/src/pds.go
+++ b/src/pds.go
@@ -4,7 +4,7 @@
//
// Immutable collections provide an efficient, safe way to share collections
// of data while minimizing locks. The collections in this package provide
-// List, Map, and SortedMap implementations. These act similarly to slices
+// Vector, Map, and SortedMap implementations. These act similarly to slices
// and maps, respectively, except that altering a collection returns a new
// copy of the collection with that change.
//
@@ -16,9 +16,9 @@
//
// # Collection Types
//
-// The List type provides an API similar to Go slices. They allow appending,
+// The Vector type provides an API similar to Go slices. They allow appending,
// prepending, and updating of elements. Elements can also be fetched by index
-// or iterated over using a ListIterator.
+// or iterated over using a VectorIterator.
//
// The Map & SortedMap types provide an API similar to Go maps. They allow
// values to be assigned to unique keys and allow for the deletion of keys.
@@ -50,20 +50,20 @@ import (
"strings"
)
-// List is a dense, ordered, indexed collections. They are analogous to slices
-// in Go. They can be updated by appending to the end of the list, prepending
-// values to the beginning of the list, or updating existing indexes in the
-// list.
-type List[T any] struct {
- root listNode[T] // root node
+// Vector is a dense, ordered, indexed collections. They are analogous to slices
+// in Go. They can be updated by appending to the end of the vector, prepending
+// values to the beginning of the vector, or updating existing indexes in the
+// vector.
+type Vector[T any] struct {
+ root vectorNode[T] // root node
origin int // offset to zero index element
size int // total number of elements in use
}
-// NewList returns a new empty instance of List.
-func NewList[T any](values ...T) *List[T] {
- l := &List[T]{
- root: &listLeafNode[T]{},
+// NewVector returns a new empty instance of Vector.
+func NewVector[T any](values ...T) *Vector[T] {
+ l := &Vector[T]{
+ root: &vectorLeafNode[T]{},
}
for _, value := range values {
l.append(value, true)
@@ -71,41 +71,47 @@ func NewList[T any](values ...T) *List[T] {
return l
}
-// clone returns a copy of the list.
-func (l *List[T]) clone() *List[T] {
+// clone returns a copy of the vector.
+func (l *Vector[T]) clone() *Vector[T] {
other := *l
return &other
}
-// Len returns the number of elements in the list.
-func (l *List[T]) Len() int {
+// Len returns the number of elements in the vector.
+func (l *Vector[T]) Len() int {
return l.size
}
// cap returns the total number of possible elements for the current depth.
-func (l *List[T]) cap() int {
- return 1 << (l.root.depth() * listNodeBits)
+func (l *Vector[T]) cap() int {
+ return 1 << (l.root.depth() * vectorNodeBits)
}
// Get returns the value at the given index. Similar to slices, this method will
-// panic if index is below zero or is greater than or equal to the list size.
-func (l *List[T]) Get(index int) T {
+// panic if index is below zero or is greater than or equal to the vector size.
+func (l *Vector[T]) Get(index int) T {
if index < 0 || index >= l.size {
- panic(fmt.Sprintf("immutable.List.Get: index %d out of bounds", index))
+ panic(fmt.Sprintf(
+ "immutable.Vector.Get: index %d out of bounds",
+ index,
+ ))
}
return l.root.get(l.origin + index)
}
-// Set returns a new list with value set at index. Similar to slices, this
+// Set returns a new vector with value set at index. Similar to slices, this
// method will panic if index is below zero or if the index is greater than
-// or equal to the list size.
-func (l *List[T]) Set(index int, value T) *List[T] {
+// or equal to the vector size.
+func (l *Vector[T]) Set(index int, value T) *Vector[T] {
return l.set(index, value, false)
}
-func (l *List[T]) set(index int, value T, mutable bool) *List[T] {
+func (l *Vector[T]) set(index int, value T, mutable bool) *Vector[T] {
if index < 0 || index >= l.size {
- panic(fmt.Sprintf("immutable.List.Set: index %d out of bounds", index))
+ panic(fmt.Sprintf(
+ "immutable.Vector.Set: index %d out of bounds",
+ index,
+ ))
}
other := l
if !mutable {
@@ -115,20 +121,20 @@ func (l *List[T]) set(index int, value T, mutable bool) *List[T] {
return other
}
-// Append returns a new list with value added to the end of the list.
-func (l *List[T]) Append(value T) *List[T] {
+// Append returns a new vector with value added to the end of the vector.
+func (l *Vector[T]) Append(value T) *Vector[T] {
return l.append(value, false)
}
-func (l *List[T]) append(value T, mutable bool) *List[T] {
+func (l *Vector[T]) append(value T, mutable bool) *Vector[T] {
other := l
if !mutable {
other = l.clone()
}
- // Expand list to the right if no slots remain.
+ // Expand vector to the right if no slots remain.
if other.size+other.origin >= l.cap() {
- newRoot := &listBranchNode[T]{d: other.root.depth() + 1}
+ newRoot := &vectorBranchNode[T]{d: other.root.depth() + 1}
newRoot.children[0] = other.root
other.root = newRoot
}
@@ -139,23 +145,25 @@ func (l *List[T]) append(value T, mutable bool) *List[T] {
return other
}
-// Prepend returns a new list with value(s) added to the beginning of the list.
-func (l *List[T]) Prepend(value T) *List[T] {
+// Prepend returns a new vector with value(s) added to the beginning of the
+// vector.
+func (l *Vector[T]) Prepend(value T) *Vector[T] {
return l.prepend(value, false)
}
-func (l *List[T]) prepend(value T, mutable bool) *List[T] {
+func (l *Vector[T]) prepend(value T, mutable bool) *Vector[T] {
other := l
if !mutable {
other = l.clone()
}
- // Expand list to the left if no slots remain.
+ // Expand vector to the left if no slots remain.
if other.origin == 0 {
- newRoot := &listBranchNode[T]{d: other.root.depth() + 1}
- newRoot.children[listNodeSize-1] = other.root
+ newRoot := &vectorBranchNode[T]{d: other.root.depth() + 1}
+ newRoot.children[vectorNodeSize-1] = other.root
other.root = newRoot
- other.origin += (listNodeSize - 1) << (other.root.depth() * listNodeBits)
+ other.origin += (vectorNodeSize - 1) <<
+ ((other.root.depth() * vectorNodeBits))
}
// Increase size and move origin back. Update first element to value.
@@ -165,28 +173,31 @@ func (l *List[T]) prepend(value T, mutable bool) *List[T] {
return other
}
-// Slice returns a new list of elements between start index and end index.
+// Slice returns a new vector of elements between start index and end index.
// Similar to slices, this method will panic if start or end are below zero or
-// greater than the list size. A panic will also occur if start is greater than
-// end.
+// greater than the vector size. A panic will also occur if start is greater
+// than end.
//
// Unlike Go slices, references to inaccessible elements will be automatically
// removed so they can be garbage collected.
-func (l *List[T]) Slice(start, end int) *List[T] {
+func (l *Vector[T]) Slice(start, end int) *Vector[T] {
return l.slice(start, end, false)
}
-func (l *List[T]) slice(start, end int, mutable bool) *List[T] {
+func (l *Vector[T]) slice(start, end int, mutable bool) *Vector[T] {
// Panics similar to Go slices.
if start < 0 || start > l.size {
- panic(fmt.Sprintf("immutable.List.Slice: start index %d out of bounds", start))
+ panic(fmt.Sprintf(
+ "immutable.Vector.Slice: start index %d out of bounds",
+ start,
+ ))
} else if end < 0 || end > l.size {
- panic(fmt.Sprintf("immutable.List.Slice: end index %d out of bounds", end))
+ panic(fmt.Sprintf("immutable.Vector.Slice: end index %d out of bounds", end))
} else if start > end {
- panic(fmt.Sprintf("immutable.List.Slice: invalid slice index: [%d:%d]", start, end))
+ panic(fmt.Sprintf("immutable.Vector.Slice: invalid slice index: [%d:%d]", start, end))
}
- // Return the same list if the start and end are the entire range.
+ // Return the same vector if the start and end are the entire range.
if start == 0 && end == l.size {
return l
}
@@ -203,15 +214,16 @@ func (l *List[T]) slice(start, end int, mutable bool) *List[T] {
// Contract tree while the start & end are in the same child node.
for other.root.depth() > 1 {
- i := (other.origin >> (other.root.depth() * listNodeBits)) & listNodeMask
- j := ((other.origin + other.size - 1) >> (other.root.depth() * listNodeBits)) & listNodeMask
+ i := (other.origin >> (other.root.depth() * vectorNodeBits)) & vectorNodeMask
+ j := ((other.origin + other.size - 1) >> (other.root.depth() * vectorNodeBits)) & vectorNodeMask
if i != j {
break // branch contains at least two nodes, exit
}
- // Replace the current root with the single child & update origin offset.
- other.origin -= i << (other.root.depth() * listNodeBits)
- other.root = other.root.(*listBranchNode[T]).children[i]
+ // Replace the current root with the single child & update
+ // origin offset.
+ other.origin -= i << (other.root.depth() * vectorNodeBits)
+ other.root = other.root.(*vectorBranchNode[T]).children[i]
}
// Ensure all references are removed before start & after end.
@@ -221,133 +233,138 @@ func (l *List[T]) slice(start, end int, mutable bool) *List[T] {
return other
}
-// Iterator returns a new iterator for this list positioned at the first index.
-func (l *List[T]) Iterator() *ListIterator[T] {
- itr := &ListIterator[T]{list: l}
+// Iterator returns a new iterator for this vector positioned at the first
+// index.
+func (l *Vector[T]) Iterator() *VectorIterator[T] {
+ itr := &VectorIterator[T]{vector: l}
itr.First()
return itr
}
-// ListBuilder represents an efficient builder for creating new Lists.
-type ListBuilder[T any] struct {
- list *List[T] // current state
+// VectorBuilder represents an efficient builder for creating new Vectors.
+type VectorBuilder[T any] struct {
+ vector *Vector[T] // current state
}
-// NewListBuilder returns a new instance of ListBuilder.
-func NewListBuilder[T any]() *ListBuilder[T] {
- return &ListBuilder[T]{list: NewList[T]()}
+// NewVectorBuilder returns a new instance of VectorBuilder.
+func NewVectorBuilder[T any]() *VectorBuilder[T] {
+ return &VectorBuilder[T]{vector: NewVector[T]()}
}
-// List returns the current copy of the list.
-// The builder should not be used again after the list after this call.
-func (b *ListBuilder[T]) List() *List[T] {
- assert(b.list != nil, "immutable.ListBuilder.List(): duplicate call to fetch list")
- list := b.list
- b.list = nil
- return list
+// Vector returns the current copy of the vector.
+// The builder should not be used again after the vector after this call.
+func (b *VectorBuilder[T]) Vector() *Vector[T] {
+ assert(b.vector != nil, "immutable.VectorBuilder.Vector(): duplicate call to fetch vector")
+ vector := b.vector
+ b.vector = nil
+ return vector
}
-// Len returns the number of elements in the underlying list.
-func (b *ListBuilder[T]) Len() int {
- assert(b.list != nil, "immutable.ListBuilder: builder invalid after List() invocation")
- return b.list.Len()
+// Len returns the number of elements in the underlying vector.
+func (b *VectorBuilder[T]) Len() int {
+ assert(b.vector != nil, "immutable.VectorBuilder: builder invalid after Vector() invocation")
+ return b.vector.Len()
}
// Get returns the value at the given index. Similar to slices, this method will
-// panic if index is below zero or is greater than or equal to the list size.
-func (b *ListBuilder[T]) Get(index int) T {
- assert(b.list != nil, "immutable.ListBuilder: builder invalid after List() invocation")
- return b.list.Get(index)
+// panic if index is below zero or is greater than or equal to the vector size.
+func (b *VectorBuilder[T]) Get(index int) T {
+ assert(b.vector != nil, "immutable.VectorBuilder: builder invalid after Vector() invocation")
+ return b.vector.Get(index)
}
// Set updates the value at the given index. Similar to slices, this method will
// panic if index is below zero or if the index is greater than or equal to the
-// list size.
-func (b *ListBuilder[T]) Set(index int, value T) {
- assert(b.list != nil, "immutable.ListBuilder: builder invalid after List() invocation")
- b.list = b.list.set(index, value, true)
+// vector size.
+func (b *VectorBuilder[T]) Set(index int, value T) {
+ assert(b.vector != nil, "immutable.VectorBuilder: builder invalid after Vector() invocation")
+ b.vector = b.vector.set(index, value, true)
}
-// Append adds value to the end of the list.
-func (b *ListBuilder[T]) Append(value T) {
- assert(b.list != nil, "immutable.ListBuilder: builder invalid after List() invocation")
- b.list = b.list.append(value, true)
+// Append adds value to the end of the vector.
+func (b *VectorBuilder[T]) Append(value T) {
+ assert(b.vector != nil, "immutable.VectorBuilder: builder invalid after Vector() invocation")
+ b.vector = b.vector.append(value, true)
}
-// Prepend adds value to the beginning of the list.
-func (b *ListBuilder[T]) Prepend(value T) {
- assert(b.list != nil, "immutable.ListBuilder: builder invalid after List() invocation")
- b.list = b.list.prepend(value, true)
+// Prepend adds value to the beginning of the vector.
+func (b *VectorBuilder[T]) Prepend(value T) {
+ assert(b.vector != nil, "immutable.VectorBuilder: builder invalid after Vector() invocation")
+ b.vector = b.vector.prepend(value, true)
}
-// Slice updates the list with a sublist of elements between start and end index.
-// See List.Slice() for more details.
-func (b *ListBuilder[T]) Slice(start, end int) {
- assert(b.list != nil, "immutable.ListBuilder: builder invalid after List() invocation")
- b.list = b.list.slice(start, end, true)
+// Slice updates the vector with a subvector of elements between start and end
+// index.
+// See Vector.Slice() for more details.
+func (b *VectorBuilder[T]) Slice(start, end int) {
+ assert(b.vector != nil, "immutable.VectorBuilder: builder invalid after Vector() invocation")
+ b.vector = b.vector.slice(start, end, true)
}
-// Iterator returns a new iterator for the underlying list.
-func (b *ListBuilder[T]) Iterator() *ListIterator[T] {
- assert(b.list != nil, "immutable.ListBuilder: builder invalid after List() invocation")
- return b.list.Iterator()
+// Iterator returns a new iterator for the underlying vector.
+func (b *VectorBuilder[T]) Iterator() *VectorIterator[T] {
+ assert(b.vector != nil, "immutable.VectorBuilder: builder invalid after Vector() invocation")
+ return b.vector.Iterator()
}
-// Constants for bit shifts used for levels in the List trie.
+// Constants for bit shifts used for levels in the Vector trie.
const (
- listNodeBits = 5
- listNodeSize = 1 << listNodeBits
- listNodeMask = listNodeSize - 1
+ vectorNodeBits = 5
+ vectorNodeSize = 1 << vectorNodeBits
+ vectorNodeMask = vectorNodeSize - 1
)
-// listNode represents either a branch or leaf node in a List.
-type listNode[T any] interface {
+// vectorNode represents either a branch or leaf node in a Vector.
+type vectorNode[T any] interface {
depth() uint
get(index int) T
- set(index int, v T, mutable bool) listNode[T]
+ set(index int, v T, mutable bool) vectorNode[T]
containsBefore(index int) bool
containsAfter(index int) bool
- deleteBefore(index int, mutable bool) listNode[T]
- deleteAfter(index int, mutable bool) listNode[T]
+ deleteBefore(index int, mutable bool) vectorNode[T]
+ deleteAfter(index int, mutable bool) vectorNode[T]
}
-// newListNode returns a leaf node for depth zero, otherwise returns a branch node.
-func newListNode[T any](depth uint) listNode[T] {
+// newVectorNode returns a leaf node for depth zero, otherwise returns a branch
+// node.
+func newVectorNode[T any](depth uint) vectorNode[T] {
if depth == 0 {
- return &listLeafNode[T]{}
+ return &vectorLeafNode[T]{}
}
- return &listBranchNode[T]{d: depth}
+ return &vectorBranchNode[T]{d: depth}
}
-// listBranchNode represents a branch of a List tree at a given depth.
-type listBranchNode[T any] struct {
+// vectorBranchNode represents a branch of a Vector tree at a given depth.
+type vectorBranchNode[T any] struct {
d uint // depth
- children [listNodeSize]listNode[T]
+ children [vectorNodeSize]vectorNode[T]
}
// depth returns the depth of this branch node from the leaf.
-func (n *listBranchNode[T]) depth() uint { return n.d }
+func (n *vectorBranchNode[T]) depth() uint { return n.d }
// get returns the child node at the segment of the index for this depth.
-func (n *listBranchNode[T]) get(index int) T {
- idx := (index >> (n.d * listNodeBits)) & listNodeMask
+func (n *vectorBranchNode[T]) get(index int) T {
+ idx := (index >> (n.d * vectorNodeBits)) & vectorNodeMask
return n.children[idx].get(index)
}
-// set recursively updates the value at index for each lower depth from the node.
-func (n *listBranchNode[T]) set(index int, v T, mutable bool) listNode[T] {
- idx := (index >> (n.d * listNodeBits)) & listNodeMask
+// set recursively updates the value at index for each lower depth from the
+// node.
+func (n *vectorBranchNode[T]) set(index int, v T, mutable bool) vectorNode[T] {
+ idx := (index >> (n.d * vectorNodeBits)) & vectorNodeMask
- // Find child for the given value in the branch. Create new if it doesn't exist.
+ // Find child for the given value in the branch. Create new if it
+ // doesn't exist.
child := n.children[idx]
if child == nil {
- child = newListNode[T](n.depth() - 1)
+ child = newVectorNode[T](n.depth() - 1)
}
// Return a copy of this branch with the new child.
- var other *listBranchNode[T]
+ var other *vectorBranchNode[T]
if mutable {
other = n
} else {
@@ -359,8 +376,8 @@ func (n *listBranchNode[T]) set(index int, v T, mutable bool) listNode[T] {
}
// containsBefore returns true if non-nil values exists between [0,index).
-func (n *listBranchNode[T]) containsBefore(index int) bool {
- idx := (index >> (n.d * listNodeBits)) & listNodeMask
+func (n *vectorBranchNode[T]) containsBefore(index int) bool {
+ idx := (index >> (n.d * vectorNodeBits)) & vectorNodeMask
// Quickly check if any direct children exist before this segment of the index.
for i := 0; i < idx; i++ {
@@ -376,9 +393,9 @@ func (n *listBranchNode[T]) containsBefore(index int) bool {
return false
}
-// containsAfter returns true if non-nil values exists between (index,listNodeSize).
-func (n *listBranchNode[T]) containsAfter(index int) bool {
- idx := (index >> (n.d * listNodeBits)) & listNodeMask
+// containsAfter returns true if non-nil values exists between (index,vectorNodeSize).
+func (n *vectorBranchNode[T]) containsAfter(index int) bool {
+ idx := (index >> (n.d * vectorNodeBits)) & vectorNodeMask
// Quickly check if any direct children exist after this segment of the index.
for i := idx + 1; i < len(n.children); i++ {
@@ -395,23 +412,23 @@ func (n *listBranchNode[T]) containsAfter(index int) bool {
}
// deleteBefore returns a new node with all elements before index removed.
-func (n *listBranchNode[T]) deleteBefore(index int, mutable bool) listNode[T] {
+func (n *vectorBranchNode[T]) deleteBefore(index int, mutable bool) vectorNode[T] {
// Ignore if no nodes exist before the given index.
if !n.containsBefore(index) {
return n
}
// Return a copy with any nodes prior to the index removed.
- idx := (index >> (n.d * listNodeBits)) & listNodeMask
+ idx := (index >> (n.d * vectorNodeBits)) & vectorNodeMask
- var other *listBranchNode[T]
+ var other *vectorBranchNode[T]
if mutable {
other = n
for i := 0; i < idx; i++ {
n.children[i] = nil
}
} else {
- other = &listBranchNode[T]{d: n.d}
+ other = &vectorBranchNode[T]{d: n.d}
copy(other.children[idx:][:], n.children[idx:][:])
}
@@ -422,23 +439,23 @@ func (n *listBranchNode[T]) deleteBefore(index int, mutable bool) listNode[T] {
}
// deleteBefore returns a new node with all elements before index removed.
-func (n *listBranchNode[T]) deleteAfter(index int, mutable bool) listNode[T] {
+func (n *vectorBranchNode[T]) deleteAfter(index int, mutable bool) vectorNode[T] {
// Ignore if no nodes exist after the given index.
if !n.containsAfter(index) {
return n
}
// Return a copy with any nodes after the index removed.
- idx := (index >> (n.d * listNodeBits)) & listNodeMask
+ idx := (index >> (n.d * vectorNodeBits)) & vectorNodeMask
- var other *listBranchNode[T]
+ var other *vectorBranchNode[T]
if mutable {
other = n
for i := idx + 1; i < len(n.children); i++ {
n.children[i] = nil
}
} else {
- other = &listBranchNode[T]{d: n.d}
+ other = &vectorBranchNode[T]{d: n.d}
copy(other.children[:idx+1], n.children[:idx+1])
}
@@ -448,25 +465,25 @@ func (n *listBranchNode[T]) deleteAfter(index int, mutable bool) listNode[T] {
return other
}
-// listLeafNode represents a leaf node in a List.
-type listLeafNode[T any] struct {
- children [listNodeSize]T
+// vectorLeafNode represents a leaf node in a Vector.
+type vectorLeafNode[T any] struct {
+ children [vectorNodeSize]T
// bitset with ones at occupied positions, position 0 is the LSB
occupied uint32
}
// depth always returns 0 for leaf nodes.
-func (n *listLeafNode[T]) depth() uint { return 0 }
+func (n *vectorLeafNode[T]) depth() uint { return 0 }
// get returns the value at the given index.
-func (n *listLeafNode[T]) get(index int) T {
- return n.children[index&listNodeMask]
+func (n *vectorLeafNode[T]) get(index int) T {
+ return n.children[index&vectorNodeMask]
}
// set returns a copy of the node with the value at the index updated to v.
-func (n *listLeafNode[T]) set(index int, v T, mutable bool) listNode[T] {
- idx := index & listNodeMask
- var other *listLeafNode[T]
+func (n *vectorLeafNode[T]) set(index int, v T, mutable bool) vectorNode[T] {
+ idx := index & vectorNodeMask
+ var other *vectorLeafNode[T]
if mutable {
other = n
} else {
@@ -479,26 +496,26 @@ func (n *listLeafNode[T]) set(index int, v T, mutable bool) listNode[T] {
}
// containsBefore returns true if non-nil values exists between [0,index).
-func (n *listLeafNode[T]) containsBefore(index int) bool {
- idx := index & listNodeMask
+func (n *vectorLeafNode[T]) containsBefore(index int) bool {
+ idx := index & vectorNodeMask
return bits.TrailingZeros32(n.occupied) < idx
}
-// containsAfter returns true if non-nil values exists between (index,listNodeSize).
-func (n *listLeafNode[T]) containsAfter(index int) bool {
- idx := index & listNodeMask
+// containsAfter returns true if non-nil values exists between (index,vectorNodeSize).
+func (n *vectorLeafNode[T]) containsAfter(index int) bool {
+ idx := index & vectorNodeMask
lastSetPos := 31 - bits.LeadingZeros32(n.occupied)
return lastSetPos > idx
}
// deleteBefore returns a new node with all elements before index removed.
-func (n *listLeafNode[T]) deleteBefore(index int, mutable bool) listNode[T] {
+func (n *vectorLeafNode[T]) deleteBefore(index int, mutable bool) vectorNode[T] {
if !n.containsBefore(index) {
return n
}
- idx := index & listNodeMask
- var other *listLeafNode[T]
+ idx := index & vectorNodeMask
+ var other *vectorLeafNode[T]
if mutable {
other = n
var empty T
@@ -506,7 +523,7 @@ func (n *listLeafNode[T]) deleteBefore(index int, mutable bool) listNode[T] {
other.children[i] = empty
}
} else {
- other = &listLeafNode[T]{occupied: n.occupied}
+ other = &vectorLeafNode[T]{occupied: n.occupied}
copy(other.children[idx:][:], n.children[idx:][:])
}
// Set the first idx bits to 0.
@@ -515,13 +532,13 @@ func (n *listLeafNode[T]) deleteBefore(index int, mutable bool) listNode[T] {
}
// deleteAfter returns a new node with all elements after index removed.
-func (n *listLeafNode[T]) deleteAfter(index int, mutable bool) listNode[T] {
+func (n *vectorLeafNode[T]) deleteAfter(index int, mutable bool) vectorNode[T] {
if !n.containsAfter(index) {
return n
}
- idx := index & listNodeMask
- var other *listLeafNode[T]
+ idx := index & vectorNodeMask
+ var other *vectorLeafNode[T]
if mutable {
other = n
var empty T
@@ -529,7 +546,7 @@ func (n *listLeafNode[T]) deleteAfter(index int, mutable bool) listNode[T] {
other.children[i] = empty
}
} else {
- other = &listLeafNode[T]{occupied: n.occupied}
+ other = &vectorLeafNode[T]{occupied: n.occupied}
copy(other.children[:idx+1][:], n.children[:idx+1][:])
}
// Set bits after idx to 0. idx < 31 because n.containsAfter(index) == true.
@@ -537,55 +554,55 @@ func (n *listLeafNode[T]) deleteAfter(index int, mutable bool) listNode[T] {
return other
}
-// ListIterator represents an ordered iterator over a list.
-type ListIterator[T any] struct {
- list *List[T] // source list
+// VectorIterator represents an ordered iterator over a vector.
+type VectorIterator[T any] struct {
+ vector *Vector[T] // source vector
index int // current index position
- stack [32]listIteratorElem[T] // search stack
+ stack [32]vectorIteratorElem[T] // search stack
depth int // stack depth
}
// Done returns true if no more elements remain in the iterator.
-func (itr *ListIterator[T]) Done() bool {
- return itr.index < 0 || itr.index >= itr.list.Len()
+func (itr *VectorIterator[T]) Done() bool {
+ return itr.index < 0 || itr.index >= itr.vector.Len()
}
// First positions the iterator on the first index.
-// If source list is empty then no change is made.
-func (itr *ListIterator[T]) First() {
- if itr.list.Len() != 0 {
+// If source vector is empty then no change is made.
+func (itr *VectorIterator[T]) First() {
+ if itr.vector.Len() != 0 {
itr.Seek(0)
}
}
// Last positions the iterator on the last index.
-// If source list is empty then no change is made.
-func (itr *ListIterator[T]) Last() {
- if n := itr.list.Len(); n != 0 {
+// If source vector is empty then no change is made.
+func (itr *VectorIterator[T]) Last() {
+ if n := itr.vector.Len(); n != 0 {
itr.Seek(n - 1)
}
}
-// Seek moves the iterator position to the given index in the list.
+// Seek moves the iterator position to the given index in the vector.
// Similar to Go slices, this method will panic if index is below zero or if
-// the index is greater than or equal to the list size.
-func (itr *ListIterator[T]) Seek(index int) {
+// the index is greater than or equal to the vector size.
+func (itr *VectorIterator[T]) Seek(index int) {
// Panic similar to Go slices.
- if index < 0 || index >= itr.list.Len() {
- panic(fmt.Sprintf("immutable.ListIterator.Seek: index %d out of bounds", index))
+ if index < 0 || index >= itr.vector.Len() {
+ panic(fmt.Sprintf("immutable.VectorIterator.Seek: index %d out of bounds", index))
}
itr.index = index
// Reset to the bottom of the stack at seek to the correct position.
- itr.stack[0] = listIteratorElem[T]{node: itr.list.root}
+ itr.stack[0] = vectorIteratorElem[T]{node: itr.vector.root}
itr.depth = 0
itr.seek(index)
}
// Next returns the current index and its value & moves the iterator forward.
// Returns an index of -1 if the there are no more elements to return.
-func (itr *ListIterator[T]) Next() (index int, value T) {
+func (itr *VectorIterator[T]) Next() (index int, value T) {
// Exit immediately if there are no elements remaining.
var empty T
if itr.Done() {
@@ -594,7 +611,7 @@ func (itr *ListIterator[T]) Next() (index int, value T) {
// Retrieve current index & value.
elem := &itr.stack[itr.depth]
- index, value = itr.index, elem.node.(*listLeafNode[T]).children[elem.index]
+ index, value = itr.index, elem.node.(*vectorLeafNode[T]).children[elem.index]
// Increase index. If index is at the end then return immediately.
itr.index++
@@ -603,7 +620,7 @@ func (itr *ListIterator[T]) Next() (index int, value T) {
}
// Move up stack until we find a node that has remaining position ahead.
- for ; itr.depth > 0 && itr.stack[itr.depth].index >= listNodeSize-1; itr.depth-- {
+ for ; itr.depth > 0 && itr.stack[itr.depth].index >= vectorNodeSize-1; itr.depth-- {
}
// Seek to correct position from current depth.
@@ -614,7 +631,7 @@ func (itr *ListIterator[T]) Next() (index int, value T) {
// Prev returns the current index and value and moves the iterator backward.
// Returns an index of -1 if the there are no more elements to return.
-func (itr *ListIterator[T]) Prev() (index int, value T) {
+func (itr *VectorIterator[T]) Prev() (index int, value T) {
// Exit immediately if there are no elements remaining.
var empty T
if itr.Done() {
@@ -623,7 +640,7 @@ func (itr *ListIterator[T]) Prev() (index int, value T) {
// Retrieve current index & value.
elem := &itr.stack[itr.depth]
- index, value = itr.index, elem.node.(*listLeafNode[T]).children[elem.index]
+ index, value = itr.index, elem.node.(*vectorLeafNode[T]).children[elem.index]
// Decrease index. If index is past the beginning then return immediately.
itr.index--
@@ -643,26 +660,26 @@ func (itr *ListIterator[T]) Prev() (index int, value T) {
// seek positions the stack to the given index from the current depth.
// Elements and indexes below the current depth are assumed to be correct.
-func (itr *ListIterator[T]) seek(index int) {
+func (itr *VectorIterator[T]) seek(index int) {
// Iterate over each level until we reach a leaf node.
for {
elem := &itr.stack[itr.depth]
- elem.index = ((itr.list.origin + index) >> (elem.node.depth() * listNodeBits)) & listNodeMask
+ elem.index = ((itr.vector.origin + index) >> (elem.node.depth() * vectorNodeBits)) & vectorNodeMask
switch node := elem.node.(type) {
- case *listBranchNode[T]:
+ case *vectorBranchNode[T]:
child := node.children[elem.index]
- itr.stack[itr.depth+1] = listIteratorElem[T]{node: child}
+ itr.stack[itr.depth+1] = vectorIteratorElem[T]{node: child}
itr.depth++
- case *listLeafNode[T]:
+ case *vectorLeafNode[T]:
return
}
}
}
-// listIteratorElem represents the node and it's child index within the stack.
-type listIteratorElem[T any] struct {
- node listNode[T]
+// vectorIteratorElem represents the node and it's child index within the stack.
+type vectorIteratorElem[T any] struct {
+ node vectorNode[T]
index int
}
@@ -940,7 +957,7 @@ func (n *mapArrayNode[K, V]) set(key K, value V, shift uint, keyHash uint32, h H
}
// Update existing entry if a match is found.
- // Otherwise append to the end of the element list if it doesn't exist.
+ // Otherwise append to the end of the element vector if it doesn't exist.
var other mapArrayNode[K, V]
if idx != -1 {
other.entries = make([]mapEntry[K, V], len(n.entries))
@@ -1059,7 +1076,7 @@ func (n *mapBitmapIndexedNode[K, V]) set(key K, value V, shift uint, keyHash uin
}
// If node exists at given slot then overwrite it with new node.
- // Otherwise expand the node list and insert new node into appropriate position.
+ // Otherwise expand the node vector and insert new node into appropriate position.
other := &mapBitmapIndexedNode[K, V]{bitmap: n.bitmap | bit}
if exists {
other.nodes = make([]mapNode[K, V], len(n.nodes))
@@ -1113,7 +1130,7 @@ func (n *mapBitmapIndexedNode[K, V]) delete(key K, shift uint, keyHash uint32, h
return n
}
- // Return copy with bit removed from bitmap and node removed from node list.
+ // Return copy with bit removed from bitmap and node removed from node vector.
other := &mapBitmapIndexedNode[K, V]{bitmap: n.bitmap ^ bit, nodes: make([]mapNode[K, V], len(n.nodes)-1)}
copy(other.nodes[:idx], n.nodes[:idx])
copy(other.nodes[idx:], n.nodes[idx+1:])
@@ -2691,7 +2708,7 @@ func (s SortedSetBuilder[T]) Len() int {
}
// SortedSet returns the current copy of the set.
-// The builder should not be used again after the list after this call.
+// The builder should not be used again after the vector after this call.
func (s SortedSetBuilder[T]) SortedSet() SortedSet[T] {
assert(s.s != nil, "immutable.SortedSetBuilder.SortedSet(): duplicate call to fetch sorted set")
set := s.s
diff --git a/tests/benchmarks/list-append/main.go b/tests/benchmarks/vector-append/main.go
index f67563d..f67563d 120000
--- a/tests/benchmarks/list-append/main.go
+++ b/tests/benchmarks/vector-append/main.go
diff --git a/tests/benchmarks/list-append/pds.go b/tests/benchmarks/vector-append/pds.go
index a9b7690..58368b3 100644
--- a/tests/benchmarks/list-append/pds.go
+++ b/tests/benchmarks/vector-append/pds.go
@@ -16,7 +16,7 @@ func MainTest() {
flag.Parse()
n := *nFlag
- l := NewList[int]()
+ l := NewVector[int]()
for i := 0; i < n; i++ {
l = l.Append(i)
}
diff --git a/tests/benchmarks/list-builder-append/main.go b/tests/benchmarks/vector-builder-append/main.go
index f67563d..f67563d 120000
--- a/tests/benchmarks/list-builder-append/main.go
+++ b/tests/benchmarks/vector-builder-append/main.go
diff --git a/tests/benchmarks/list-builder-append/pds.go b/tests/benchmarks/vector-builder-append/pds.go
index 3357ee6..ab5cdec 100644
--- a/tests/benchmarks/list-builder-append/pds.go
+++ b/tests/benchmarks/vector-builder-append/pds.go
@@ -16,7 +16,7 @@ func MainTest() {
flag.Parse()
n := *nFlag
- builder := NewListBuilder[int]()
+ builder := NewVectorBuilder[int]()
for i := 0; i < n; i++ {
builder.Append(i)
}
diff --git a/tests/benchmarks/list-builder-prepend/main.go b/tests/benchmarks/vector-builder-prepend/main.go
index f67563d..f67563d 120000
--- a/tests/benchmarks/list-builder-prepend/main.go
+++ b/tests/benchmarks/vector-builder-prepend/main.go
diff --git a/tests/benchmarks/list-builder-prepend/pds.go b/tests/benchmarks/vector-builder-prepend/pds.go
index 572b6b6..9d1d669 100644
--- a/tests/benchmarks/list-builder-prepend/pds.go
+++ b/tests/benchmarks/vector-builder-prepend/pds.go
@@ -16,7 +16,7 @@ func MainTest() {
flag.Parse()
n := *nFlag
- builder := NewListBuilder[int]()
+ builder := NewVectorBuilder[int]()
for i := 0; i < n; i++ {
builder.Prepend(i)
}
diff --git a/tests/benchmarks/list-builder-set/main.go b/tests/benchmarks/vector-builder-set/main.go
index f67563d..f67563d 120000
--- a/tests/benchmarks/list-builder-set/main.go
+++ b/tests/benchmarks/vector-builder-set/main.go
diff --git a/tests/benchmarks/list-builder-set/pds.go b/tests/benchmarks/vector-builder-set/pds.go
index 4080e22..c4d5b2b 100644
--- a/tests/benchmarks/list-builder-set/pds.go
+++ b/tests/benchmarks/vector-builder-set/pds.go
@@ -16,7 +16,7 @@ func MainTest() {
flag.Parse()
n := *nFlag
- builder := NewListBuilder[int]()
+ builder := NewVectorBuilder[int]()
for i := 0; i < n; i++ {
builder.Append(i)
}
diff --git a/tests/benchmarks/list-iterator-backward/main.go b/tests/benchmarks/vector-iterator-backward/main.go
index f67563d..f67563d 120000
--- a/tests/benchmarks/list-iterator-backward/main.go
+++ b/tests/benchmarks/vector-iterator-backward/main.go
diff --git a/tests/benchmarks/list-iterator-backward/pds.go b/tests/benchmarks/vector-iterator-backward/pds.go
index 6ca51e4..a03e138 100644
--- a/tests/benchmarks/list-iterator-backward/pds.go
+++ b/tests/benchmarks/vector-iterator-backward/pds.go
@@ -16,7 +16,7 @@ func MainTest() {
flag.Parse()
n := *nFlag
- l := NewList[int]()
+ l := NewVector[int]()
for i := 0; i < n; i++ {
l = l.Append(i)
}
diff --git a/tests/benchmarks/list-iterator-forward/main.go b/tests/benchmarks/vector-iterator-forward/main.go
index f67563d..f67563d 120000
--- a/tests/benchmarks/list-iterator-forward/main.go
+++ b/tests/benchmarks/vector-iterator-forward/main.go
diff --git a/tests/benchmarks/list-iterator-forward/pds.go b/tests/benchmarks/vector-iterator-forward/pds.go
index 6831dad..298fd4e 100644
--- a/tests/benchmarks/list-iterator-forward/pds.go
+++ b/tests/benchmarks/vector-iterator-forward/pds.go
@@ -16,7 +16,7 @@ func MainTest() {
flag.Parse()
n := *nFlag
- l := NewList[int]()
+ l := NewVector[int]()
for i := 0; i < n; i++ {
l = l.Append(i)
}
diff --git a/tests/benchmarks/list-prepend/main.go b/tests/benchmarks/vector-prepend/main.go
index f67563d..f67563d 120000
--- a/tests/benchmarks/list-prepend/main.go
+++ b/tests/benchmarks/vector-prepend/main.go
diff --git a/tests/benchmarks/list-prepend/pds.go b/tests/benchmarks/vector-prepend/pds.go
index 918ff72..4f82cea 100644
--- a/tests/benchmarks/list-prepend/pds.go
+++ b/tests/benchmarks/vector-prepend/pds.go
@@ -16,7 +16,7 @@ func MainTest() {
flag.Parse()
n := *nFlag
- l := NewList[int]()
+ l := NewVector[int]()
for i := 0; i < n; i++ {
l = l.Prepend(i)
}
diff --git a/tests/benchmarks/list-set/main.go b/tests/benchmarks/vector-set/main.go
index f67563d..f67563d 120000
--- a/tests/benchmarks/list-set/main.go
+++ b/tests/benchmarks/vector-set/main.go
diff --git a/tests/benchmarks/list-set/pds.go b/tests/benchmarks/vector-set/pds.go
index e2d3709..ce0ee55 100644
--- a/tests/benchmarks/list-set/pds.go
+++ b/tests/benchmarks/vector-set/pds.go
@@ -16,7 +16,7 @@ func MainTest() {
flag.Parse()
n := *nFlag
- l := NewList[int]()
+ l := NewVector[int]()
for i := 0; i < n; i++ {
l = l.Append(i)
}
diff --git a/tests/functional/list-api/main.go b/tests/functional/vector-api/main.go
index f67563d..f67563d 120000
--- a/tests/functional/list-api/main.go
+++ b/tests/functional/vector-api/main.go
diff --git a/tests/functional/list-api/pds.go b/tests/functional/vector-api/pds.go
index c4290c8..aa37949 100644
--- a/tests/functional/list-api/pds.go
+++ b/tests/functional/vector-api/pds.go
@@ -7,8 +7,8 @@ import (
func MainTest() {
- g.Testing("NewList() - API usage", func() {
- l := NewList[string]().Append("foo").Append("bar").Append("baz")
+ g.Testing("NewVector() - API usage", func() {
+ l := NewVector[string]().Append("foo").Append("bar").Append("baz")
g.TAssertEqual(l.Get(0), "foo")
g.TAssertEqual(l.Get(1), "bar")
g.TAssertEqual(l.Get(2), "baz")
@@ -27,8 +27,8 @@ func MainTest() {
g.TAssertEqual(l.Len(), 2)
})
- g.Testing("NewList().Iterator() - API usage", func() {
- l := NewList[string]()
+ g.Testing("NewVector().Iterator() - API usage", func() {
+ l := NewVector[string]()
l = l.Append("foo")
l = l.Append("bar")
l = l.Append("baz")
diff --git a/tests/functional/list-builder-api/main.go b/tests/functional/vector-builder-api/main.go
index f67563d..f67563d 120000
--- a/tests/functional/list-builder-api/main.go
+++ b/tests/functional/vector-builder-api/main.go
diff --git a/tests/functional/list-builder-api/pds.go b/tests/functional/vector-builder-api/pds.go
index c7b632c..6dd8c2f 100644
--- a/tests/functional/list-builder-api/pds.go
+++ b/tests/functional/vector-builder-api/pds.go
@@ -8,44 +8,44 @@ import (
func MainTest() {
g.Testing("API usage", func() {
- b1 := NewListBuilder[string]()
+ b1 := NewVectorBuilder[string]()
b1.Append("foo")
b1.Append("bar")
b1.Append("baz")
- l1 := b1.List()
+ l1 := b1.Vector()
g.TAssertEqual(l1.Get(0), "foo")
g.TAssertEqual(l1.Get(1), "bar")
g.TAssertEqual(l1.Get(2), "baz")
- b2 := NewListBuilder[string]()
+ b2 := NewVectorBuilder[string]()
b2.Prepend("foo")
b2.Prepend("bar")
b2.Prepend("baz")
- l2 := b2.List()
+ l2 := b2.Vector()
g.TAssertEqual(l2.Get(0), "baz")
g.TAssertEqual(l2.Get(1), "bar")
g.TAssertEqual(l2.Get(2), "foo")
- b3 := NewListBuilder[string]()
+ b3 := NewVectorBuilder[string]()
b3.Append("foo")
b3.Append("bar")
b3.Set(1, "___")
- l3 := b3.List()
+ l3 := b3.Vector()
g.TAssertEqual(l3.Get(0), "foo")
g.TAssertEqual(l3.Get(1), "___")
- b4 := NewListBuilder[string]()
+ b4 := NewVectorBuilder[string]()
b4.Append("foo")
b4.Append("bar")
b4.Append("baz")
b4.Slice(1, 3)
- l4 := b4.List()
+ l4 := b4.Vector()
g.TAssertEqual(l4.Len(), 2)
g.TAssertEqual(l4.Get(0), "bar")
g.TAssertEqual(l4.Get(1), "baz")
diff --git a/tests/pds.go b/tests/pds.go
index 049edae..33ef400 100644
--- a/tests/pds.go
+++ b/tests/pds.go
@@ -15,50 +15,50 @@ import (
-func test_NewList() {
- g.TestStart("NewList[]()")
+func test_NewVector() {
+ g.TestStart("NewVector[]()")
- g.Testing("a brand new list starts empty", func() {
- g.TAssertEqual(NewList[int]().Len(), 0)
+ g.Testing("a brand new vector starts empty", func() {
+ g.TAssertEqual(NewVector[int]().Len(), 0)
})
}
-func TestList(t *testing.T) {
+func TestVector(t *testing.T) {
t.Run("Shallow", func(t *testing.T) {
- list := NewList[string]()
- list = list.Append("foo")
- if v := list.Get(0); v != "foo" {
+ vector := NewVector[string]()
+ vector = vector.Append("foo")
+ if v := vector.Get(0); v != "foo" {
t.Fatalf("unexpected value: %v", v)
}
- other := list.Append("bar")
+ other := vector.Append("bar")
if v := other.Get(0); v != "foo" {
t.Fatalf("unexpected value: %v", v)
} else if v := other.Get(1); v != "bar" {
t.Fatalf("unexpected value: %v", v)
}
- if v := list.Len(); v != 1 {
+ if v := vector.Len(); v != 1 {
t.Fatalf("unexpected value: %v", v)
}
})
t.Run("Deep", func(t *testing.T) {
- list := NewList[int]()
+ vector := NewVector[int]()
var array []int
const n = 1000 // FIXME: 100000 was too slow
for i := 0; i < n; i++ {
- list = list.Append(i)
+ vector = vector.Append(i)
array = append(array, i)
}
- if got, exp := len(array), list.Len(); got != exp {
- t.Fatalf("List.Len()=%d, exp %d", got, exp)
+ if got, exp := len(array), vector.Len(); got != exp {
+ t.Fatalf("Vector.Len()=%d, exp %d", got, exp)
}
for j := range array {
- if got, exp := list.Get(j), array[j]; got != exp {
+ if got, exp := vector.Get(j), array[j]; got != exp {
t.Fatalf(
- "%d. List.Get(%d)=%d, exp %d",
+ "%d. Vector.Get(%d)=%d, exp %d",
len(array),
j,
got,
@@ -69,18 +69,18 @@ func TestList(t *testing.T) {
})
t.Run("Set", func(t *testing.T) {
- list := NewList[string]()
- list = list.Append("foo")
- list = list.Append("bar")
+ vector := NewVector[string]()
+ vector = vector.Append("foo")
+ vector = vector.Append("bar")
- if v := list.Get(0); v != "foo" {
+ if v := vector.Get(0); v != "foo" {
t.Fatalf("unexpected value: %v", v)
}
- list = list.Set(0, "baz")
- if v := list.Get(0); v != "baz" {
+ vector = vector.Set(0, "baz")
+ if v := vector.Get(0); v != "baz" {
t.Fatalf("unexpected value: %v", v)
- } else if v := list.Get(1); v != "bar" {
+ } else if v := vector.Get(1); v != "bar" {
t.Fatalf("unexpected value: %v", v)
}
})
@@ -89,11 +89,11 @@ func TestList(t *testing.T) {
var r string
func() {
defer func() { r = recover().(string) }()
- l := NewList[string]()
+ l := NewVector[string]()
l = l.Append("foo")
l.Get(-1)
}()
- if r != `immutable.List.Get: index -1 out of bounds` {
+ if r != `immutable.Vector.Get: index -1 out of bounds` {
t.Fatalf("unexpected panic: %q", r)
}
})
@@ -102,11 +102,11 @@ func TestList(t *testing.T) {
var r string
func() {
defer func() { r = recover().(string) }()
- l := NewList[string]()
+ l := NewVector[string]()
l = l.Append("foo")
l.Get(1)
}()
- if r != `immutable.List.Get: index 1 out of bounds` {
+ if r != `immutable.Vector.Get: index 1 out of bounds` {
t.Fatalf("unexpected panic: %q", r)
}
})
@@ -115,11 +115,11 @@ func TestList(t *testing.T) {
var r string
func() {
defer func() { r = recover().(string) }()
- l := NewList[string]()
+ l := NewVector[string]()
l = l.Append("foo")
l.Set(1, "bar")
}()
- if r != `immutable.List.Set: index 1 out of bounds` {
+ if r != `immutable.Vector.Set: index 1 out of bounds` {
t.Fatalf("unexpected panic: %q", r)
}
})
@@ -128,11 +128,11 @@ func TestList(t *testing.T) {
var r string
func() {
defer func() { r = recover().(string) }()
- l := NewList[string]()
+ l := NewVector[string]()
l = l.Append("foo")
l.Slice(2, 3)
}()
- if r != `immutable.List.Slice: start index 2 out of bounds` {
+ if r != `immutable.Vector.Slice: start index 2 out of bounds` {
t.Fatalf("unexpected panic: %q", r)
}
})
@@ -141,11 +141,11 @@ func TestList(t *testing.T) {
var r string
func() {
defer func() { r = recover().(string) }()
- l := NewList[string]()
+ l := NewVector[string]()
l = l.Append("foo")
l.Slice(1, 3)
}()
- if r != `immutable.List.Slice: end index 3 out of bounds` {
+ if r != `immutable.Vector.Slice: end index 3 out of bounds` {
t.Fatalf("unexpected panic: %q", r)
}
})
@@ -154,25 +154,25 @@ func TestList(t *testing.T) {
var r string
func() {
defer func() { r = recover().(string) }()
- l := NewList[string]()
+ l := NewVector[string]()
l = l.Append("foo")
l = l.Append("bar")
l.Slice(2, 1)
}()
- if r != `immutable.List.Slice: invalid slice index: [2:1]` {
+ if r != `immutable.Vector.Slice: invalid slice index: [2:1]` {
t.Fatalf("unexpected panic: %q", r)
}
})
t.Run("SliceBeginning", func(t *testing.T) {
- l := NewList[string]()
+ l := NewVector[string]()
l = l.Append("foo")
l = l.Append("bar")
l = l.Slice(1, 2)
if got, exp := l.Len(), 1; got != exp {
- t.Fatalf("List.Len()=%d, exp %d", got, exp)
+ t.Fatalf("Vector.Len()=%d, exp %d", got, exp)
} else if got, exp := l.Get(0), "bar"; got != exp {
- t.Fatalf("List.Get(0)=%v, exp %v", got, exp)
+ t.Fatalf("Vector.Get(0)=%v, exp %v", got, exp)
}
})
@@ -180,35 +180,35 @@ func TestList(t *testing.T) {
var r string
func() {
defer func() { r = recover().(string) }()
- l := NewList[string]()
+ l := NewVector[string]()
l = l.Append("foo")
l.Iterator().Seek(-1)
}()
- if r != `immutable.ListIterator.Seek: index -1 out of bounds` {
+ if r != `immutable.VectorIterator.Seek: index -1 out of bounds` {
t.Fatalf("unexpected panic: %q", r)
}
})
t.Run("TestSliceFreesReferences", func(t *testing.T) {
- // Test that the leaf node in a sliced list contains zero'ed
+ // Test that the leaf node in a sliced vector contains zero'ed
// entries at the correct positions. To do this we directly
- // access the internal tree structure of the list.
- l := NewList[*int]()
+ // access the internal tree structure of the vector.
+ l := NewVector[*int]()
var ints [5]int
for i := 0; i < 5; i++ {
l = l.Append(&ints[i])
}
sl := l.Slice(2, 4)
- var findLeaf func(listNode[*int]) *listLeafNode[*int]
- findLeaf = func(n listNode[*int]) *listLeafNode[*int] {
+ var findLeaf func(vectorNode[*int]) *vectorLeafNode[*int]
+ findLeaf = func(n vectorNode[*int]) *vectorLeafNode[*int] {
switch n := n.(type) {
- case *listBranchNode[*int]:
+ case *vectorBranchNode[*int]:
if n.children[0] == nil {
t.Fatal("Failed to find leaf node due to nil child")
}
return findLeaf(n.children[0])
- case *listLeafNode[*int]:
+ case *vectorLeafNode[*int]:
return n
default:
panic("Unexpected case")
@@ -220,7 +220,7 @@ func TestList(t *testing.T) {
t.Errorf("Expected occupied to be 1100, was %032b", leaf.occupied)
}
- for i := 0; i < listNodeSize; i++ {
+ for i := 0; i < vectorNodeSize; i++ {
if 2 <= i && i < 4 {
if leaf.children[i] != &ints[i] {
t.Errorf("Position %v does not contain the right pointer?", i)
@@ -232,12 +232,12 @@ func TestList(t *testing.T) {
})
t.Run("AppendImmutable", func(t *testing.T) {
- outer_l := NewList[int]()
+ outer_l := NewVector[int]()
for N := 0; N < 1_000; N++ {
l1 := outer_l.Append(0)
outer_l.Append(1)
if actual := l1.Get(N); actual != 0 {
- t.Fatalf("Append mutates list with %d elements. Got %d instead of 0", N, actual)
+ t.Fatalf("Append mutates vector with %d elements. Got %d instead of 0", N, actual)
}
outer_l = outer_l.Append(0)
@@ -246,7 +246,7 @@ func TestList(t *testing.T) {
RunRandom(t, "Random", func(t *testing.T, rand *rand.Rand) {
const n = 100 // FIXME: 100000 was too slow
- l := newTList()
+ l := newTVector()
for i := 0; i < n; i++ {
rnd := rand.Intn(70)
switch {
@@ -269,29 +269,29 @@ func TestList(t *testing.T) {
})
}
-// TList represents a list that operates on a standard Go slice & immutable
-// list.
-type tList struct {
- im, prev *List[int]
- builder *ListBuilder[int]
+// TVector represents a vector that operates on a standard Go slice & immutable
+// vector.
+type tVector struct {
+ im, prev *Vector[int]
+ builder *VectorBuilder[int]
std []int
}
-// newTList returns a new instance of tList.
-func newTList() *tList {
- return &tList{
- im: NewList[int](),
- builder: NewListBuilder[int](),
+// newTVector returns a new instance of tVector.
+func newTVector() *tVector {
+ return &tVector{
+ im: NewVector[int](),
+ builder: NewVectorBuilder[int](),
}
}
-// Len returns the size of the list.
-func (l *tList) Len() int {
+// Len returns the size of the vector.
+func (l *tVector) Len() int {
return len(l.std)
}
// ChooseIndex returns a randomly chosen, valid index from the standard slice.
-func (l *tList) ChooseIndex(rand *rand.Rand) int {
+func (l *tVector) ChooseIndex(rand *rand.Rand) int {
if len(l.std) == 0 {
return -1
}
@@ -299,7 +299,7 @@ func (l *tList) ChooseIndex(rand *rand.Rand) int {
}
// ChooseSliceIndices returns randomly chosen, valid indices for slicing.
-func (l *tList) ChooseSliceIndices(rand *rand.Rand) (start, end int) {
+func (l *tVector) ChooseSliceIndices(rand *rand.Rand) (start, end int) {
if len(l.std) == 0 {
return 0, 0
}
@@ -308,40 +308,40 @@ func (l *tList) ChooseSliceIndices(rand *rand.Rand) (start, end int) {
return start, end
}
-// Append adds v to the end of slice and List.
-func (l *tList) Append(v int) {
+// Append adds v to the end of slice and Vector.
+func (l *tVector) Append(v int) {
l.prev = l.im
l.im = l.im.Append(v)
l.builder.Append(v)
l.std = append(l.std, v)
}
-// Prepend adds v to the beginning of the slice and List.
-func (l *tList) Prepend(v int) {
+// Prepend adds v to the beginning of the slice and Vector.
+func (l *tVector) Prepend(v int) {
l.prev = l.im
l.im = l.im.Prepend(v)
l.builder.Prepend(v)
l.std = append([]int{v}, l.std...)
}
-// Set updates the value at index i to v in the slice and List.
-func (l *tList) Set(i, v int) {
+// Set updates the value at index i to v in the slice and Vector.
+func (l *tVector) Set(i, v int) {
l.prev = l.im
l.im = l.im.Set(i, v)
l.builder.Set(i, v)
l.std[i] = v
}
-// Slice contracts the slice and List to the range of start/end indices.
-func (l *tList) Slice(start, end int) {
+// Slice contracts the slice and Vector to the range of start/end indices.
+func (l *tVector) Slice(start, end int) {
l.prev = l.im
l.im = l.im.Slice(start, end)
l.builder.Slice(start, end)
l.std = l.std[start:end]
}
-// Validate returns an error if the slice and List are different.
-func (l *tList) Validate() error {
+// Validate returns an error if the slice and Vector are different.
+func (l *tVector) Validate() error {
if got, exp := l.im.Len(), len(l.std); got != exp {
return fmt.Errorf("Len()=%v, expected %d", got, exp)
} else if got, exp := l.builder.Len(), len(l.std); got != exp {
@@ -352,7 +352,7 @@ func (l *tList) Validate() error {
if got, exp := l.im.Get(i), l.std[i]; got != exp {
return fmt.Errorf("Get(%d)=%v, expected %v", i, got, exp)
} else if got, exp := l.builder.Get(i), l.std[i]; got != exp {
- return fmt.Errorf("Builder.List/Get(%d)=%v, expected %v", i, got, exp)
+ return fmt.Errorf("Builder.Vector/Get(%d)=%v, expected %v", i, got, exp)
}
}
@@ -370,37 +370,37 @@ func (l *tList) Validate() error {
return nil
}
-func (l *tList) validateForwardIterator(typ string, itr *ListIterator[int]) error {
+func (l *tVector) validateForwardIterator(typ string, itr *VectorIterator[int]) error {
for i := range l.std {
if j, v := itr.Next(); i != j || l.std[i] != v {
- return fmt.Errorf("ListIterator.Next()=<%v,%v>, expected <%v,%v> [%s]", j, v, i, l.std[i], typ)
+ return fmt.Errorf("VectorIterator.Next()=<%v,%v>, expected <%v,%v> [%s]", j, v, i, l.std[i], typ)
}
done := i == len(l.std)-1
if v := itr.Done(); v != done {
- return fmt.Errorf("ListIterator.Done()=%v, expected %v [%s]", v, done, typ)
+ return fmt.Errorf("VectorIterator.Done()=%v, expected %v [%s]", v, done, typ)
}
}
if i, v := itr.Next(); i != -1 || v != 0 {
- return fmt.Errorf("ListIterator.Next()=<%v,%v>, expected DONE [%s]", i, v, typ)
+ return fmt.Errorf("VectorIterator.Next()=<%v,%v>, expected DONE [%s]", i, v, typ)
}
return nil
}
-func (l *tList) validateBackwardIterator(typ string, itr *ListIterator[int]) error {
+func (l *tVector) validateBackwardIterator(typ string, itr *VectorIterator[int]) error {
itr.Last()
for i := len(l.std) - 1; i >= 0; i-- {
if j, v := itr.Prev(); i != j || l.std[i] != v {
- return fmt.Errorf("ListIterator.Prev()=<%v,%v>, expected <%v,%v> [%s]", j, v, i, l.std[i], typ)
+ return fmt.Errorf("VectorIterator.Prev()=<%v,%v>, expected <%v,%v> [%s]", j, v, i, l.std[i], typ)
}
done := i == 0
if v := itr.Done(); v != done {
- return fmt.Errorf("ListIterator.Done()=%v, expected %v [%s]", v, done, typ)
+ return fmt.Errorf("VectorIterator.Done()=%v, expected %v [%s]", v, done, typ)
}
}
if i, v := itr.Prev(); i != -1 || v != 0 {
- return fmt.Errorf("ListIterator.Prev()=<%v,%v>, expected DONE [%s]", i, v, typ)
+ return fmt.Errorf("VectorIterator.Prev()=<%v,%v>, expected DONE [%s]", i, v, typ)
}
return nil
}
@@ -2030,10 +2030,10 @@ func TestSortedSetBuilder(t *testing.T) {
func MainTest() {
- test_NewList()
+ test_NewVector()
tests := []testing.InternalTest{
- { "TestList", TestList },
+ { "TestVector", TestVector },
{ "TestInternal_mapNode_Overwrite", TestInternal_mapNode_Overwrite },
{ "TestInternal_mapArrayNode", TestInternal_mapArrayNode },
{ "TestInternal_mapValueNode", TestInternal_mapValueNode },