Documentation ¶
Overview ¶
Package immutable provides immutable collection types.
Introduction ¶
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 and maps, respectively, except that altering a collection returns a new copy of the collection with that change.
Because collections are unable to change, they are safe for multiple goroutines to read from at the same time without a mutex. However, these types of collections come with increased CPU & memory usage as compared with Go's built-in collection types so please evaluate for your specific use.
Collection Types ¶
The List 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.
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. Values can be fetched by key and key/value pairs can be iterated over using the appropriate iterator type. Both map types provide the same API. The SortedMap, however, provides iteration over sorted keys while the Map provides iteration over unsorted keys. Maps improved performance and memory usage as compared to SortedMaps.
Hashing and Sorting ¶
Map types require the use of a Hasher implementation to calculate hashes for their keys and check for key equality. SortedMaps require the use of a Comparer implementation to sort keys in the map.
These collection types automatically provide built-in hasher and comparers for int, string, and byte slice keys. If you are using one of these key types then simply pass a nil into the constructor. Otherwise you will need to implement a custom Hasher or Comparer type. Please see the provided implementations for reference.
Index ¶
- type Comparer
- type Hasher
- type List
- type ListBuilder
- func (b *ListBuilder) Append(value interface{})
- func (b *ListBuilder) Get(index int) interface{}
- func (b *ListBuilder) Len() int
- func (b *ListBuilder) List() *List
- func (b *ListBuilder) Prepend(value interface{})
- func (b *ListBuilder) Set(index int, value interface{})
- func (b *ListBuilder) Slice(start, end int)
- type ListIterator
- type Map
- type MapBuilder
- type MapIterator
- type SortedMap
- type SortedMapBuilder
- type SortedMapIterator
Examples ¶
- List.Append
- List.Iterator
- List.Iterator (Reverse)
- List.Prepend
- List.Set
- List.Slice
- ListBuilder.Append
- ListBuilder.Prepend
- ListBuilder.Set
- ListBuilder.Slice
- Map.Delete
- Map.Iterator
- Map.Set
- MapBuilder.Delete
- MapBuilder.Set
- SortedMap.Delete
- SortedMap.Iterator
- SortedMap.Set
- SortedMapBuilder.Delete
- SortedMapBuilder.Set
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Comparer ¶
type Comparer interface { // Returns -1 if a is less than b, returns 1 if a is greater than b, // and returns 0 if a is equal to b. Compare(a, b interface{}) int }
Comparer allows the comparison of two keys for the purpose of sorting.
type Hasher ¶
type Hasher interface { // Computes a 32-bit hash for key. Hash(key interface{}) uint32 // Returns true if a and b are equal. Equal(a, b interface{}) bool }
Hasher hashes keys and checks them for equality.
type List ¶
type List struct {
// contains filtered or unexported fields
}
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.
func (*List) Append ¶
Append returns a new list with value added to the end of the list.
Example ¶
l := NewList() l = l.Append("foo") l = l.Append("bar") l = l.Append("baz") fmt.Println(l.Get(0)) fmt.Println(l.Get(1)) fmt.Println(l.Get(2))
Output: foo bar baz
func (*List) Get ¶
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 (*List) Iterator ¶
func (l *List) Iterator() *ListIterator
Iterator returns a new iterator for this list positioned at the first index.
Example ¶
l := NewList() l = l.Append("foo") l = l.Append("bar") l = l.Append("baz") itr := l.Iterator() for !itr.Done() { i, v := itr.Next() fmt.Println(i, v) }
Output: 0 foo 1 bar 2 baz
Example (Reverse) ¶
l := NewList() l = l.Append("foo") l = l.Append("bar") l = l.Append("baz") itr := l.Iterator() itr.Last() for !itr.Done() { i, v := itr.Prev() fmt.Println(i, v) }
Output: 2 baz 1 bar 0 foo
func (*List) Prepend ¶
Prepend returns a new list with value added to the beginning of the list.
Example ¶
l := NewList() l = l.Prepend("foo") l = l.Prepend("bar") l = l.Prepend("baz") fmt.Println(l.Get(0)) fmt.Println(l.Get(1)) fmt.Println(l.Get(2))
Output: baz bar foo
func (*List) Set ¶
Set returns a new list 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.
Example ¶
l := NewList() l = l.Append("foo") l = l.Append("bar") l = l.Set(1, "baz") fmt.Println(l.Get(0)) fmt.Println(l.Get(1))
Output: foo baz
func (*List) Slice ¶
Slice returns a new list 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.
Unlike Go slices, references to inaccessible elements will be automatically removed so they can be garbage collected.
Example ¶
l := NewList() l = l.Append("foo") l = l.Append("bar") l = l.Append("baz") l = l.Slice(1, 3) fmt.Println(l.Get(0)) fmt.Println(l.Get(1))
Output: bar baz
type ListBuilder ¶
type ListBuilder struct {
// contains filtered or unexported fields
}
ListBuilder represents an efficient builder for creating Lists.
Lists returned from the builder are safe to use even after you continue to use the builder. However, for efficiency, you should only retrieve your list after you have completed building it.
func NewListBuilder ¶
func NewListBuilder(list *List) *ListBuilder
NewListBuilder returns a new instance of ListBuilder to build on a base list.
func (*ListBuilder) Append ¶
func (b *ListBuilder) Append(value interface{})
Append adds value to the end of the list.
Example ¶
b := NewListBuilder(NewList()) b.Append("foo") b.Append("bar") b.Append("baz") l := b.List() fmt.Println(l.Get(0)) fmt.Println(l.Get(1)) fmt.Println(l.Get(2))
Output: foo bar baz
func (*ListBuilder) Get ¶
func (b *ListBuilder) Get(index int) interface{}
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 (*ListBuilder) Len ¶
func (b *ListBuilder) Len() int
Len returns the number of elements in the underlying list.
func (*ListBuilder) List ¶
func (b *ListBuilder) List() *List
List returns the current copy of the list. The returned list is safe to use even if after the builder continues to be used.
func (*ListBuilder) Prepend ¶
func (b *ListBuilder) Prepend(value interface{})
Prepend adds value to the beginning of the list.
Example ¶
b := NewListBuilder(NewList()) b.Prepend("foo") b.Prepend("bar") b.Prepend("baz") l := b.List() fmt.Println(l.Get(0)) fmt.Println(l.Get(1)) fmt.Println(l.Get(2))
Output: baz bar foo
func (*ListBuilder) Set ¶
func (b *ListBuilder) Set(index int, value interface{})
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.
Example ¶
b := NewListBuilder(NewList()) b.Append("foo") b.Append("bar") b.Set(1, "baz") l := b.List() fmt.Println(l.Get(0)) fmt.Println(l.Get(1))
Output: foo baz
func (*ListBuilder) Slice ¶
func (b *ListBuilder) Slice(start, end int)
Slice updates the list with a sublist of elements between start and end index. See List.Slice() for more details.
Example ¶
b := NewListBuilder(NewList()) b.Append("foo") b.Append("bar") b.Append("baz") b.Slice(1, 3) l := b.List() fmt.Println(l.Get(0)) fmt.Println(l.Get(1))
Output: bar baz
type ListIterator ¶
type ListIterator struct {
// contains filtered or unexported fields
}
ListIterator represents an ordered iterator over a list.
func (*ListIterator) Done ¶
func (itr *ListIterator) Done() bool
Done returns true if no more elements remain in the iterator.
func (*ListIterator) First ¶
func (itr *ListIterator) First()
First positions the iterator on the first index. If source list is empty then no change is made.
func (*ListIterator) Last ¶
func (itr *ListIterator) Last()
Last positions the iterator on the last index. If source list is empty then no change is made.
func (*ListIterator) Next ¶
func (itr *ListIterator) Next() (index int, value interface{})
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 (*ListIterator) Prev ¶
func (itr *ListIterator) Prev() (index int, value interface{})
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 (*ListIterator) Seek ¶
func (itr *ListIterator) Seek(index int)
Seek moves the iterator position to the given index in the list. 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.
type Map ¶
type Map struct {
// contains filtered or unexported fields
}
Map represents an immutable hash map implementation. The map uses a Hasher to generate hashes and check for equality of key values.
It is implemented as an Hash Array Mapped Trie.
func NewMap ¶
NewMap returns a new instance of Map. If hasher is nil, a default hasher implementation will automatically be chosen based on the first key added. Default hasher implementations only exist for int, string, and byte slice types.
func (*Map) Delete ¶
Delete returns a map with the given key removed. Removing a non-existent key will cause this method to return the same map.
Example ¶
m := NewMap(nil) m = m.Set("foo", "bar") m = m.Set("baz", 100) m = m.Delete("baz") v, ok := m.Get("foo") fmt.Println("foo", v, ok) v, ok = m.Get("baz") fmt.Println("baz", v, ok)
Output: foo bar true baz <nil> false
func (*Map) Get ¶
Get returns the value for a given key and a flag indicating whether the key exists. This flag distinguishes a nil value set on a key versus a non-existent key in the map.
func (*Map) Iterator ¶
func (m *Map) Iterator() *MapIterator
Iterator returns a new iterator for the map.
Example ¶
m := NewMap(nil) m = m.Set("apple", 100) m = m.Set("grape", 200) m = m.Set("kiwi", 300) m = m.Set("mango", 400) m = m.Set("orange", 500) m = m.Set("peach", 600) m = m.Set("pear", 700) m = m.Set("pineapple", 800) m = m.Set("strawberry", 900) itr := m.Iterator() for !itr.Done() { k, v := itr.Next() fmt.Println(k, v) }
Output: mango 400 pear 700 pineapple 800 grape 200 orange 500 strawberry 900 kiwi 300 peach 600 apple 100
func (*Map) Set ¶
Set returns a map with the key set to the new value. A nil value is allowed.
This function will return a new map even if the updated value is the same as the existing value because Map does not track value equality.
Example ¶
m := NewMap(nil) m = m.Set("foo", "bar") m = m.Set("baz", 100) v, ok := m.Get("foo") fmt.Println("foo", v, ok) v, ok = m.Get("baz") fmt.Println("baz", v, ok) v, ok = m.Get("bat") // does not exist fmt.Println("bat", v, ok)
Output: foo bar true baz 100 true bat <nil> false
type MapBuilder ¶
type MapBuilder struct {
// contains filtered or unexported fields
}
MapBuilder represents an efficient builder for creating Maps.
Maps returned from the builder are safe to use even after you continue to use the builder. However, for efficiency, you should only retrieve your map after you have completed building it.
func NewMapBuilder ¶
func NewMapBuilder(m *Map) *MapBuilder
NewMapBuilder returns a new instance of MapBuilder to build on a base map.
func (*MapBuilder) Delete ¶
func (b *MapBuilder) Delete(key interface{})
Delete removes the given key. See Map.Delete() for additional details.
Example ¶
b := NewMapBuilder(NewMap(nil)) b.Set("foo", "bar") b.Set("baz", 100) b.Delete("baz") m := b.Map() v, ok := m.Get("foo") fmt.Println("foo", v, ok) v, ok = m.Get("baz") fmt.Println("baz", v, ok)
Output: foo bar true baz <nil> false
func (*MapBuilder) Get ¶
func (b *MapBuilder) Get(key interface{}) (value interface{}, ok bool)
Get returns the value for the given key.
func (*MapBuilder) Len ¶
func (b *MapBuilder) Len() int
Len returns the number of elements in the underlying map.
func (*MapBuilder) Map ¶
func (b *MapBuilder) Map() *Map
Map returns the current copy of the map. The returned map is safe to use even if after the builder continues to be used.
func (*MapBuilder) Set ¶
func (b *MapBuilder) Set(key, value interface{})
Set sets the value of the given key. See Map.Set() for additional details.
Example ¶
b := NewMapBuilder(NewMap(nil)) b.Set("foo", "bar") b.Set("baz", 100) m := b.Map() v, ok := m.Get("foo") fmt.Println("foo", v, ok) v, ok = m.Get("baz") fmt.Println("baz", v, ok) v, ok = m.Get("bat") // does not exist fmt.Println("bat", v, ok)
Output: foo bar true baz 100 true bat <nil> false
type MapIterator ¶
type MapIterator struct {
// contains filtered or unexported fields
}
MapIterator represents an iterator over a map's key/value pairs. Although map keys are not sorted, the iterator's order is deterministic.
func (*MapIterator) Done ¶
func (itr *MapIterator) Done() bool
Done returns true if no more elements remain in the iterator.
func (*MapIterator) First ¶
func (itr *MapIterator) First()
First resets the iterator to the first key/value pair.
func (*MapIterator) Next ¶
func (itr *MapIterator) Next() (key, value interface{})
Next returns the next key/value pair. Returns a nil key when no elements remain.
type SortedMap ¶
type SortedMap struct {
// contains filtered or unexported fields
}
SortedMap represents a map of key/value pairs sorted by key. The sort order is determined by the Comparer used by the map.
This map is implemented as a B+tree.
func NewSortedMap ¶
NewSortedMap returns a new instance of SortedMap. If comparer is nil then a default comparer is set after the first key is inserted. Default comparers exist for int, string, and byte slice keys.
func (*SortedMap) Delete ¶
Delete returns a copy of the map with the key removed. Returns the original map if key does not exist.
Example ¶
m := NewSortedMap(nil) m = m.Set("foo", "bar") m = m.Set("baz", 100) m = m.Delete("baz") v, ok := m.Get("foo") fmt.Println("foo", v, ok) v, ok = m.Get("baz") fmt.Println("baz", v, ok)
Output: foo bar true baz <nil> false
func (*SortedMap) Get ¶
Get returns the value for a given key and a flag indicating if the key is set. The flag can be used to distinguish between a nil-set key versus an unset key.
func (*SortedMap) Iterator ¶
func (m *SortedMap) Iterator() *SortedMapIterator
Iterator returns a new iterator for this map positioned at the first key.
Example ¶
m := NewSortedMap(nil) m = m.Set("strawberry", 900) m = m.Set("kiwi", 300) m = m.Set("apple", 100) m = m.Set("pear", 700) m = m.Set("pineapple", 800) m = m.Set("peach", 600) m = m.Set("orange", 500) m = m.Set("grape", 200) m = m.Set("mango", 400) itr := m.Iterator() for !itr.Done() { k, v := itr.Next() fmt.Println(k, v) }
Output: apple 100 grape 200 kiwi 300 mango 400 orange 500 peach 600 pear 700 pineapple 800 strawberry 900
func (*SortedMap) Set ¶
Set returns a copy of the map with the key set to the given value.
Example ¶
m := NewSortedMap(nil) m = m.Set("foo", "bar") m = m.Set("baz", 100) v, ok := m.Get("foo") fmt.Println("foo", v, ok) v, ok = m.Get("baz") fmt.Println("baz", v, ok) v, ok = m.Get("bat") // does not exist fmt.Println("bat", v, ok)
Output: foo bar true baz 100 true bat <nil> false
type SortedMapBuilder ¶
type SortedMapBuilder struct {
// contains filtered or unexported fields
}
SortedMapBuilder represents an efficient builder for creating sorted maps.
Maps returned from the builder are safe to use even after you continue to use the builder. However, for efficiency, you should only retrieve your map after you have completed building it.
func NewSortedMapBuilder ¶
func NewSortedMapBuilder(m *SortedMap) *SortedMapBuilder
NewSortedMapBuilder returns a new instance of SortedMapBuilder to build on a base map.
func (*SortedMapBuilder) Delete ¶
func (b *SortedMapBuilder) Delete(key interface{})
Delete removes the given key. See SortedMap.Delete() for additional details.
Example ¶
b := NewSortedMapBuilder(NewSortedMap(nil)) b.Set("foo", "bar") b.Set("baz", 100) b.Delete("baz") m := b.Map() v, ok := m.Get("foo") fmt.Println("foo", v, ok) v, ok = m.Get("baz") fmt.Println("baz", v, ok)
Output: foo bar true baz <nil> false
func (*SortedMapBuilder) Get ¶
func (b *SortedMapBuilder) Get(key interface{}) (value interface{}, ok bool)
Get returns the value for the given key.
func (*SortedMapBuilder) Len ¶
func (b *SortedMapBuilder) Len() int
Len returns the number of elements in the underlying map.
func (*SortedMapBuilder) Map ¶
func (b *SortedMapBuilder) Map() *SortedMap
SortedMap returns the current copy of the map. The returned map is safe to use even if after the builder continues to be used.
func (*SortedMapBuilder) Set ¶
func (b *SortedMapBuilder) Set(key, value interface{})
Set sets the value of the given key. See SortedMap.Set() for additional details.
Example ¶
b := NewSortedMapBuilder(NewSortedMap(nil)) b.Set("foo", "bar") b.Set("baz", 100) m := b.Map() v, ok := m.Get("foo") fmt.Println("foo", v, ok) v, ok = m.Get("baz") fmt.Println("baz", v, ok) v, ok = m.Get("bat") // does not exist fmt.Println("bat", v, ok)
Output: foo bar true baz 100 true bat <nil> false
type SortedMapIterator ¶
type SortedMapIterator struct {
// contains filtered or unexported fields
}
SortedMapIterator represents an iterator over a sorted map. Iteration can occur in natural or reverse order based on use of Next() or Prev().
func (*SortedMapIterator) Done ¶
func (itr *SortedMapIterator) Done() bool
Done returns true if no more key/value pairs remain in the iterator.
func (*SortedMapIterator) First ¶
func (itr *SortedMapIterator) First()
First moves the iterator to the first key/value pair.
func (*SortedMapIterator) Last ¶
func (itr *SortedMapIterator) Last()
Last moves the iterator to the last key/value pair.
func (*SortedMapIterator) Next ¶
func (itr *SortedMapIterator) Next() (key, value interface{})
Next returns the current key/value pair and moves the iterator forward. Returns a nil key if the there are no more elements to return.
func (*SortedMapIterator) Prev ¶
func (itr *SortedMapIterator) Prev() (key, value interface{})
Prev returns the current key/value pair and moves the iterator backward. Returns a nil key if the there are no more elements to return.
func (*SortedMapIterator) Seek ¶
func (itr *SortedMapIterator) Seek(key interface{})
Seek moves the iterator position to the given key in the map. If the key does not exist then the next key is used. If no more keys exist then the iteartor is marked as done.