[libcxx-commits] [PATCH] D128021: [libc++] Don't call key_eq in unordered_map/set rehashing routine

Ivan via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jun 16 19:24:12 PDT 2022


itrofimow created this revision.
Herald added a project: All.
itrofimow requested review of this revision.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

As of now containers key_eq might get called when rehashing happens, which is redundant for unique keys containers.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128021

Files:
  libcxx/include/__hash_table
  libcxx/include/unordered_map
  libcxx/include/unordered_set


Index: libcxx/include/unordered_set
===================================================================
--- libcxx/include/unordered_set
+++ libcxx/include/unordered_set
@@ -501,7 +501,8 @@
                   "Invalid allocator::value_type");
 
 private:
-    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
+    typedef __hash_table<value_type, hasher, key_equal, allocator_type,
+        __hash_table_traits<true>> __table;
 
     __table __table_;
 
@@ -1157,7 +1158,8 @@
                   "Invalid allocator::value_type");
 
 private:
-    typedef __hash_table<value_type, hasher, key_equal, allocator_type> __table;
+    typedef __hash_table<value_type, hasher, key_equal, allocator_type,
+        __hash_table_traits<false>> __table;
 
     __table __table_;
 
Index: libcxx/include/unordered_map
===================================================================
--- libcxx/include/unordered_map
+++ libcxx/include/unordered_map
@@ -1032,7 +1032,7 @@
                                                  __value_type>::type          __allocator_type;
 
     typedef __hash_table<__value_type, __hasher,
-                         __key_equal,  __allocator_type>   __table;
+                         __key_equal,  __allocator_type, __hash_table_traits<true>>   __table;
 
     __table __table_;
 
@@ -1922,7 +1922,7 @@
                                                  __value_type>::type          __allocator_type;
 
     typedef __hash_table<__value_type, __hasher,
-                         __key_equal,  __allocator_type>   __table;
+                         __key_equal,  __allocator_type, __hash_table_traits<false>>   __table;
 
     __table __table_;
 
Index: libcxx/include/__hash_table
===================================================================
--- libcxx/include/__hash_table
+++ libcxx/include/__hash_table
@@ -860,7 +860,11 @@
 template <class _Key, class _Hash, class _Equal>
 int __diagnose_unordered_container_requirements(void*);
 
-template <class _Tp, class _Hash, class _Equal, class _Alloc>
+template <bool _Unique_Keys> struct __hash_table_traits {
+    typedef integral_constant<bool, _Unique_Keys>  __unique_keys;
+};
+
+template <class _Tp, class _Hash, class _Equal, class _Alloc, class _Traits>
 class __hash_table
 {
 public:
@@ -921,6 +925,7 @@
     typedef unique_ptr<__next_pointer[], __bucket_list_deleter> __bucket_list;
     typedef allocator_traits<__pointer_allocator>          __pointer_alloc_traits;
     typedef typename __bucket_list_deleter::pointer       __node_pointer_pointer;
+    typedef typename _Traits::__unique_keys               __unique_keys;
 
     // --- Member data begin ---
     __bucket_list                                         __bucket_list_;
@@ -2274,11 +2279,13 @@
                     else
                     {
                         __next_pointer __np = __cp;
-                        for (; __np->__next_ != nullptr &&
-                               key_eq()(__cp->__upcast()->__value_,
-                                        __np->__next_->__upcast()->__value_);
-                                                           __np = __np->__next_)
-                            ;
+                        if (!__unique_keys{}) {
+                            for (; __np->__next_ != nullptr &&
+                                   key_eq()(__cp->__upcast()->__value_,
+                                            __np->__next_->__upcast()->__value_);
+                                                               __np = __np->__next_)
+                                ;
+                        }
                         __pp->__next_ = __np->__next_;
                         __np->__next_ = __bucket_list_[__chash]->__next_;
                         __bucket_list_[__chash]->__next_ = __cp;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D128021.437769.patch
Type: text/x-patch
Size: 3809 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220617/012a3022/attachment.bin>


More information about the libcxx-commits mailing list