bimap

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 16, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

README

bimap

Bidirectional map implementations where both keys and values are unique.

Overview

A BiMap maintains a one-to-one mapping between keys and values. Looking up by key or by value is equally efficient using the Reverse() method.

Creating a BiMap

import (
    "github.com/bronlabs/bron-crypto/pkg/base/datastructures/bimap"
    "github.com/bronlabs/bron-crypto/pkg/base/datastructures/hashmap"
)

// Create with two empty maps (one for each direction)
m, err := bimap.NewMutableBiMap(
    hashmap.NewComparable[string, int](),
    hashmap.NewComparable[int, string](),
)

Bidirectional Lookup

// Forward lookup: key -> value
m.Put("one", 1)
value, exists := m.Get("one")  // 1, true

// Reverse lookup: value -> key
reversed := m.Reverse()
key, exists := reversed.Get(1)  // "one", true

Thread-Safe BiMap

inner, _ := bimap.NewMutableBiMap(
    hashmap.NewComparable[string, int](),
    hashmap.NewComparable[int, string](),
)
m := bimap.NewConcurrentBiMap(inner)

// Atomic operations
m.Compute("key", func(k string, old int, exists bool) (int, bool) {
    return old + 1, true
})

m.ComputeIfAbsent("key", func(k string) (int, bool) {
    return 42, true
})

m.ComputeIfPresent("key", func(k string, old int) (int, bool) {
    return old * 2, true
})

Common Operations

// Basic operations
m.Put("key", 123)
value, exists := m.Get("key")
m.Remove("key")
m.Clear()

// Query
m.Size()
m.IsEmpty()
m.ContainsKey("key")
m.Keys()
m.Values()

// Transform
filtered := m.Filter(func(k string) bool { return len(k) > 2 })
retained := m.Retain("a", "b", "c")

// Iterate
for k, v := range m.Iter() {
    // ...
}

// Freeze/Unfreeze
frozen := m.Freeze()
mutable := frozen.Unfreeze()

Value Uniqueness

When putting a key-value pair, if the key already exists with a different value, the old value is removed from the reverse mapping:

m.Put("a", 1)
m.Put("a", 2)  // "a" now maps to 2; reverse lookup for 1 no longer works

Documentation

Overview

Package bimap provides bidirectional map implementations for the datastructures interfaces.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewMutableBiMap

func NewMutableBiMap[K any, V any](emptyKey ds.MutableMap[K, V], emptyValue ds.MutableMap[V, K]) (ds.MutableBiMap[K, V], error)

NewMutableBiMap creates a new mutable bidirectional map using the provided empty maps. Both emptyKey and emptyValue must be empty maps; returns an error if they are not.

Types

type ConcurrentBiMap

type ConcurrentBiMap[K any, V any] struct {
	// contains filtered or unexported fields
}

ConcurrentBiMap is a thread-safe wrapper around a MutableBiMap. All operations are protected by a read-write mutex.

func NewConcurrentBiMap

func NewConcurrentBiMap[K any, V any](innerBiMap ds.MutableBiMap[K, V]) *ConcurrentBiMap[K, V]

NewConcurrentBiMap creates a new thread-safe bimap wrapping the given mutable bimap.

func (*ConcurrentBiMap[_, _]) Clear

func (m *ConcurrentBiMap[_, _]) Clear()

Clear removes all entries from the bimap.

func (*ConcurrentBiMap[K, V]) Clone

func (m *ConcurrentBiMap[K, V]) Clone() ds.ConcurrentBiMap[K, V]

Clone returns a new concurrent bimap with a copy of the data.

func (*ConcurrentBiMap[K, V]) Compute

func (m *ConcurrentBiMap[K, V]) Compute(key K, remappingFunction func(key K, oldVal V, exists bool) (V, bool)) V

Compute atomically computes a new value based on the key's current mapping. The remappingFunction receives the key, current value (if any), and existence flag, returning the new value and whether to store it (false removes the key).

func (*ConcurrentBiMap[K, V]) ComputeIfAbsent

func (m *ConcurrentBiMap[K, V]) ComputeIfAbsent(key K, mappingFunction func(key K) (V, bool)) V

ComputeIfAbsent atomically computes a value only if the key is not present. The mappingFunction returns the value to store and whether to store it. If the key exists, returns the current value without calling mappingFunction.

func (*ConcurrentBiMap[K, V]) ComputeIfPresent

func (m *ConcurrentBiMap[K, V]) ComputeIfPresent(key K, remappingFunction func(key K, oldVal V) (V, bool)) V

ComputeIfPresent atomically computes a new value only if the key is present. The remappingFunction returns the new value and whether to keep it (false removes the key). If the key is absent, returns the zero value without calling remappingFunction.

func (*ConcurrentBiMap[K, V]) ContainsKey

func (m *ConcurrentBiMap[K, V]) ContainsKey(key K) bool

ContainsKey returns true if the key exists in the bimap.

func (*ConcurrentBiMap[K, V]) Filter

func (m *ConcurrentBiMap[K, V]) Filter(predicate func(key K) bool) ds.ConcurrentBiMap[K, V]

Filter returns a new concurrent bimap containing only entries where the predicate returns true.

func (*ConcurrentBiMap[K, V]) Get

func (m *ConcurrentBiMap[K, V]) Get(l K) (V, bool)

Get returns the value associated with the key and whether it exists.

func (*ConcurrentBiMap[_, _]) IsEmpty

func (m *ConcurrentBiMap[_, _]) IsEmpty() bool

IsEmpty returns true if the bimap contains no entries.

func (*ConcurrentBiMap[K, V]) Iter

func (m *ConcurrentBiMap[K, V]) Iter() iter.Seq2[K, V]

Iter returns an iterator over all key-value pairs.

func (*ConcurrentBiMap[K, _]) Keys

func (m *ConcurrentBiMap[K, _]) Keys() []K

Keys returns a slice of all keys in the bimap.

func (*ConcurrentBiMap[K, V]) Put

func (m *ConcurrentBiMap[K, V]) Put(l K, r V)

Put adds or updates a key-value pair in the bimap.

func (*ConcurrentBiMap[K, V]) Remove

func (m *ConcurrentBiMap[K, V]) Remove(l K)

Remove deletes the entry with the given key from the bimap.

func (*ConcurrentBiMap[K, V]) Retain

func (m *ConcurrentBiMap[K, V]) Retain(keys ...K) ds.ConcurrentBiMap[K, V]

Retain returns a new concurrent bimap containing only entries with the specified keys.

func (*ConcurrentBiMap[K, V]) Reverse

func (m *ConcurrentBiMap[K, V]) Reverse() ds.ConcurrentBiMap[V, K]

Reverse returns a thread-safe view of this bimap with keys and values swapped.

func (*ConcurrentBiMap[_, _]) Size

func (m *ConcurrentBiMap[_, _]) Size() int

Size returns the number of entries in the bimap.

func (*ConcurrentBiMap[K, V]) TryPut

func (m *ConcurrentBiMap[K, V]) TryPut(l K, r V) (replaced bool, oldValue V)

TryPut adds or updates a key-value pair, returning whether a value was replaced and the old value.

func (*ConcurrentBiMap[K, V]) TryRemove

func (m *ConcurrentBiMap[K, V]) TryRemove(l K) (removed bool, r V)

TryRemove deletes the entry with the given key, returning whether it existed and its value.

func (*ConcurrentBiMap[_, V]) Values

func (m *ConcurrentBiMap[_, V]) Values() []V

Values returns a slice of all values in the bimap.

type ImmutableBiMap

type ImmutableBiMap[K any, V any] struct {
	// contains filtered or unexported fields
}

ImmutableBiMap is an immutable bidirectional map where both keys and values are unique.

func (*ImmutableBiMap[K, V]) Clone

func (m *ImmutableBiMap[K, V]) Clone() ds.BiMap[K, V]

Clone returns a copy of this bimap.

func (*ImmutableBiMap[K, V]) ContainsKey

func (m *ImmutableBiMap[K, V]) ContainsKey(key K) bool

ContainsKey returns true if the key exists in the bimap.

func (*ImmutableBiMap[K, V]) Filter

func (m *ImmutableBiMap[K, V]) Filter(predicate func(key K) bool) ds.BiMap[K, V]

Filter returns a new bimap containing only entries where the predicate returns true.

func (*ImmutableBiMap[K, V]) Get

func (m *ImmutableBiMap[K, V]) Get(l K) (V, bool)

Get returns the value associated with the key and whether it exists.

func (*ImmutableBiMap[_, _]) IsEmpty

func (m *ImmutableBiMap[_, _]) IsEmpty() bool

IsEmpty returns true if the bimap contains no entries.

func (*ImmutableBiMap[K, V]) Iter

func (m *ImmutableBiMap[K, V]) Iter() iter.Seq2[K, V]

Iter returns an iterator over all key-value pairs.

func (*ImmutableBiMap[K, _]) Keys

func (m *ImmutableBiMap[K, _]) Keys() []K

Keys returns a slice of all keys in the bimap.

func (*ImmutableBiMap[K, V]) Retain

func (m *ImmutableBiMap[K, V]) Retain(keys ...K) ds.BiMap[K, V]

Retain returns a new bimap containing only entries with the specified keys.

func (*ImmutableBiMap[K, V]) Reverse

func (m *ImmutableBiMap[K, V]) Reverse() ds.BiMap[V, K]

Reverse returns a view of this bimap with keys and values swapped.

func (*ImmutableBiMap[_, _]) Size

func (m *ImmutableBiMap[_, _]) Size() int

Size returns the number of entries in the bimap.

func (*ImmutableBiMap[K, V]) Unfreeze

func (m *ImmutableBiMap[K, V]) Unfreeze() ds.MutableBiMap[K, V]

Unfreeze returns a mutable copy of this bimap.

func (*ImmutableBiMap[_, V]) Values

func (m *ImmutableBiMap[_, V]) Values() []V

Values returns a slice of all values in the bimap.

type MutableBiMap

type MutableBiMap[K any, V any] struct {
	// contains filtered or unexported fields
}

MutableBiMap is a mutable bidirectional map where both keys and values are unique. It maintains two internal maps for efficient lookup in both directions.

func (*MutableBiMap[_, _]) Clear

func (m *MutableBiMap[_, _]) Clear()

Clear removes all entries from the bimap.

func (*MutableBiMap[K, V]) Clone

func (m *MutableBiMap[K, V]) Clone() ds.MutableBiMap[K, V]

Clone returns a mutable copy of this bimap.

func (*MutableBiMap[K, V]) ContainsKey

func (m *MutableBiMap[K, V]) ContainsKey(key K) bool

ContainsKey returns true if the key exists in the bimap.

func (*MutableBiMap[K, V]) Filter

func (m *MutableBiMap[K, V]) Filter(predicate func(key K) bool) ds.MutableBiMap[K, V]

Filter returns a new bimap containing only entries where the predicate returns true.

func (*MutableBiMap[K, V]) Freeze

func (m *MutableBiMap[K, V]) Freeze() ds.BiMap[K, V]

Freeze returns an immutable snapshot of this bimap.

func (*MutableBiMap[K, V]) Get

func (m *MutableBiMap[K, V]) Get(l K) (V, bool)

Get returns the value associated with the key and whether it exists.

func (*MutableBiMap[_, _]) IsEmpty

func (m *MutableBiMap[_, _]) IsEmpty() bool

IsEmpty returns true if the bimap contains no entries.

func (*MutableBiMap[K, V]) Iter

func (m *MutableBiMap[K, V]) Iter() iter.Seq2[K, V]

Iter returns an iterator over all key-value pairs.

func (*MutableBiMap[K, _]) Keys

func (m *MutableBiMap[K, _]) Keys() []K

Keys returns a slice of all keys in the bimap.

func (*MutableBiMap[K, V]) Put

func (m *MutableBiMap[K, V]) Put(l K, r V)

Put adds or updates a key-value pair in the bimap.

func (*MutableBiMap[K, V]) Remove

func (m *MutableBiMap[K, V]) Remove(l K)

Remove deletes the entry with the given key from the bimap.

func (*MutableBiMap[K, V]) Retain

func (m *MutableBiMap[K, V]) Retain(keys ...K) ds.MutableBiMap[K, V]

Retain returns a new bimap containing only entries with the specified keys.

func (*MutableBiMap[K, V]) Reverse

func (m *MutableBiMap[K, V]) Reverse() ds.MutableBiMap[V, K]

Reverse returns a view of this bimap with keys and values swapped. The returned bimap shares storage with the original.

func (*MutableBiMap[_, _]) Size

func (m *MutableBiMap[_, _]) Size() int

Size returns the number of entries in the bimap.

func (*MutableBiMap[K, V]) TryPut

func (m *MutableBiMap[K, V]) TryPut(l K, r V) (replaced bool, oldValue V)

TryPut adds or updates a key-value pair, returning whether a value was replaced and the old value. If the key already existed, the old value is removed from the reverse map.

func (*MutableBiMap[K, V]) TryRemove

func (m *MutableBiMap[K, V]) TryRemove(l K) (removed bool, r V)

TryRemove deletes the entry with the given key, returning whether it existed and its value.

func (*MutableBiMap[_, V]) Values

func (m *MutableBiMap[_, V]) Values() []V

Values returns a slice of all values in the bimap.

Jump to

Keyboard shortcuts

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