Files
amethyst/.claude/skills/nostr-expert/references/large-cache.md
T
Claude 60edd473c7 Refreshes .claude/ skill library: fixes stale refs, adds 4 new skills
- Updates CLAUDE.md tech stack to current versions (Compose 1.10.3, Kotlin 2.3.20).
- Reframes kotlin-multiplatform iOS as mature; adds secp256k1-kmp 0.23.0 references.
- Updates desktop-expert Main.kt references (code grew from ~270 to 1341 lines and
  NavigationRail moved to ui/deck/SinglePaneLayout.kt); replaces obsolete
  "hardcoded ctrl = true" anti-pattern note with accurate isMacOS branching.
- Removes compose-desktop.md (superseded by desktop-expert/).
- Adds nostr-expert references: nip19-bech32, event-factory, crypto-and-encryption,
  large-cache. Adds kotlin-expert/common-utilities, compose-expert/rich-text-parsing,
  android-expert/image-loading.
- New skills: account-state (Account + LocalCache), relay-client (subscriptions,
  filter assemblers, preloaders), feed-patterns (FeedFilter + FeedViewModel family),
  auth-signers (NostrSigner across internal / NIP-46 / NIP-55).
2026-04-21 21:00:45 +00:00

64 lines
3.2 KiB
Markdown

# LargeCache: Platform-Aware In-Memory Store
`quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/cache/LargeCache.kt` provides a thread-safe key-value cache with a functional iteration API. Used everywhere Amethyst needs to hold many events, users, or derived state in memory.
## Files
- `LargeCache.kt``expect class LargeCache<K, V>` and its factory `createLargeCache()`.
- `ICacheOperations.kt` — interface the cache exposes: `forEach`, `filter`, `map`, `mapNotNull`, `groupBy`, `maxOrNullOf`, `sumOf`, `count`, `any`, `firstOrNull`, etc.
- `CacheCollectors.kt` — functional collector helpers used by the cache API.
### Actual implementations
- **Android** (`androidMain`) — backed by a `ConcurrentHashMap` (and optionally `androidx.collection.LruCache` variants for size-bounded caches).
- **JVM/Desktop** (`jvmMain`) — `ConcurrentHashMap` directly.
- **iOS** (`iosMain`) — `NSMapTable`/Kotlin concurrent map wrapper.
## Core API
```kotlin
val cache: LargeCache<HexKey, Note> = LargeCache()
cache.put(id, note)
cache.get(id) // V?
cache.getOrCreate(id) { Note(id) } // atomic compute-if-absent
cache.containsKey(id)
cache.remove(id)
cache.size()
// Functional iteration — thread-safe snapshot semantics
cache.forEach { key, value -> ... }
cache.filter { key, value -> value.kind == 1 }
cache.map { key, value -> value.pubKey }
cache.count { _, v -> v.isUnread }
cache.maxOrNullOf { _, v -> v.createdAt }
cache.groupBy { _, v -> v.kind }
```
The important contract: **functional operations iterate a consistent snapshot**, so you can `filter` inside a coroutine without racing concurrent writers. This is why `LocalCache` (the Amethyst event store) can be scanned to build a feed while relays are still inserting.
## When to Use
- **Event / note stores** — `LocalCache.notes: LargeCache<HexKey, Note>`.
- **User profiles** — `LocalCache.users: LargeCache<HexKey, User>`.
- **Address → event** lookups for addressable (parameterized replaceable) events.
- **Shared-secret caches** (see `SharedKeyCache.kt` — a similar pattern at smaller scale).
## When Not to Use
- Small maps (<100 entries) — regular `mutableMapOf` is fine.
- Off-process state (DB, disk) — use the `store/` event DB, not LargeCache.
- Hot one-shot lookups — if you're already inside a Flow pipeline, chain operators rather than maintaining a parallel cache.
## Gotchas
- **`getOrCreate` vs `put`** — `getOrCreate` is atomic and safe under contention; `get` then `put` is a race.
- **Iteration during mutation is safe** but the snapshot may include or exclude a concurrent write. Don't rely on a just-put value being visible inside a currently-running `forEach`.
- **Don't store `Flow`s inside LargeCache.** Cache values should be immutable / thread-safe objects. For reactive state, keep a `StateFlow` next to the cache and emit on writes.
- **No TTL / eviction by default.** If you need bounded size, wrap with `LruCache` or build an explicit eviction loop keyed off a secondary structure.
## Related
- `amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt` — the canonical user of `LargeCache<HexKey, Note>` and `LargeCache<HexKey, User>`.
- `nip44Encryption/SharedKeyCache.kt` — smaller domain-specific cache using the same pattern.