immutable

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 17, 2023 License: Unlicense Imports: 4 Imported by: 0

README

immutable

import "github.com/reactivego/immutable"

Go Reference

Package immutable provides an immutable persistent Map type. A Map is a collection of unordered key:value pairs. The Map is similar to a standard Go map[interface{}]interface{} type.

Documentation

Overview

Example (Map)
package main

import (
	"fmt"

	"github.com/reactivego/immutable"
)

func main() {
	m := immutable.Map
	m = m.Set("Hello", "World!")
	fmt.Println(m)
}
Output:

{Hello:World!}

Index

Examples

Constants

View Source
const UnhashableKeyType = MapError("Unhashable Key Type")

Variables

View Source
var Map = Hamt{}

Map is an empty Hamt

Functions

This section is empty.

Types

type Hamt

type Hamt struct {
	// contains filtered or unexported fields
}

Hamt is a persistent immutable hash array mapped trie (HAMT) with an internal hash function that uses the standard "hash/maphash" package for hashing. The key types it supports are either string or any integer type. Keys are directly compared using the '==' operator. Key types other than string or integers need an external hasher. Use the method WithHasher to create a HAMT with an external hasher.

Example
package main

import (
	"fmt"

	"github.com/reactivego/immutable"
)

func main() {
	m := immutable.Map

	m = m.Set("first", 123).Set("second", 456).Set("first", 789)

	m.Range(func(key, value any) bool {
		fmt.Println(key, value)
		return true
	})

}
Output:

first 789
second 456

func (Hamt) Del

func (a Hamt) Del(key any) Hamt

Del returns a copy of the Hamt with the entry for the key removed.

func (Hamt) Depth

func (a Hamt) Depth() int

Depth returns the number of levels in the Hamt. Calling Depth on an empty Hamt returns 1.

func (Hamt) Get

func (a Hamt) Get(key any) any

Get returns the value for the entry with the given key or nil when it is not present.

func (Hamt) Has

func (a Hamt) Has(key any) bool

Has returns true when an entry with the given key is present.

func (Hamt) Len

func (a Hamt) Len() int

Len returns the number of entries that are present.

func (Hamt) Lookup

func (a Hamt) Lookup(key any) (any, bool)

Lookup returns the value of an entry associated with a given key along with the value true when the key is present. Otherwise it returns (nil, false).

func (Hamt) Put

func (a Hamt) Put(key any) Hamt

Put returns a copy of the Hamt with the key,key pair inserted. So the key is also inserted as the value.

func (Hamt) Range

func (a Hamt) Range(f func(any, any) bool)

Range calls the given function for every key,value pair present.

func (Hamt) Set

func (a Hamt) Set(key, value any) Hamt

Set returns a copy of the Hamt with the given key,value pair inserted.

func (Hamt) Size

func (a Hamt) Size() int

Size returns the number of bytes used for storing the entries, not including the size of the actual keys and the values.

func (Hamt) String

func (a Hamt) String() string

String returns a string representation of the key,value pairs present.

func (Hamt) WithHasher

func (a Hamt) WithHasher(hash func(any) (uint32, any)) HamtX

WithHasher returns an empty HamtX with the given hasher function. The hasher function is used to convert a key into a hash an a key. So it allows for key transformation.

type HamtX

type HamtX struct {
	// contains filtered or unexported fields
}

HamtX is a Hash Array Mapped Trie with an external hash function.

Example
package main

import (
	"fmt"

	"github.com/reactivego/immutable"

	"hash/maphash"
)

func main() {
	// Setup a hasher to allow the use of []byte values as a key
	seed := maphash.MakeSeed()
	hasher := func(key any) (uint32, any) {
		var h maphash.Hash
		h.SetSeed(seed)
		k := key.([]byte)
		h.Write(k)
		// Return a hash of the bytes and map the bytes to string to make it comparable.
		return uint32(h.Sum64() & 0xFFFFFFFF), string(k)
	}
	m := immutable.Map.WithHasher(hasher)

	m = m.Set([]byte{1, 2, 3}, "Mammalia is the class of mammals.")
	m = m.Set([]byte{4, 5, 6}, "Aves is the class of birds.")

	fmt.Println(m.Get([]byte{1, 2, 3}))
	fmt.Println(m.Get([]byte{4, 5, 6}))
	fmt.Println(m.Get([]byte{7, 8, 9}))
}
Output:

Mammalia is the class of mammals.
Aves is the class of birds.
<nil>

func (HamtX) Del

func (a HamtX) Del(key any) HamtX

Del returns a copy of the HamtX with the entry for the key removed.

func (HamtX) Depth

func (a HamtX) Depth() int

Depth returns the number of levels in the Hamt. Calling Depth on an empty Hamt returns 1.

func (HamtX) Get

func (a HamtX) Get(key any) any

Get returns the value for the entry with the given key or nil when it is not present.

func (HamtX) Has

func (a HamtX) Has(key any) bool

Has returns true when an entry with the given key is present.

func (HamtX) Len

func (a HamtX) Len() int

Len returns the number of entries that are present.

func (HamtX) Lookup

func (a HamtX) Lookup(key any) (any, bool)

Lookup returns the value of an entry associated with a given key along with the value true when the key is present. Otherwise it returns (nil, false).

func (HamtX) Put

func (a HamtX) Put(key any) HamtX

Put returns a copy of the HamtX with the key,key pair inserted. So the key is also inserted as the value.

Example
package main

import (
	"fmt"

	"github.com/reactivego/immutable"

	"hash/maphash"
)

func main() {
	// Topic is an example of data where the key (i.e. Name) is part of the data.
	type Topic struct{ Name, Description string }

	// Setup a hasher to index a Topic on the Name field
	seed := maphash.MakeSeed()
	hasher := func(key any) (uint32, any) {
		var h maphash.Hash
		Name := key.(Topic).Name
		h.SetSeed(seed)
		h.WriteString(Name)
		// Return a 32 bit hash of Name and also the Name itself as it is comparable
		return uint32(h.Sum64() & 0xFFFFFFFF), Name
	}
	m := immutable.Map.WithHasher(hasher)

	m = m.Put(Topic{"Aves", "This topic is about birds."})
	m = m.Put(Topic{"Mammalia", "This topic is about mammals"})
	fmt.Printf("%+v\n", m.Get(Topic{Name: "Mammalia"}))
	fmt.Printf("%+v\n", m.Get(Topic{Name: "Aves"}))
}
Output:

{Name:Mammalia Description:This topic is about mammals}
{Name:Aves Description:This topic is about birds.}

func (HamtX) Range

func (a HamtX) Range(f func(any, any) bool)

Range calls the given function for every key,value pair present.

func (HamtX) Set

func (a HamtX) Set(key, value any) HamtX

Set returns a copy of the HamtX with the given key,value pair inserted.

Example
package main

import (
	"fmt"

	"github.com/reactivego/immutable"

	"encoding/binary"
	"hash/maphash"
)

func main() {
	// Key is comparable (i.e. == and !=) but not hashable.
	type Key struct{ K1, K2 int64 }
	type Topic struct{ Name, Description string }

	// Setup a hasher to hash the key
	seed := maphash.MakeSeed()
	hasher := func(key any) (uint32, any) {
		var h maphash.Hash
		h.SetSeed(seed)
		k := key.(Key)
		binary.Write(&h, binary.LittleEndian, k.K1)
		binary.Write(&h, binary.LittleEndian, k.K2)
		// Return a hash of the key and the key itself verbatim as it is comparable
		return uint32(h.Sum64() & 0xFFFFFFFF), key
	}
	m := immutable.Map.WithHasher(hasher)

	m = m.Set(Key{1, 2}, Topic{"Theme", "This is a topic about theme"})
	fmt.Println(m)
	fmt.Println(m.Get(Key{1, 2}))
}
Output:

{{K1:1 K2:2}:{Name:Theme Description:This is a topic about theme}}
{Theme This is a topic about theme}

func (HamtX) Size

func (a HamtX) Size() int

Size returns the number of bytes used for storing the entries, not including the size of the actual keys and the values.

func (HamtX) String

func (a HamtX) String() string

String returns a string representation of the key,value pairs present.

type MapError

type MapError string

func (MapError) Error

func (e MapError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL