lfmap package - github.com/Snawoot/lfmap - Go Packages

3 min read Original article ↗

Package lfmap provides generic concurrent lock-free map implementation, using immutable map and atomic swaps.

package main

import (
	"fmt"
	"sync"

	"github.com/Snawoot/lfmap"
)

func main() {
	m := lfmap.New[string, int]()
	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			defer wg.Done()
			key := fmt.Sprintf("k%d", i)
			value := i * 100
			m.Set(key, value)
		}(i)
	}
	wg.Wait()

	for k, v := range m.Range {
		fmt.Printf("key = %s, value = %d\n", k, v)
	}
}

This section is empty.

This section is empty.

This section is empty.

Map is an instance of concurrent map. All Map methods are safe for concurrent use.

New returns a new instance of empty Map.

func (m *Map[K, V]) Clear()

Clear empties map. It's a shortcut for a transaction with just clear operation in it.

func (m *Map[K, V]) Delete(key K)

Delete updates the map removing specified key. It's a shortcut for a transaction with just delete operation in it.

func (m *Map[K, V]) Get(key K) (value V, ok bool)

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 (m *Map[K, V]) Len(key K) int

Len returns the number of elements in the map.

func (m *Map[K, V]) Range(yield func(key K, value V) bool)

Map iterator suitable for use with range keyword.

func (m *Map[K, V]) Set(key K, value V)

Set updates the map setting specified key to the new value. It's a shorcut for a Map.Transaction invoked with function setting only one value.

func (m *Map[K, V]) Transaction(txn func(t Tx[K, V]))

Transaction executes operations made by txn function, allowing complex interactions with map to be performed atomically and consistently.

txn function can be invoked more than once in case if collision happened during update.

package main

import (
	"fmt"

	"github.com/Snawoot/lfmap"
)

func main() {
	m := lfmap.New[string, int]()

	// Let's do a simple increment to illustrate transactions
	key := "abc"
	m.Transaction(func(t lfmap.Tx[string, int]) {
		ctr, _ := t.Get(key)
		t.Set(key, ctr+1)
	})
	fmt.Println(m.Get(key))
}
type Tx[K comparable, V any] interface {
	
	Clear()

	
	Delete(key K)

	
	
	
	Get(key K) (value V, ok bool)

	
	Len() int

	
	Range(yield func(key K, value V) bool)

	
	Set(key K, value V)
}

Tx is a handle to map state usable from within transactions. It's methods are NOT safe for concurrent use.