Documentation ¶
Overview ¶
Package amt implements the Hash Array Mapped Trie (HAMT) in Go (1.18+ generics).
See "Ideal Hash Trees" (Phil Bagwell, 2001) for an overview of the implementation, advantages, and disadvantages of HAMTs.
The AMT implementation has a natural cardinality of 16 for the root trie and all sub-tries; each AMT level is indexed by 4 hash bits. The depth of a map or set will be on the order of log16(N).
This package uses unsafe pointers/pointer-arithmetic extensively, so it is inherently unsafe and not guaranteed to work today or tomorrow. Unsafe pointers enable a compact memory layout with fewer allocations, and effectively reduce the depth of a map or set by reducing the number of pointers dereferenced along the path to a key or value. No attention is paid to 32-bit architectures since it's now the year 2000, but compatibility may still be there.
An alternative approach, using an interface type to represent either a key-value pair or entry slice (sub-trie), has a few drawbacks. Interface values are the size of 2 pointers (versus 1 when using unsafe pointers), which would increase the memory overhead for key-value/sub-trie entries by 50% (e.g. 24 bytes versus 16 bytes on 64-bit architectures). If the interface value is assigned a slice of entries (sub-trie), a new allocation (the size of 3 pointers) is required for the slice-header before it can be wrapped into the interface value. Accessing an entry slice (sub-trie) through an interface value requires (1) dereferencing the interface's data pointer to get to the slice-header (among other things), then (2) dereferencing the slice-header's data pointer to access an entry in the slice. Unsafe pointers eliminate the extra allocation and overhead of (1), allowing entries to point directly to either a key-value struct or an array of entries. Generics enable a type-safe implementation, where the key-value type of a map or set is fixed after instantiation.
The memory layouts of Go interfaces and slices are detailed in the following articles:
Go Data Structures: Interfaces (Russ Cox): https://research.swtch.com/interfaces Go Slices: usage and internals (Andrew Gerrand): https://go.dev/blog/slices-intro Go internals: invariance and memory layout of slices (Eli Bendersky): https://eli.thegreenplace.net/2021/go-internals-invariance-and-memory-layout-of-slices/
Index ¶
- func HashBytes(key []byte, seed maphash.Seed, iter uint) uint64
- type ArrKey
- type ArrMap
- func (m ArrMap[K, V]) All(do func(K, *V) bool)
- func (m ArrMap[K, V]) Del(key K)
- func (m ArrMap[K, V]) Dep() float64
- func (m ArrMap[K, V]) Get(key K) (value V, ok bool)
- func (m ArrMap[K, V]) Len() uint
- func (m ArrMap[K, V]) Mod(key K, mod func(*V, bool))
- func (m ArrMap[K, V]) Nil() bool
- func (m ArrMap[K, V]) Ptr(key K) *V
- func (m ArrMap[K, V]) Set(key K, value V)
- func (m ArrMap[K, V]) Val(key K) (value V)
- type ArrSet
- type Bytes
- type BytesMap
- func (m BytesMap[V]) All(do func([]byte, *V) bool)
- func (m BytesMap[V]) Del(key []byte)
- func (m BytesMap[V]) Dep() float64
- func (m BytesMap[V]) Get(key []byte) (value V, ok bool)
- func (m BytesMap[V]) Len() uint
- func (m BytesMap[V]) Mod(key []byte, mod func(*V, bool))
- func (m BytesMap[V]) Nil() bool
- func (m BytesMap[V]) Ptr(key []byte) *V
- func (m BytesMap[V]) Set(key []byte, value V)
- func (m BytesMap[V]) Val(key []byte) (value V)
- type BytesSet
- type Int
- type IntKey
- type IntMap
- func (m IntMap[V]) All(do func(IntKey, *V) bool)
- func (m IntMap[V]) Del(key IntKey)
- func (m IntMap[V]) Dep() float64
- func (m IntMap[V]) Get(key IntKey) (value V, ok bool)
- func (m IntMap[V]) Len() uint
- func (m IntMap[V]) Mod(key IntKey, mod func(*V, bool))
- func (m IntMap[V]) Nil() bool
- func (m IntMap[V]) Ptr(key IntKey) *V
- func (m IntMap[V]) Set(key IntKey, value V)
- func (m IntMap[V]) Val(key IntKey) (value V)
- type IntSet
- type Key
- type Map
- func (m Map[K, V]) All(do func(K, *V) bool)
- func (m Map[K, V]) Del(key K)
- func (m Map[K, V]) Dep() float64
- func (m Map[K, V]) Get(key K) (value V, ok bool)
- func (m Map[K, V]) Len() uint
- func (m Map[K, V]) Mod(key K, mod func(*V, bool))
- func (m Map[K, V]) Nil() bool
- func (m Map[K, V]) Ptr(key K) *V
- func (m Map[K, V]) Set(key K, value V)
- func (m Map[K, V]) Val(key K) (value V)
- type Set
- type String
- type StringMap
- func (m StringMap[V]) All(do func(string, *V) bool)
- func (m StringMap[V]) Del(key string)
- func (m StringMap[V]) Dep() float64
- func (m StringMap[V]) Get(key string) (value V, ok bool)
- func (m StringMap[V]) Len() uint
- func (m StringMap[V]) Mod(key string, mod func(*V, bool))
- func (m StringMap[V]) Nil() bool
- func (m StringMap[V]) Ptr(key string) *V
- func (m StringMap[V]) Set(key string, value V)
- func (m StringMap[V]) Val(key string) (value V)
- type StringSet
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type ArrKey ¶
type ArrKey interface { comparable KeyBytes() [64]byte }
ArrKey is a key with a method which converts the key to a fixed-size array for hashing, used as the key type of an ArrMap[K, V]. For byte-array keys with length up to 64 bytes, ArrMap[K, V] may be suitable.
type ArrMap ¶
ArrMap maps byte arrays to values. Methods on a map value will panic if the map is not initialized. A map value is safe to copy.
func (ArrMap[K, V]) All ¶
All ranges over values in m, applying the do callback to each value until the callback returns false or all values have been visited. The iteration order is not randomized for each call.
func (ArrMap[K, V]) Dep ¶
Dep returns the average (mean) depth of all values in m. If m is not initialized, Dep returns 0.
func (ArrMap[K, V]) Get ¶
Get returns the value for key, or a zero value and false if the key is missing.
func (ArrMap[K, V]) Len ¶
Len returns the number of values in m. If m is not initialized, Len returns 0.
func (ArrMap[K, V]) Mod ¶
Mod modifies the value for key using the mod callback. The mod callback receives a pointer to the existing or new value for key, and true if the key existed.
func (ArrMap[K, V]) Ptr ¶
func (m ArrMap[K, V]) Ptr(key K) *V
Ptr returns a pointer to the value for key, or nil if the key is missing. The value may be updated through the returned pointer.
type ArrSet ¶
type ArrSet[K ArrKey] struct { // contains filtered or unexported fields }
ArrSet contains a set of byte arrays. Methods on a set value will panic if the set is not initialized. A set value is safe to copy.
func (ArrSet[K]) All ¶
All ranges over keys in s, applying the do callback to each key until the callback returns false or all keys have been visited. The iteration order is not randomized for each call.
func (ArrSet[K]) Dep ¶
Dep returns the average (mean) depth of all keys in s. If s is not initialized, Dep returns 0.
type BytesMap ¶
type BytesMap[V any] struct { // contains filtered or unexported fields }
BytesMap maps byte slices to values. Methods on a map value will panic if the map is not initialized. Key slices will be retained in a map, and must not be modified after they are added. A map value is safe to copy.
func NewBytesMap ¶
NewBytesMap returns an initialized map. The map value is safe to copy.
func (BytesMap[V]) All ¶
All ranges over values in m, applying the do callback to each value until the callback returns false or all values have been visited. The iteration order is not randomized for each call.
func (BytesMap[V]) Dep ¶
Dep returns the average (mean) depth of all values in m. If m is not initialized, Dep returns 0.
func (BytesMap[V]) Get ¶
Get returns the value for key, or a zero value and false if the key is missing.
func (BytesMap[V]) Len ¶
Len returns the number of values in m. If m is not initialized, Len returns 0.
func (BytesMap[V]) Mod ¶
Mod modifies the value for key using the mod callback. The mod callback receives a pointer to the existing or new value for key, and true if the key existed. The key slice may be retained in m, and must not be modified after the key is added.
func (BytesMap[V]) Ptr ¶
Ptr returns a pointer to the value for key, or nil if the key is missing. The value may be updated through the returned pointer.
type BytesSet ¶
type BytesSet struct {
// contains filtered or unexported fields
}
BytesSet contains a set of byte slices. Methods on a set value will panic if the set is not initialized. Key slices will be retained in a set, and must not be modified after they are added. A set value is safe to copy.
func NewBytesSet ¶
func NewBytesSet() BytesSet
NewBytesSet returns an initialized set. The set value is safe to copy.
func (BytesSet) Add ¶
Add adds key to s. The key slice will be retained in s, and must not be modified after the key is added.
func (BytesSet) All ¶
All ranges over keys in s, applying the do callback to each key until the callback returns false or all keys have been visited. The iteration order is not randomized for each call.
func (BytesSet) Dep ¶
Dep returns the average (mean) depth of all keys in s. If s is not initialized, Dep returns 0.
type IntMap ¶
type IntMap[V any] struct { // contains filtered or unexported fields }
IntMap maps integers to values. Methods on a map value will panic if the map is not initialized. A map value is safe to copy.
func (IntMap[V]) All ¶
All ranges over values in m, applying the do callback to each value until the callback returns false or all values have been visited. The iteration order is not randomized for each call.
func (IntMap[V]) Dep ¶
Dep returns the average (mean) depth of all values in m. If m is not initialized, Dep returns 0.
func (IntMap[V]) Get ¶
Get returns the value for key, or a zero value and false if the key is missing.
func (IntMap[V]) Len ¶
Len returns the number of values in m. If m is not initialized, Len returns 0.
func (IntMap[V]) Mod ¶
Mod modifies the value for key using the mod callback. The mod callback receives a pointer to the existing or new value for key, and true if the key existed.
func (IntMap[V]) Ptr ¶
Ptr returns a pointer to the value for key, or nil if the key is missing. The value may be updated through the returned pointer.
type IntSet ¶
type IntSet struct {
// contains filtered or unexported fields
}
IntSet contains a set of integers. Methods on a set value will panic if the set is not initialized. A set value is safe to copy.
func NewIntSet ¶
func NewIntSet() IntSet
NewIntSet returns an initialized set. The set value is safe to copy.
func (IntSet) All ¶
All ranges over keys in s, applying the do callback to each key until the callback returns false or all keys have been visited. The iteration order is not randomized for each call.
func (IntSet) Dep ¶
Dep returns the average (mean) depth of all keys in s. If s is not initialized, Dep returns 0.
type Key ¶
type Key[K any] interface { // Equal must return true if the key is equal to a comparison key. Equal(K) bool // Hash must hash the key 1 or more times. The iter count indicates the number of times the key // must be rehashed. For the initial hash the iter count will be zero. Hash(seed maphash.Seed, iter uint) uint64 }
Key may be used as the key type of a generic Map[K, V].
type Map ¶
Map maps hashable keys to values. Methods on a map value will panic if the map is not initialized. A map value is safe to copy.
func (Map[K, V]) All ¶
All ranges over values in m, applying the do callback to each value until the callback returns false or all values have been visited. The iteration order is not randomized for each call.
func (Map[K, V]) Dep ¶
Dep returns the average (mean) depth of all values in m. If m is not initialized, Dep returns 0.
func (Map[K, V]) Get ¶
Get returns the value for key, or a zero value and false if the key is missing.
func (Map[K, V]) Len ¶
Len returns the number of values in m. If m is not initialized, Len returns 0.
func (Map[K, V]) Mod ¶
Mod modifies the value for key using the mod callback. The mod callback receives a pointer to the existing or new value for key, and true if the key existed.
func (Map[K, V]) Ptr ¶
func (m Map[K, V]) Ptr(key K) *V
Ptr returns a pointer to the value for key, or nil if the key is missing. The value may be updated through the returned pointer.
type Set ¶
type Set[K Key[K]] struct { // contains filtered or unexported fields }
Set contains a set of keys. Methods on a set value will panic if the set is not initialized. A set value is safe to copy.
func (Set[K]) All ¶
All ranges over keys in s, applying the do callback to each key until the callback returns false or all keys have been visited. The iteration order is not randomized for each call.
func (Set[K]) Dep ¶
Dep returns the average (mean) depth of all keys in s. If s is not initialized, Dep returns 0.
type StringMap ¶
type StringMap[V any] struct { // contains filtered or unexported fields }
StringMap maps strings to values. Methods on a map value will panic if the map is not initialized. A map value is safe to copy.
func NewStringMap ¶
NewStringMap returns an initialized map. The map value is safe to copy.
func (StringMap[V]) All ¶
All ranges over values in m, applying the do callback to each value until the callback returns false or all values have been visited. The iteration order is not randomized for each call.
func (StringMap[V]) Dep ¶
Dep returns the average (mean) depth of all values in m. If m is not initialized, Dep returns 0.
func (StringMap[V]) Get ¶
Get returns the value for key, or a zero value and false if the key is missing.
func (StringMap[V]) Len ¶
Len returns the number of values in m. If m is not initialized, Len returns 0.
func (StringMap[V]) Mod ¶
Mod modifies the value for key using the mod callback. The mod callback receives a pointer to the existing or new value for key, and true if the key existed.
func (StringMap[V]) Ptr ¶
Ptr returns a pointer to the value for key, or nil if the key is missing. The value may be updated through the returned pointer.
type StringSet ¶
type StringSet struct {
// contains filtered or unexported fields
}
StringSet contains a set of strings. Methods on a set value will panic if the set is not initialized. A set value is safe to copy.
func NewStringSet ¶
func NewStringSet() StringSet
NewStringSet returns an initialized set. The set value is safe to copy.
func (StringSet) All ¶
All ranges over keys in s, applying the do callback to each key until the callback returns false or all keys have been visited. The iteration order is not randomized for each call.
func (StringSet) Dep ¶
Dep returns the average (mean) depth of all keys in s. If s is not initialized, Dep returns 0.