Commit 716fa007 by Evan Brown Committed by Copybara-Service

Partial roll forward of reentrant validation with the validation itself…

Partial roll forward of reentrant validation with the validation itself disabled. This will make it easier to roll back and forwards in the future (if needed) without causing merge conflicts in unrelated code.

PiperOrigin-RevId: 582059046
Change-Id: I66dc6527e7a0b351367b7a391c2d653fe793143f
parent c046692a
...@@ -2161,7 +2161,7 @@ class raw_hash_set { ...@@ -2161,7 +2161,7 @@ class raw_hash_set {
alignas(slot_type) unsigned char raw[sizeof(slot_type)]; alignas(slot_type) unsigned char raw[sizeof(slot_type)];
slot_type* slot = reinterpret_cast<slot_type*>(&raw); slot_type* slot = reinterpret_cast<slot_type*>(&raw);
PolicyTraits::construct(&alloc_ref(), slot, std::forward<Args>(args)...); construct(slot, std::forward<Args>(args)...);
const auto& elem = PolicyTraits::element(slot); const auto& elem = PolicyTraits::element(slot);
return PolicyTraits::apply(InsertSlot<true>{*this, std::move(*slot)}, elem); return PolicyTraits::apply(InsertSlot<true>{*this, std::move(*slot)}, elem);
} }
...@@ -2266,7 +2266,7 @@ class raw_hash_set { ...@@ -2266,7 +2266,7 @@ class raw_hash_set {
// a better match if non-const iterator is passed as an argument. // a better match if non-const iterator is passed as an argument.
void erase(iterator it) { void erase(iterator it) {
AssertIsFull(it.control(), it.generation(), it.generation_ptr(), "erase()"); AssertIsFull(it.control(), it.generation(), it.generation_ptr(), "erase()");
PolicyTraits::destroy(&alloc_ref(), it.slot()); destroy(it.slot());
erase_meta_only(it); erase_meta_only(it);
} }
...@@ -2558,10 +2558,9 @@ class raw_hash_set { ...@@ -2558,10 +2558,9 @@ class raw_hash_set {
std::pair<iterator, bool> operator()(const K& key, Args&&...) && { std::pair<iterator, bool> operator()(const K& key, Args&&...) && {
auto res = s.find_or_prepare_insert(key); auto res = s.find_or_prepare_insert(key);
if (res.second) { if (res.second) {
PolicyTraits::transfer(&s.alloc_ref(), s.slot_array() + res.first, s.transfer(s.slot_array() + res.first, &slot);
&slot);
} else if (do_destroy) { } else if (do_destroy) {
PolicyTraits::destroy(&s.alloc_ref(), &slot); s.destroy(&slot);
} }
return {s.iterator_at(res.first), res.second}; return {s.iterator_at(res.first), res.second};
} }
...@@ -2570,13 +2569,25 @@ class raw_hash_set { ...@@ -2570,13 +2569,25 @@ class raw_hash_set {
slot_type&& slot; slot_type&& slot;
}; };
// TODO(b/303305702): re-enable reentrant validation.
template <typename... Args>
inline void construct(slot_type* slot, Args&&... args) {
PolicyTraits::construct(&alloc_ref(), slot, std::forward<Args>(args)...);
}
inline void destroy(slot_type* slot) {
PolicyTraits::destroy(&alloc_ref(), slot);
}
inline void transfer(slot_type* to, slot_type* from) {
PolicyTraits::transfer(&alloc_ref(), to, from);
}
inline void destroy_slots() { inline void destroy_slots() {
const size_t cap = capacity(); const size_t cap = capacity();
const ctrl_t* ctrl = control(); const ctrl_t* ctrl = control();
slot_type* slot = slot_array(); slot_type* slot = slot_array();
for (size_t i = 0; i != cap; ++i) { for (size_t i = 0; i != cap; ++i) {
if (IsFull(ctrl[i])) { if (IsFull(ctrl[i])) {
PolicyTraits::destroy(&alloc_ref(), slot + i); destroy(slot + i);
} }
} }
} }
...@@ -2639,7 +2650,7 @@ class raw_hash_set { ...@@ -2639,7 +2650,7 @@ class raw_hash_set {
size_t new_i = target.offset; size_t new_i = target.offset;
total_probe_length += target.probe_length; total_probe_length += target.probe_length;
SetCtrl(common(), new_i, H2(hash), sizeof(slot_type)); SetCtrl(common(), new_i, H2(hash), sizeof(slot_type));
PolicyTraits::transfer(&alloc_ref(), new_slots + new_i, old_slots + i); transfer(new_slots + new_i, old_slots + i);
} }
} }
if (old_capacity) { if (old_capacity) {
...@@ -2749,7 +2760,7 @@ class raw_hash_set { ...@@ -2749,7 +2760,7 @@ class raw_hash_set {
reserve(size); reserve(size);
for (iterator it = that.begin(); it != that.end(); ++it) { for (iterator it = that.begin(); it != that.end(); ++it) {
insert(std::move(PolicyTraits::element(it.slot()))); insert(std::move(PolicyTraits::element(it.slot())));
PolicyTraits::destroy(&that.alloc_ref(), it.slot()); that.destroy(it.slot());
} }
that.dealloc(); that.dealloc();
that.common() = CommonFields{}; that.common() = CommonFields{};
...@@ -2840,8 +2851,7 @@ class raw_hash_set { ...@@ -2840,8 +2851,7 @@ class raw_hash_set {
// POSTCONDITION: *m.iterator_at(i) == value_type(forward<Args>(args)...). // POSTCONDITION: *m.iterator_at(i) == value_type(forward<Args>(args)...).
template <class... Args> template <class... Args>
void emplace_at(size_t i, Args&&... args) { void emplace_at(size_t i, Args&&... args) {
PolicyTraits::construct(&alloc_ref(), slot_array() + i, construct(slot_array() + i, std::forward<Args>(args)...);
std::forward<Args>(args)...);
assert(PolicyTraits::apply(FindElement{*this}, *iterator_at(i)) == assert(PolicyTraits::apply(FindElement{*this}, *iterator_at(i)) ==
iterator_at(i) && iterator_at(i) &&
...@@ -2907,8 +2917,7 @@ class raw_hash_set { ...@@ -2907,8 +2917,7 @@ class raw_hash_set {
} }
static void transfer_slot_fn(void* set, void* dst, void* src) { static void transfer_slot_fn(void* set, void* dst, void* src) {
auto* h = static_cast<raw_hash_set*>(set); auto* h = static_cast<raw_hash_set*>(set);
PolicyTraits::transfer(&h->alloc_ref(), static_cast<slot_type*>(dst), h->transfer(static_cast<slot_type*>(dst), static_cast<slot_type*>(src));
static_cast<slot_type*>(src));
} }
// Note: dealloc_fn will only be used if we have a non-standard allocator. // Note: dealloc_fn will only be used if we have a non-standard allocator.
static void dealloc_fn(CommonFields& common, const PolicyFunctions&) { static void dealloc_fn(CommonFields& common, const PolicyFunctions&) {
......
...@@ -409,19 +409,15 @@ struct StringTable ...@@ -409,19 +409,15 @@ struct StringTable
using Base::Base; using Base::Base;
}; };
struct IntTable template <typename T>
: raw_hash_set<IntPolicy, hash_default_hash<int64_t>, struct ValueTable : raw_hash_set<ValuePolicy<T>, hash_default_hash<T>,
std::equal_to<int64_t>, std::allocator<int64_t>> { std::equal_to<T>, std::allocator<T>> {
using Base = typename IntTable::raw_hash_set; using Base = typename ValueTable::raw_hash_set;
using Base::Base; using Base::Base;
}; };
struct Uint8Table using IntTable = ValueTable<int64_t>;
: raw_hash_set<Uint8Policy, hash_default_hash<uint8_t>, using Uint8Table = ValueTable<uint8_t>;
std::equal_to<uint8_t>, std::allocator<uint8_t>> {
using Base = typename Uint8Table::raw_hash_set;
using Base::Base;
};
template <typename T> template <typename T>
struct CustomAlloc : std::allocator<T> { struct CustomAlloc : std::allocator<T> {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment