[libcxx-commits] [libcxx] [libc++] Optimize __tree::find and __tree::__erase_unique (PR #152370)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Aug 25 07:33:49 PDT 2025
philnik777 wrote:
> > However for their multi versions this can mean a change in behaviour since it's not longer guaranteed that find will return the first element.
>
> Should that go in the release notes as well?
Yes, this should probably be release noted. I'll make a patch.
> We have this function that tries to find all bookmark nodes with a given URL:
>
> ```
> std::vector<BookmarkNode*> BookmarkModel::GetNodesByURL(GURL url) {
> std::vector<BookmarkNode*> nodes;
> auto i = nodes_ordered_by_url_set_.find<GURL>(url);
> while (i != nodes_ordered_by_url_set_.end() && (*i)->url() == url) {
> nodes.push_back(*i);
> ++i;
> }
> return nodes;
> }
> ```
>
> `nodes_ordered_by_url_set_` looks like so:
>
> ```
> // Used to order BookmarkNodes by URL as well as lookups using GURL.
> class NodeUrlComparator {
> public:
> // Required by std::set to support GURL-based lookups.
> using is_transparent = void;
>
> bool operator()(const BookmarkNode* n1, const BookmarkNode* n2) const {
> return n1->url() < n2->url();
> }
> bool operator()(const BookmarkNode* n1, const GURL& url2) const {
> return n1->url() < url2;
> }
> bool operator()(const GURL& url1, const BookmarkNode* n2) const {
> return url1 < n2->url();
> }
> };
>
> using NodesOrderedByUrlSet = std::multiset<BookmarkNode*, NodeUrlComparator>;
> NodesOrderedByUrlSet nodes_ordered_by_url_set_;
> ```
>
> The whole thing as a standalone repro (the .sh is meant to run on a mac; needs minor tweaks to run on linux): [repro.zip](https://github.com/user-attachments/files/21971130/repro.zip) This includes a single standalone .cc file that prints `count: 2` without this commit but `count: 1` with it. It also includes a .sh script to compile libc++ and link the included .cc file against the just-built libc++. You probably have a local script for the latter part that you like better :)
>
> From what I understand, our code is incorrect, and we should use e.g. `equal_range()` instead. I'm only mentioning this here in case other folks run into it.
>
> (But, see question in the comment above please :))
Yeah, this looks incorrect to me. You want to either use `lower_bound()` to get the first element, or `equal_range()` so you can simply iterate through the equal elements.
https://github.com/llvm/llvm-project/pull/152370
More information about the libcxx-commits
mailing list