Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source pure

Package bidimap is a bidirectional map — unique in both directions — as a pure, reusable package.

Readme View source

gno.land/p/moul/x/daily/bidimap/v0

Bidirectional map, unique both waysNew, Put, PutUnique, Get, GetKey, Has, HasValue, Delete, DeleteValue, Keys, Values, Iterate, Invert, Clone, Consistent, MaxPairs.

1import "gno.land/p/moul/x/daily/bidimap/v0"
2
3m := bidimap.New()
4m.Put("alice", "admin")
5m.Get("alice")      // "admin", true
6m.GetKey("admin")   // "alice", true — O(1), not a scan

Both sides are unique, which is the interesting constraint: inserting a pair whose value already belongs to another key must do something deliberate rather than silently corrupt the reverse index.

  • Put replaces, and returns the pairs it displaced, so the caller sees what it evicted rather than discovering it later.
  • PutUnique refuses instead, returning false and changing nothing.

What is not on offer is a half-updated map. Consistent() is exported so callers and tests can assert the two indexes agree; it is true through the whole public API.

One subtlety with MaxPairs (4096): a full map still accepts a Put that rebinds an existing key or steals an existing value, because that reuses a slot rather than growing the map. Only a pair new on both sides is refused.

Keys/Values come back sorted, never in map order: gno map iteration order is unspecified, and a Render built from one can differ between nodes.

Live demo: r/moul/x/daily/bidimapdemo · render it at /r/moul/x/daily/bidimapdemo/v0.


Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.

Overview

Package bidimap is a bidirectional map — unique in both directions — as a pure, reusable package.

A normal map answers "what is the value for this key". A bidirectional one also answers the reverse in O(1), by keeping a second index. The cost is an invariant a plain pair of maps does not give you: BOTH sides are unique, so inserting a pair whose value already belongs to another key must do something deliberate rather than silently corrupt the reverse index.

This implementation makes that choice explicit. Put REPLACES: it evicts any existing pairing on either side first, so the two indexes can never disagree. PutUnique refuses instead, returning false. Pick whichever the caller wants; what is not on offer is a half-updated map.

Iteration is over sorted keys, never a built-in map range: gno map iteration order is unspecified, and a Render built from one can differ between nodes, which is a consensus bug rather than a cosmetic one.

A live demo of this package is at r/moul/x/daily/bidimapdemo(/r/moul/x/daily/bidimapdemo/v0).

Constants 1

const MaxPairs

1const MaxPairs = 4096
source

MaxPairs bounds the map so gas stays predictable.

Functions 1

func New

1func New() *BiMap
source

New returns an empty BiMap.

Types 1

type BiMap

struct
1type BiMap struct {
2	fwd map[string]string
3	rev map[string]string
4}
source

BiMap is a string<->string map, unique in both directions.

Methods on BiMap

func Clone

method on BiMap
1func (m *BiMap) Clone() *BiMap
source

Clone returns an independent copy.

func Consistent

method on BiMap
1func (m *BiMap) Consistent() bool
source

Consistent reports whether the two indexes agree. Always true through the public API; exported so tests and callers can assert the invariant directly.

func Delete

method on BiMap
1func (m *BiMap) Delete(key string) bool
source

Delete removes the pair for key. Returns false when key is absent.

func DeleteValue

method on BiMap
1func (m *BiMap) DeleteValue(value string) bool
source

DeleteValue removes the pair for value. Returns false when value is absent.

func Get

method on BiMap
1func (m *BiMap) Get(key string) (string, bool)
source

Get returns the value bound to key.

func GetKey

method on BiMap
1func (m *BiMap) GetKey(value string) (string, bool)
source

GetKey returns the key bound to value — the reverse lookup, also O(1).

func Has

method on BiMap
1func (m *BiMap) Has(key string) bool
source

Has reports whether key is present.

func HasValue

method on BiMap
1func (m *BiMap) HasValue(value string) bool
source

HasValue reports whether value is present.

func Invert

method on BiMap
1func (m *BiMap) Invert() *BiMap
source

Invert returns a new BiMap with keys and values swapped.

func Iterate

method on BiMap
1func (m *BiMap) Iterate(fn func(key, value string) bool)
source

Iterate calls fn for each pair in sorted key order. Returning true stops.

func Keys

method on BiMap
1func (m *BiMap) Keys() []string
source

Keys returns every key, sorted. Sorted, not map order: a Render built from an unspecified order can differ between nodes.

func Len

method on BiMap
1func (m *BiMap) Len() int
source

Len returns the number of pairs.

func Put

method on BiMap
1func (m *BiMap) Put(key, value string) (evicted [][2]string, ok bool)
source

Put binds key<->value, REPLACING any existing pairing on either side. It returns the pairs that were evicted to make room, so the caller can see what it displaced rather than discovering it later.

Returns ok=false only when the map is full and the pair is entirely new.

func PutUnique

method on BiMap
1func (m *BiMap) PutUnique(key, value string) bool
source

PutUnique binds key<->value only when NEITHER side is already taken by a different pairing. Returns false without changing anything otherwise.

func Values

method on BiMap
1func (m *BiMap) Values() []string
source

Values returns every value, sorted.

Imports 1

  • sort stdlib

Source Files 3