summaryrefslogtreecommitdiff
path: root/absl
diff options
context:
space:
mode:
authorGravatar Evan Brown <ezb@google.com>2023-11-07 08:50:48 -0800
committerGravatar Copybara-Service <copybara-worker@google.com>2023-11-07 08:51:52 -0800
commit116ee0fed75c1d032604f3b675e7e44e10d124b4 (patch)
treedf8fff6521175367ace26151a505c0bfed03df40 /absl
parent3be31775945aa843c230afc77bb63a98450a413d (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.h34
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;