const MaxPairs
MaxPairs bounds the map so gas stays predictable.
Package bidimap is a bidirectional map — unique in both directions — as a pure, reusable package.
gno.land/p/moul/x/daily/bidimap/v0Bidirectional map, unique both ways — New, 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.
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).
BiMap is a string<->string map, unique in both directions.
Clone returns an independent copy.
Consistent reports whether the two indexes agree. Always true through the public API; exported so tests and callers can assert the invariant directly.
Delete removes the pair for key. Returns false when key is absent.
DeleteValue removes the pair for value. Returns false when value is absent.
Get returns the value bound to key.
GetKey returns the key bound to value — the reverse lookup, also O(1).
Has reports whether key is present.
HasValue reports whether value is present.
Invert returns a new BiMap with keys and values swapped.
Iterate calls fn for each pair in sorted key order. Returning true stops.
Keys returns every key, sorted. Sorted, not map order: a Render built from an unspecified order can differ between nodes.
Len returns the number of pairs.
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.
PutUnique binds key<->value only when NEITHER side is already taken by a different pairing. Returns false without changing anything otherwise.
Values returns every value, sorted.