Files
amethyst/.claude/skills/nostr-expert/references/large-cache.md
Claude 8bd5063e10 refactor: consume Quartz from its own repository
Quartz now lives in github.com/vitorpamplona/quartz, split into
quartz-core, quartz-social, quartz-relay-client and the other quartz-*
libraries, with history kept. Amethyst depends on the `quartz` umbrella
artifact at a released version (1.20.0) instead of the :quartz project.

- Remove the quartz/ module, jitpack.yml and the Quartz CI, release and
  pre-push steps; tools/unicode-nfkc moved with it.
- Point every module at libs.quartz.
- Move the device-test fixtures the benchmark and relayBench still read
  to testdata/.
- NostrConnectLoginUseCase parses bunker messages with BunkerJson, which
  now owns NIP-46 JSON.
- Repoint docs and skills at the Quartz repository; the nostr-expert
  scripts read a Quartz checkout (QUARTZ_REPO, default ../quartz).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014ZR5ZBfhFzRiXubJc5Evyv
2026-10-15 02:03:53 +00:00

1.4 KiB

LargeCache

core/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/cache/LargeCache.kt — expect class LargeCache<K, V>() implementing ICacheOperations<K, V>. It is the store behind LocalCache (commons/.../model/cache/: notes, addressables, users); see the account-state skill for how LocalCache uses it.

Actuals:

  • jvmAndroid/.../LargeCache.jvmAndroid.kt — a ConcurrentSkipListMap.
  • nativeMain/.../LargeCache.native.kt — a lock-free-read, striped-write hash table (StripedHashMap); its KDoc explains why.

API: get, put, remove, containsKey, size, keys(), values(), clear, getOrCreate(key) { builder } (returns the winner under a race), createIfAbsent (true when this call created it), plus the functional scans from ICacheOperations (forEach, filter, filterIntoSet, map, mapNotNull, mapFlatten, count, groupBy, countByGroup, sumOf, maxOrNullOf, associate, …) with collector types in CacheCollectors.kt. Siblings: ConcurrentHashCache.kt, ConcurrentLruCache.kt.

Rules:

  • Use getOrCreate/createIfAbsent, not get then put (a race).
  • Scans run while writers insert; a concurrent write may or may not be seen.
  • No eviction. Bounded caches use ConcurrentLruCache; LocalCache prunes via CachePruner.
  • A small map does not need a LargeCache.