Revision history for Data-HashMap-Shared

0.20      2026-09-07
          - Inserts now reclaim expired slots and evict on a full arena,
            overwrites included; pop, shift and drain without an LRU sweep the
            whole table instead of one end.
          - Incompatible: new sharded sets route on a different half of the
            hash and record their shard count; upgrade every process sharing a
            sharded set together.
          - Fix a corrupt key offset crashing lookups, get_multi's missing 1 GB
            check, a spurious "corrupt header" on attach, cursor_seek on a miss
            and the shrink after a sparse removal.
          - Correct the documentation and re-measure the benchmarks.

0.19      2026-09-03
          - Fix LRU accounting, reserve()'s ceiling, sharded iteration, writes
            to frozen maps and NUL bytes in paths; remove the v9 upgrader.
          - Incompatible: upgrade_file() and hashmap-shared-upgrade are gone and
            v9 files no longer open; a TTL or limit argument of 2**32 or more
            croaks instead of wrapping; an unreachable $max_size warns.
          - Correct the benchmark units and many API and crash-safety notes.

0.18      2026-09-01
          - Fix three crash windows that could corrupt a map when a writer was
            killed mid-operation: a removed entry's key, the entry count that
            resize() trusts, and a string's offset/length pair.
          - A cursor whose map was explicitly destroyed now croaks instead of
            reading freed memory.
          - List-returning keywords no longer force list context, so one used in
            scalar context stops adding values to the enclosing call.
          - reserve() rejects an out-of-range target instead of truncating it or
            reporting success.
          - Correct the crash-safety, iteration and upgrade notes; report NA
            instead of failing to build on a big-endian architecture.

0.17      2026-08-12
          - Enforce the freeze in every mutator, not only at open.
          - Bound the arena offset when reading a string, so a corrupt record
            cannot hand an out-of-range pointer to newSVpvn.
          - Retire a tombstone before counting the new entry, so a concurrent
            open no longer reports a corrupt header on a saturated map.
          - new_sharded croaks above 4096 shards instead of looping forever, and
            constructor sizes above 2**32 croak instead of truncating.
          - get() no longer spins forever on a stably-corrupt record.
          - drain() reserves only what the map can yield, not the requested
            limit.
          - Sharded capacity(), tombstones() and stat_recoveries() accumulate in
            64 bits and saturate, matching size().
          - The v9->v10 upgrader loops on short writes, preserves group
            ownership across the rename, and no longer reports a dead pid as
            a live writer.
          - Every access to the shared value word is now atomic (relaxed).
          - Recover a file left behind by an interrupted create.
          - Frozen read-only mode: freeze() seals a file-backed map;
            new_readonly() maps it O_RDONLY and queries it lock-free.
          - Hardening: re-entrancy with tied and overloaded arguments, and
            DESTROY on an invocant that is not one of ours.
          - Documentation and test-harness corrections.
          - Document that unlink() reports through its return value rather than
            by dying.

0.16      2026-07-21
          - On-disk format change (v9 -> v10): migrate existing files with
            bin/hashmap-shared-upgrade or Data::HashMap::Shared->upgrade_file.
          - Bound arena free-list offsets before use.

0.15  2026-07-11
    - Fix flaky dead-reader-recovery precondition test.

0.14  2026-07-03
    - Security and robustness hardening; backing files now created mode
      0600 (pass a file-mode argument to new() for cross-user sharing).

0.13  2026-06-24
    - Docs: abstract and description now highlight LRU and per-key TTL
    - Add Cookbook, examples, and an oracle test (no code change)

0.12  2026-06-09
    - Optional $arena_cap (bytes) constructor arg decouples string-storage
      capacity from max_entries (no header change; reopen-compatible)

0.11  2026-06-09
    - Atomic max/min for integer-value maps (monotonic, insert-if-absent)
    - Sharded stats: max_entries/max_size/mmap_size now aggregate across shards
    - get_with_ttl registers an LRU access (clock bit), consistent with get
    - new_sharded with an undef path now dies cleanly instead of creating stray files
    - Exception-safe drain buffer; fix max_entries overflow at 2^31 capacity
    - Robustness: O_CLOEXEC on the backing fd; retry flock/msync on EINTR

0.10  2026-05-29
    - Exception-safe batch ops; integer-overflow and edge-case fixes
    - Documentation fixes; -Wall -Wextra clean

0.09  2026-05-26
    - Dead-reader rwlock recovery: SIGKILL'd worker holding rdlock no longer
      pins the counter; 1024-slot per-process mirror enables wrlock ETIMEDOUT
      to drain dead PIDs' contributions and force-reset when safe
    - LRU rebuild on writer recovery if a dead writer left the chain inconsistent
    - Cursor fixes: iter_pos/gen reset on cursor_seek shard switch;
      double-decrement of iterating on exhausted cursor destroy/reset/seek
    - SHM_VERSION 7 -> 9 (header layout); existing 0.08 maps must be recreated

0.08  2026-05-18
    - New ops: cas (string values), add_ttl, update_ttl, cas_take,
      remove_multi (method), get_with_ttl (method)

0.07  2026-04-26
    - anonymous mmap; new memfd/new from fd/sync
    - sharded sync iterates all shards
    - rwlock writers waiting split + crash recovery
    - utf8-flag hash miss fix; header validation
    - aarch64 CI matrix


0.06  2026-04-15
    - Clarify new_sharded $max_entries is per-shard
    - Improve benchmark tables in POD

0.05  2026-04-12
    - Fix DESTROY ordering (zero IV before free)
    - Add SEE ALSO cross-links to family modules


0.04  2026-04-06
    - Fix timing-sensitive TTL tests for slow CI environments

0.03  2026-03-30
    - Fix "panic: free from wrong pool" on threaded/DEBUGGING Perls
      (use Perl allocator for SAVEFREEPV-managed buffers)

0.02  2026-03-17
    - New ops: add, update, swap, cas, pop, shift, drain, set_multi,
      get_multi, persist, set_ttl, touch, reserve, flush_expired_partial,
      ttl_remaining, stats, arena_used, arena_cap, stat_evictions,
      stat_expired, stat_recoveries
    - Clock/second-chance eviction: lock-free LRU reads
    - Hash-tag probe filtering, prefetch, lru_skip optimization
    - SSE2-accelerated state scanning for iteration
    - SSE2-accelerated tag matching in probe loops
    - Inline small strings (<=7 bytes) stored in node structs, no arena overhead
    - Batch get_multi with prefetch pipeline under single lock
    - Fast monotonic clock (CLOCK_MONOTONIC_COARSE) for TTL paths
    - Pre-sized copy_buf to avoid realloc on first access
    - C-level sharding: new_sharded($path, $shards, ...) for parallel writes
    - Cursor chains across shards with correct iterating/flush_deferred
    - Harden header validation, fix cursor_seek gen tracking
    - SHM_VERSION 7 (inline strings, monotonic timestamps)

0.01  2026-03-14
    - 10 type-specialized shared-memory hash map variants (II, SS, SI, IS,
      I16, I32, I16S, I32S, SI16, SI32)
    - File-backed mmap(MAP_SHARED) for cross-process data sharing
    - Futex-based read-write lock with seqlock for lock-free reads
    - Lock-free atomic counters (incr/decr under read lock)
    - Elastic hash table capacity (automatic grow/shrink)
    - Arena allocator with free-list reclamation for string storage
    - Keyword API via XS::Parse::Keyword
    - Opt-in LRU eviction and per-key TTL (zero cost when disabled)
    - Removal-safe iteration with deferred resize/compact
    - Cursor API: independent iterators with seek, reset, nesting
    - Stale lock recovery via PID tracking (auto-recover after 2s timeout)
    - Diagnostic error messages from constructor
    - Bundled xxHash 0.8.3 (XXH3_64bits) for hashing
