Transaction
F99B37C2BD4A30…C51B09A81341
Block 25,909 · index 0 · indexed
Summary
- Hash
- F99B37C2BD4A301EE85D6CEA93C469C9A17D401E088E73B1B9CCC51B09A81341
- Block
- 25,909
- Size
- 6513 bytes
- Gas used
- 11,341,519 / 13,609,882
- Fee
- 1000000ugnot
- Memo
- gnopublish
- Status
- success
Messages
- Package
- gno.land/p/moul/memo/v0
Arguments · 9
- #1memo
- #2README.md
- #3# `gno.land/p/moul/memo/v0` A simple memoization utility to cache function results, **backed by a B+ tree** (`gno.land/p/nt/bptree`). A B+ tree packs many entries per persisted node, so it costs materially less storage and gas per cached entry than an AVL backing would. ```go import "gno.land/p/moul/memo/v0" m := memo.New() // Cache expensive computation; subsequent calls with the same key // return the cached result without re-running the function. result := m.Memoize("key", func() any { return "computed-value" }) m.Invalidate("key") // drop one entry m.Clear() // drop all entries m.Size() // number of cached entries ``` > ⚠️ **Gno usage:** storage updates only persist during transactions. Memoizing > during queries/render will not persist and only wastes resources — use this in > transaction-driven contexts. **Caveats from the B+ tree backing:** it mutates in place (a copy-on-write AVL backing would not), so do not Invalidate/add entries from inside a callback iterating the same Memoizer, and do not copy a non-zero `Memoizer` by value. <!-- BEGIN GNOCONTRACTS FOOTER (generated by `make readmes`; do not edit below) --> --- Part of **[moul/gno-contracts](https://github.com/moul/gno-contracts)** — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage. **Dependency graph:**  > ⚠️ **Disclaimer:** provided as-is, without warranty; not security-audited. Full disclaimer: [DISCLAIMER](https://github.com/moul/gno-contracts/blob/main/DISCLAIMER.md). <!-- END GNOCONTRACTS FOOTER -->
- #4gnomod.toml
- #5module = "gno.land/p/moul/memo/v0" gno = "0.9"
- #6memo.gno
- #7// Package memo provides a simple memoization utility to cache function results. // // The package offers a Memoizer type that can cache function results based on keys, // with optional validation of cached values. This is useful for expensive computations // that need to be cached and potentially invalidated based on custom conditions. // // It is the B+ tree successor to [gno.land/p/moul/memo/v0] (which is backed by // an AVL tree): a bump to v3 because the backing data structure — and thus the // on-chain storage layout — changed. The exported API is identical to v2 // (New/Memoize/MemoizeWithValidator/Invalidate/Clear/Size). A B+ tree packs // many entries per persisted node, so it costs materially less storage and gas // per cached entry — prefer v3 when the cache is part of persisted realm state. // // Because the B+ tree backing mutates in place (the AVL backing was // copy-on-write), do NOT invalidate or add entries to the same Memoizer from // inside a callback that is iterating it, and do NOT copy a non-zero Memoizer // by value. // // /!\ Important Warning for Gno Usage: // In Gno, storage updates only persist during transactions. This means: // - Cache entries created during queries will NOT persist // - Creating cache entries during queries will actually decrease performance // as it wastes resources trying to save data that won't be saved // // Best Practices: // - Use this pattern in transaction-driven contexts rather than query/render scenarios // - Consider controlled cache updates, e.g., by specific accounts (like oracles) // - Ideal for cases where cache updates happen every N blocks or on specific events // - Carefully evaluate if caching will actually improve performance in your use case // // Basic usage example: // // m := memo.New() // // // Cache expensive computation // result := m.Memoize("key", func() any { // // expensive operation // return "computed-value" // }) // // // Subsequent calls with same key return cached result // result = m.Memoize("key", func() any { // // function won't be called, cached value is returned // return "computed-value" // }) // // Example with validation: // // type TimestampedValue struct { // Value string // Timestamp time.Time // } // // m := memo.New() // // // Cache value with timestamp // result := m.MemoizeWithValidator( // "key", // func() any { // return TimestampedValue{ // Value: "data", // Timestamp: time.Now(), // } // }, // func(cached any) bool { // // Validate that the cached value is not older than 1 hour // if tv, ok := cached.(TimestampedValue); ok { // return time.Since(tv.Timestamp) < time.Hour // } // return false // }, // ) package memo import ( "gno.land/p/nt/bptree/v0" "gno.land/p/nt/ufmt/v0" ) // keyString derives a stable string key from an arbitrary value. Keys are // compared by their string representation, mirroring the previous ordering // behavior. func keyString(key any) string { return ufmt.Sprintf("%v", key) } // Memoizer is a structure to handle memoization of function results. type Memoizer struct { cache *bptree.BPTree } // New creates a new Memoizer instance. func New() *Memoizer { return &Memoizer{ cache: bptree.NewBPTree32(), } } // Memoize ensures the result of the given function is cached for the specified key. func (m *Memoizer) Memoize(key any, fn func() any) any { k := keyString(key) if m.cache.Has(k) { return m.cache.Get(k) } value := fn() m.cache.Set(k, value) return value } // MemoizeWithValidator ensures the result is cached and valid according to the validator function. func (m *Memoizer) MemoizeWithValidator(key any, fn func() any, isValid func(any) bool) any { k := keyString(key) if m.cache.Has(k) { cached := m.cache.Get(k) if isValid(cached) { return cached } } value := fn() m.cache.Set(k, value) return value } // Invalidate removes the cached value for the specified key. func (m *Memoizer) Invalidate(key any) { m.cache.Remove(keyString(key)) } // Clear clears all cached values. func (m *Memoizer) Clear() { m.cache = bptree.NewBPTree32() } // Size returns the number of items currently in the cache. func (m *Memoizer) Size() int { return m.cache.Size() }
- #8/gno.MemPackageType
- #9 MPUserProd
Result log
msg:0,success:true,log:,events:[]