diff options
author | Evan Brown <ezb@google.com> | 2023-11-07 08:50:48 -0800 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-11-07 08:51:52 -0800 |
commit | 116ee0fed75c1d032604f3b675e7e44e10d124b4 (patch) | |
tree | df8fff6521175367ace26151a505c0bfed03df40 /absl | |
parent | 3be31775945aa843c230afc77bb63a98450a413d (diff) |
Add control()/slot() functions to iterator/const_iterator.
This allows for avoiding e.g. it.inner_.slot_ on const iterators.
Also, refactor HashtableDebugAccess::AllocatedByteSize to use regular iteration instead of looking directly at control/slot_array of the table in order to support small object optimization.
PiperOrigin-RevId: 580194253
Change-Id: I64cd69287834ee5c7a8daf867c532258806bfb7b
Diffstat (limited to 'absl')
-rw-r--r-- | absl/container/internal/raw_hash_set.h | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h index f702f6ad..2a2b1c4e 100644 --- a/absl/container/internal/raw_hash_set.h +++ b/absl/container/internal/raw_hash_set.h @@ -1746,6 +1746,9 @@ class raw_hash_set { if (ABSL_PREDICT_FALSE(*ctrl_ == ctrl_t::kSentinel)) ctrl_ = nullptr; } + ctrl_t* control() const { return ctrl_; } + slot_type* slot() const { return slot_; } + // We use EmptyGroup() for default-constructed iterators so that they can // be distinguished from end iterators, which have nullptr ctrl_. ctrl_t* ctrl_ = EmptyGroup(); @@ -1758,6 +1761,9 @@ class raw_hash_set { class const_iterator { friend class raw_hash_set; + template <class Container, typename Enabler> + friend struct absl::container_internal::hashtable_debug_internal:: + HashtableDebugAccess; public: using iterator_category = typename iterator::iterator_category; @@ -1791,6 +1797,8 @@ class raw_hash_set { const GenerationType* gen) : inner_(const_cast<ctrl_t*>(ctrl), const_cast<slot_type*>(slot), gen) { } + ctrl_t* control() const { return inner_.control(); } + slot_type* slot() const { return inner_.slot(); } iterator inner_; }; @@ -2257,8 +2265,8 @@ class raw_hash_set { // This overload is necessary because otherwise erase<K>(const K&) would be // a better match if non-const iterator is passed as an argument. void erase(iterator it) { - AssertIsFull(it.ctrl_, it.generation(), it.generation_ptr(), "erase()"); - destroy(it.slot_); + AssertIsFull(it.control(), it.generation(), it.generation_ptr(), "erase()"); + destroy(it.slot()); erase_meta_only(it); } @@ -2289,8 +2297,8 @@ class raw_hash_set { assert(this != &src); for (auto it = src.begin(), e = src.end(); it != e;) { auto next = std::next(it); - if (PolicyTraits::apply(InsertSlot<false>{*this, std::move(*it.slot_)}, - PolicyTraits::element(it.slot_)) + if (PolicyTraits::apply(InsertSlot<false>{*this, std::move(*it.slot())}, + PolicyTraits::element(it.slot())) .second) { src.erase_meta_only(it); } @@ -2304,10 +2312,9 @@ class raw_hash_set { } node_type extract(const_iterator position) { - AssertIsFull(position.inner_.ctrl_, position.inner_.generation(), + AssertIsFull(position.control(), position.inner_.generation(), position.inner_.generation_ptr(), "extract()"); - auto node = - CommonAccess::Transfer<node_type>(alloc_ref(), position.inner_.slot_); + auto node = CommonAccess::Transfer<node_type>(alloc_ref(), position.slot()); erase_meta_only(position); return node; } @@ -2612,7 +2619,7 @@ class raw_hash_set { // This merely updates the pertinent control byte. This can be used in // conjunction with Policy::transfer to move the object to another place. void erase_meta_only(const_iterator it) { - EraseMetaOnly(common(), it.inner_.ctrl_, sizeof(slot_type)); + EraseMetaOnly(common(), it.control(), sizeof(slot_type)); } // Allocates a backing array for `self` and initializes its control bytes. @@ -2758,8 +2765,8 @@ class raw_hash_set { if (size == 0) return *this; reserve(size); for (iterator it = that.begin(); it != that.end(); ++it) { - insert(std::move(PolicyTraits::element(it.slot_))); - that.destroy(it.slot_); + insert(std::move(PolicyTraits::element(it.slot()))); + that.destroy(it.slot()); } that.dealloc(); that.common() = CommonFields{}; @@ -3006,11 +3013,8 @@ struct HashtableDebugAccess<Set, absl::void_t<typename Set::raw_hash_set>> { if (per_slot != ~size_t{}) { m += per_slot * c.size(); } else { - const ctrl_t* ctrl = c.control(); - for (size_t i = 0; i != capacity; ++i) { - if (container_internal::IsFull(ctrl[i])) { - m += Traits::space_used(c.slot_array() + i); - } + for (auto it = c.begin(); it != c.end(); ++it) { + m += Traits::space_used(it.slot()); } } return m; |