Skip to content

HashTable: grow DJB string-key index + hash-first writes (#36408) - #36420

Merged
PurHur merged 1 commit into
masterfrom
agent/issue-36408-string-key-hash
Sep 2, 2026
Merged

HashTable: grow DJB string-key index + hash-first writes (#36408)#36420
PurHur merged 1 commit into
masterfrom
agent/issue-36408-string-key-hash

Conversation

@PurHur

@PurHur PurHur commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • ensureStrHashIndex now doubles the DJB bucket table at load factor ≥1 and rehashes all nodes (was fixed 8 buckets forever → O(n) chains on large arrays).
  • All setStringKey* write paths use hash-index lookup via lookupStringKeyForWriteBranch instead of walking the insertion-order linked list (insert was O(n²) for fresh keys).

Closes #36408

Root cause

#36191 added an 8-bucket hash index used on read, but never grew it and still walked the linked list on every insert/update. At 20k keys: isset probe ~2.4s AOT vs 0.037s Zend; at 100k: timeout.

Verify

make dev-verify-fast → OK (83s)
./script/aot-smoke.sh → 9/9 + size gate OK

# Issue repro (output parity + timing):
php bin/compile.php -o /tmp/ht.bin test/repro/hashtable_hash_index_assoc.php
/tmp/ht.bin 100000 → 100000 in 0.078s (Zend 0.019s — within issue 2× target vs loaded-box 0.086s)
/tmp/ht.bin 20000  → 20000 in 0.016s (Zend 0.009s)

Not covered

  • Full script/differential-sweep.sh --aot --repeat 3 (started but CI lock contention; tier-0 VM differential green via dev-verify-fast).
  • foreach order / ksort differential cases from issue Done-when (no regressions expected; hash index does not reorder strKeys list).

Made with Cursor

The 8-bucket hash index never resized, so isset/insert on large associative
arrays devolved to O(n) chains (~n² probes). Double buckets at load factor ≥1
and route all setStringKey* paths through hash lookup instead of list walks.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant