Skip to content

Find weak collection entries through hashed indexes - #2004

Open
ctate wants to merge 1 commit into
mainfrom
ctate/find-weak-collection-48d9a9
Open

ctate wants to merge 1 commit into
mainfrom
ctate/find-weak-collection-48d9a9

Conversation

@ctate

@ctate ctate commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator
  • WeakMap and WeakSet find an entry by (collection, key) in a hashed per-thread index instead of walking the collection's list, so get, set, has and delete take expected constant time.
  • A second index by key finds a disposed key's entries in every collection. Entries leave both lists in constant time, and the indexes are freed when empty.
  • 200,000 keys fill and read back in 0.24 s (Node 0.30 s), where the same program did not finish in 300 s before.

Closes #1702

WeakMap and WeakSet kept each collection's entries in one list and found
a key by walking it, and every collection's entries for a key in 1,024
shared buckets. Filling a collection and reading it back took quadratic
time: 40,000 keys took 6.7 s against Node's 0.2 s, and 200,000 keys did
not finish.

Each thread now indexes its entries twice, in open-addressing tables with
linear probing and backward-shift deletion: by collection, key and kind,
for get, set, has and delete, and by key pointer, for a key's disposal,
which ends the key's entries in every collection. A collection's entries
and a key's entries are doubly linked, so an entry leaves both in
constant time. The tables grow at half load and are freed when their last
entry goes, so an exiting worker leaves none. 200,000 keys now take
0.24 s (Node 0.30 s).

Closes #1702

Co-authored-by: ejc3 <1694850+ejc3@users.noreply.github.com>
@vercel

vercel Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
scriptc Ready Ready Preview, v0 Oct 23, 2026 2:55pm UTC

Comment on lines +15044 to +15052
static inline size_t scr_weak_mix(uintptr_t bits) {
bits ^= bits >> 33;
bits *= 0xff51afd7ed558ccdull;
bits ^= bits >> 29;
return (size_t)bits;
}
static inline size_t scr_weak_entry_hash(const ScrWeakMap *owner, const void *key, unsigned kind) {
return scr_weak_mix((uintptr_t)key ^ ((uintptr_t)owner * 0x9E3779B97F4A7C15ull) ^ ((uintptr_t)kind << 56));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the supported wasm32-wasi target, the new weak-collection hashes shift 32-bit uintptr_t values by 33 and 56 bits, introducing undefined behavior into every weak-collection lookup and insertion.

Fix on Vercel

This branch was successfully deployed

1 active deployment
Preview — 52792d8c Deployed Oct 23, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant