immutable

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2022 License: BSD-3-Clause Imports: 3 Imported by: 2

README

PkgGoDev Go Report Card

go-immutable

Immutable map/set/list for go.

Benchmark

This library comes with benchmark test to compare against builtin types (there's no builtin set so that's only list and map). Here is an example of the benchmark result (with baseline is builtin):

$ go test -bench .
goos: linux
goarch: amd64
pkg: go.yhsif.com/immutable
cpu: Intel(R) Core(TM) i5-7260U CPU @ 2.20GHz
BenchmarkListBuilder/literal-10/baseline-4              1000000000               0.3048 ns/op          0 B/op          0 allocs/op
BenchmarkListBuilder/literal-10/immutable-4              6821798               174.2 ns/op           288 B/op          5 allocs/op
BenchmarkListBuilder/10/baseline-4                      33455275                35.15 ns/op           80 B/op          1 allocs/op
BenchmarkListBuilder/10/immutable-4                      5512944               182.3 ns/op           288 B/op          5 allocs/op
BenchmarkListBuilder/1024/baseline-4                      637911              1738 ns/op            8192 B/op          1 allocs/op
BenchmarkListBuilder/1024/immutable-4                     289621              4133 ns/op           24624 B/op          5 allocs/op
BenchmarkListBuilder/131072/baseline-4                      6976            165604 ns/op         1048580 B/op          1 allocs/op
BenchmarkListBuilder/131072/immutable-4                     2708            409006 ns/op         3145788 B/op          5 allocs/op
BenchmarkListRange/10/baseline-4                        263224618                4.456 ns/op           0 B/op          0 allocs/op
BenchmarkListRange/10/immutable-4                       51426008                21.99 ns/op            0 B/op          0 allocs/op
BenchmarkListRange/1024/baseline-4                       3754664               324.0 ns/op             0 B/op          0 allocs/op
BenchmarkListRange/1024/immutable-4                       618620              1836 ns/op               0 B/op          0 allocs/op
BenchmarkListRange/131072/baseline-4                       30866             41303 ns/op               0 B/op          0 allocs/op
BenchmarkListRange/131072/immutable-4                       5124            246614 ns/op               0 B/op          0 allocs/op
BenchmarkMapBuilder/literal-5/baseline-4                17114613                67.12 ns/op            0 B/op          0 allocs/op
BenchmarkMapBuilder/literal-5/immutable-4                1418350               842.0 ns/op           688 B/op         12 allocs/op
BenchmarkMapBuilder/10/baseline-4                        3125396               385.5 ns/op           292 B/op          1 allocs/op
BenchmarkMapBuilder/10/immutable-literal-4                548138              2074 ns/op            1562 B/op         15 allocs/op
BenchmarkMapBuilder/10/immutable-builder-4                855835              1302 ns/op            1031 B/op         10 allocs/op
BenchmarkMapBuilder/1024/baseline-4                        16005             75099 ns/op           86580 B/op         64 allocs/op
BenchmarkMapBuilder/1024/immutable-literal-4                4414            263092 ns/op          260299 B/op        201 allocs/op
BenchmarkMapBuilder/1024/immutable-builder-4                6236            170937 ns/op          173528 B/op        134 allocs/op
BenchmarkMapBuilder/131072/baseline-4                         78          13458018 ns/op        10926740 B/op       4766 allocs/op
BenchmarkMapBuilder/131072/immutable-literal-4                24          48260776 ns/op        32782071 B/op      14315 allocs/op
BenchmarkMapBuilder/131072/immutable-builder-4                37          31927129 ns/op        21850800 B/op       9530 allocs/op
BenchmarkMapRange/10/baseline-4                          9839715               121.8 ns/op             0 B/op          0 allocs/op
BenchmarkMapRange/10/immutable-4                         8229484               139.6 ns/op             0 B/op          0 allocs/op
BenchmarkMapRange/1024/baseline-4                          86908             13736 ns/op               0 B/op          0 allocs/op
BenchmarkMapRange/1024/immutable-4                         77984             15236 ns/op               0 B/op          0 allocs/op
BenchmarkMapRange/131072/baseline-4                          662           1685172 ns/op               0 B/op          0 allocs/op
BenchmarkMapRange/131072/immutable-4                         627           1978727 ns/op               0 B/op          0 allocs/op
PASS
ok      go.yhsif.com/immutable  40.332s

License

BSD License.

Documentation

Overview

Package immutable provides immutable data structures (map/set/list).

Note that immutable map/set/list only guarantee the immutability of the container itself, not the content inside. For example if you are using a immutable list of pointers, you are guaranteed that you always get the same pointer with the same index, but the content pointer points to might be changed by others sharing the same immutable list.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrBreak = errors.New("immutable: stop iteration")

ErrBreak can be used in Range functions to stop the iteration early.

Functions

This section is empty.

Types

type List

type List[T any] interface {
	// Len returns the length of the list.
	Len() int

	// Get returns the i-th item with 0-index.
	//
	// It panics when i is out of [0, Len()-1].
	Get(i int) T

	// Range iterates through the list, in its original order.
	//
	// It will return the error returned by f.
	Range(f ListRangeFunc[T]) error

	// Reslice returns the sublist from start to end-1 index.
	//
	// Use out of range indices will cause panic.
	Reslice(start, end int) List[T]
}

List defines the interface of an immutable list.

Example
package main

import (
	"fmt"

	"go.yhsif.com/immutable"
)

func main() {
	list := immutable.ListLiteral("a", "b", "c")
	fmt.Println("Len:", list.Len())
	fmt.Println("list.Get(1):", list.Get(1))
	fmt.Println("Break iteration:")
	list.Range(func(i int, x string) error {
		if i >= 1 {
			return immutable.ErrBreak
		}
		fmt.Printf("%d: %v\n", i, x)
		return nil
	})
	fmt.Println("Full iteration:")
	list.Range(func(i int, x string) error {
		fmt.Printf("%d: %v\n", i, x)
		return nil
	})
	fmt.Printf("%%v: %v\n", list)
	fmt.Println("Reslice(1, 3):", list.Reslice(1, 3))
}
Output:


Len: 3
list.Get(1): b
Break iteration:
0: a
Full iteration:
0: a
1: b
2: c
%v: [a b c]
Reslice(1, 3): [b c]

func EmptyList added in v0.1.1

func EmptyList[T any]() List[T]

EmptyList returns an immutable empty list.

func ListLiteral

func ListLiteral[T any](items ...T) List[T]

ListLiteral creates an immutable list from items.

It's shorthand for immutable.NewListBuilder[T]().Append(items...).Build().

type ListBuilder

type ListBuilder[T any] interface {
	List[T]

	// Append appends item(s) to the list.
	//
	// It returns self for chaining.
	Append(x ...T) ListBuilder[T]

	// Build builds the immutable list.
	Build() List[T]
}

ListBuilder defines the interface of an immutable list builder.

It's not guaranteed to be thread-safe and shouldn't be used concurrently.

func NewListBuilder

func NewListBuilder[T any]() ListBuilder[T]

NewListBuilder creates a ListBuilder.

type ListRangeFunc

type ListRangeFunc[T any] func(i int, x T) error

ListRangeFunc defines the iteration function for List type.

i will be the 0-based index and x will be the item.

Whenever ListRangeFunc returns a non-nil error, the iteration will be stopped. The error will be returned by Range function.

type Map

type Map[K comparable, V any] interface {
	// Len returns the size of the map.
	Len() int

	// Load returns the value to the key.
	//
	// If the key is not in the map, value will be zero and ok will be false.
	Load(key K) (value V, ok bool)

	// Get returns the value to the key.
	//
	// It's the same as Load just without ok return.
	Get(key K) V

	// Range iterates through the map.
	//
	// It will return the error returned by f.
	Range(f MapRangeFunc[K, V]) error
}

Map defines the interface of an immutable map.

Example
package main

import (
	"fmt"

	"go.yhsif.com/immutable"
)

func main() {
	m := immutable.MapLiteral(map[int]string{
		1: "a",
	})
	fmt.Printf("%%v: %v\n", m)
	m = immutable.MapLiteral(map[int]string{
		1: "a",
		2: "b",
		3: "c",
	})
	fmt.Println("Len:", m.Len())
	fmt.Println("m.Get(1):", m.Get(1))
	fmt.Println("range:")
	m.Range(func(k int, v string) error {
		fmt.Printf("%v: %v\n", k, v)
		return nil
	})
}
Output:


%v: map[1:a]
Len: 3
m.Get(1): a
range:
1: a
2: b
3: c

func EmptyMap added in v0.1.1

func EmptyMap[K comparable, V any]() Map[K, V]

EmptyMap returns an immutable empty map.

func MapLiteral

func MapLiteral[K comparable, V any](m map[K]V) Map[K, V]

MapLiteral creates an immutable map from existing map.

It's shorthand for immutable.NewMapBuilder[K, V]().Update(m).Build().

type MapBuilder

type MapBuilder[K comparable, V any] interface {
	Map[K, V]

	// Set sets the key value pair to the map.
	//
	// It returns self for chaining.
	Set(key K, value V) MapBuilder[K, V]

	// Update updates every key value pair from m to the map.
	//
	// It returns self for chaining.
	Update(m map[K]V) MapBuilder[K, V]

	// Build builds the immutable map.
	Build() Map[K, V]
}

MapBuilder defines the interface of an immutable map builder.

It's not guaranteed to be thread-safe and shouldn't be used concurrently.

func NewMapBuilder

func NewMapBuilder[K comparable, V any]() MapBuilder[K, V]

NewMapBuilder creates a new MapBuilder.

type MapRangeFunc

type MapRangeFunc[K comparable, V any] func(key K, value V) error

MapRangeFunc defines the iteration function for Map type.

Whenever MapRangeFunc returns a non-nil error, the iteration will be stopped. The error will be returned by Range function.

type Set

type Set[T comparable] interface {
	// Len returns the length of the set.
	Len() int

	// Contains checks whether an item is in the set.
	Contains(x T) bool

	// Range iterates through the set.
	//
	// It will return the error returned by f.
	Range(f SetRangeFunc[T]) error
}

Set defines the interface of an immutable set.

Example
package main

import (
	"fmt"

	"go.yhsif.com/immutable"
)

func main() {
	s := immutable.SetLiteral("a")
	fmt.Printf("%%v: %v\n", s)
	s = immutable.SetLiteral("a", "b", "c")
	fmt.Println("Len:", s.Len())
	fmt.Println(`s.Contains("a"):`, s.Contains("a"))
	fmt.Println(`s.Contains("d"):`, s.Contains("d"))
	fmt.Println("range:")
	s.Range(func(x string) error {
		fmt.Printf("%v\n", x)
		return nil
	})
}
Output:


%v: [a]
Len: 3
s.Contains("a"): true
s.Contains("d"): false
range:
a
b
c

func EmptySet added in v0.1.1

func EmptySet[T comparable]() Set[T]

EmptySet returns an immutable empty set.

func SetLiteral

func SetLiteral[T comparable](items ...T) Set[T]

SetLiteral creates an immutable set from items.

It's shorthand for immutable.NewSetBuilder[T]().Add(items...).Build().

type SetBuilder

type SetBuilder[T comparable] interface {
	Set[T]

	// Add adds item(s) to the set.
	//
	// It returns self for chaining.
	Add(x ...T) SetBuilder[T]

	// Build builds the immutable set.
	Build() Set[T]
}

SetBuilder defines the interface of an immutable set builder.

It's not guaranteed to be thread-safe and shouldn't be used concurrently.

func NewSetBuilder

func NewSetBuilder[T comparable]() SetBuilder[T]

NewSetBuilder creates a new SetBuilder.

type SetRangeFunc

type SetRangeFunc[T comparable] func(x T) error

SetRangeFunc defines the iteration function for Set type.

Whenever SetRangeFunc returns a non-nil error, the iteration will be stopped. The error will be returned by Range function.

Jump to

Keyboard shortcuts

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