[libcxx-commits] [libcxx] [libc++] Optimize __hash_table::remove(const_iterator) (PR #236713)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Oct 29 03:23:58 PDT 2026
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/236713
None
>From 8f1351f62d3ad5b2cab307d897b39200ddb401e8 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Thu, 29 Oct 2026 11:23:27 +0100
Subject: [PATCH] [libc++] Optimize __hash_table::remove(const_iterator)
---
libcxx/include/__hash_table | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index 23916e3a3ecf32..739a0f8119fa4f 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -1962,20 +1962,32 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT {
size_t __chash = std::__constrain_hash(__cn->__hash(), __bc);
// find previous node
__next_pointer __pn = __bucket_list_[__chash];
- for (; __pn->__next_ != __cn; __pn = __pn->__next_)
- ;
- // Fix up __bucket_list_
- // if __pn is not in same bucket (before begin is not in same bucket) &&
- // if __cn->__next_ is not in same bucket (nullptr is not in same bucket)
- if (__pn == __first_node_.__ptr() || std::__constrain_hash(__pn->__hash(), __bc) != __chash) {
- if (__cn->__next_ == nullptr || std::__constrain_hash(__cn->__next_->__hash(), __bc) != __chash)
+
+ if (__pn->__next_ == __cn) {
+ // If we're at the start of the bucket we might need to update the bucket list.
+
+ // If there are no more nodes, update the bucket to be emtpy
+ if (__cn->__next_ == nullptr)
+ __bucket_list_[__chash] = nullptr;
+
+ // If the next element is not in the same bucket, we need update the current bucket to be empty and the next bucket
+ // to the previous node.
+ else if (auto __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc); __nhash != __chash) {
__bucket_list_[__chash] = nullptr;
- }
- // if __cn->__next_ is not in same bucket (nullptr is in same bucket)
- if (__cn->__next_ != nullptr) {
- size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc);
- if (__nhash != __chash)
__bucket_list_[__nhash] = __pn;
+ }
+ // Otherwise we don't need to do anything special. Simply removing the bucket from the linked list is enough.
+ } else {
+ // The removed node is not at the start of the bucket, so we need to find it.
+ for (; __pn->__next_ != __cn; __pn = __pn->__next_)
+ ;
+
+ // If we're at the end of the bucket and point to the next bucket, we need to update the bucket list.
+ if (__cn->__next_ != nullptr) {
+ size_t __nhash = std::__constrain_hash(__cn->__next_->__hash(), __bc);
+ if (__nhash != __chash)
+ __bucket_list_[__nhash] = __pn;
+ }
}
// remove __cn
__pn->__next_ = __cn->__next_;
More information about the libcxx-commits
mailing list