Skip to content

feat(data-structures/unstable): add MultiMap#7100

Merged
bartlomieju merged 9 commits intodenoland:mainfrom
tomas-zijdemans:multimap
Apr 22, 2026
Merged

feat(data-structures/unstable): add MultiMap#7100
bartlomieju merged 9 commits intodenoland:mainfrom
tomas-zijdemans:multimap

Conversation

@tomas-zijdemans
Copy link
Copy Markdown
Contributor

@tomas-zijdemans tomas-zijdemans commented Apr 20, 2026

Adds MultiMap<K, V> under @std/data-structures/unstable. It's a Map-like container where each key holds an ordered list of values.

Covers the common "values keyed by group" case (e.g. parsed query strings, HTTP headers, users grouped by role) without hand-rolling Map<K, V[]> wrappers at every call site.

I plan to use it in the cache and xml module.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.53%. Comparing base (3e91d1e) to head (1b535e6).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7100      +/-   ##
==========================================
+ Coverage   94.51%   94.53%   +0.02%     
==========================================
  Files         630      631       +1     
  Lines       50970    51165     +195     
  Branches     9090     9127      +37     
==========================================
+ Hits        48175    48371     +196     
  Misses       2224     2224              
+ Partials      571      570       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

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

Nice work — well-documented, well-tested, and covers a real gap. A few things to address:

valueCount getter

size counting distinct keys follows Map convention, but multimap users very commonly need total value count. Consider adding a valueCount getter, cheaply maintained with an internal counter (increment in add, decrement in deleteEntry, reset in clear/delete). Without it the only way is to iterate everything.

Deno.customInspect

Not a blocker (other unstable data structures don't have it either), but [Symbol.for("Deno.customInspect")] would improve DX — console.log(multimap) would show something useful rather than an opaque object.

Comment thread data_structures/unstable_multimap.ts
Comment thread data_structures/unstable_multimap.ts
Comment thread data_structures/unstable_multimap.ts
Comment thread data_structures/unstable_multimap.ts
@tomas-zijdemans
Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review.

  • valueCount: Added a valueCount getter, backed by an internal counter as suggested
  • Deno.customInspect: Added one small hook so console.log(map) prints nicely. Opted not to add a Node-side twin (nodejs.util.inspect.custom), keeping this in line with the other data_structures modules. The Deno-side hook alone already fixes the unreadable default output; we can add the Node twin later if there's demand.
  • get() complexity note: Clarified the table row to Linear in the bucket size (copy) as suggested
  • SameValueZero consistency: Added a short comment on hasEntry() noting that .includes() already matches the SameValueZero loop in deleteEntry()
  • Simplify forEach(): Removed the thisArg-undefined branch; one loop with callbackfn.call(thisArg as T, ...) covers both cases.
  • Iterator style: Benchmarked hand-rolled vs. generator (1.7×–4.4× faster, never slower). Rewrote groups() as a hand-rolled iterator to match entries()/values(); kept keys() delegating to the native Map iterator.

Copy link
Copy Markdown
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

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

Thanks!

@bartlomieju bartlomieju enabled auto-merge (squash) April 22, 2026 10:20
@bartlomieju bartlomieju merged commit 65e6547 into denoland:main Apr 22, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants