Skip to content

Commit 41a6263

Browse files
Abseil Teamsuertreus
authored andcommitted
Export of internal Abseil changes
-- dcd4d95f6201dc5781a3a374be8eb10c812fd98a by Derek Mauro <[email protected]>: Add -Wundef to GCC warnings PiperOrigin-RevId: 322388155 -- b030746368262aff6bc487f5525bcd9b32d18ebb by Abseil Team <[email protected]>: Google internal clean-up. PiperOrigin-RevId: 322381901 -- 18e4cfcd50730c493cfc0cf1e127e57c186ce90b by Evan Brown <[email protected]>: Rollback b-tree erase simplification change. PiperOrigin-RevId: 322368252 -- d15431c52fa7ccb25ffbd967fd11f8f58246d48a by Abseil Team <[email protected]>: Update MOCK_METHOD (new format) in memory/memory_test.cc PiperOrigin-RevId: 322208282 GitOrigin-RevId: dcd4d95f6201dc5781a3a374be8eb10c812fd98a Change-Id: I3a900b4993f86bdd1c9597819c7a0e6e1759eda3
1 parent 3c2bed2 commit 41a6263

File tree

7 files changed

+165
-86
lines changed

7 files changed

+165
-86
lines changed

absl/base/policy_checks.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
#endif
4242

4343
// -----------------------------------------------------------------------------
44-
// Compiler Check
44+
// Toolchain Check
4545
// -----------------------------------------------------------------------------
4646

4747
// We support MSVC++ 14.0 update 2 and later.

absl/container/internal/btree.h

Lines changed: 137 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@ struct common_params {
255255
static void move(Alloc *alloc, slot_type *src, slot_type *dest) {
256256
slot_policy::move(alloc, src, dest);
257257
}
258+
static void move(Alloc *alloc, slot_type *first, slot_type *last,
259+
slot_type *result) {
260+
slot_policy::move(alloc, first, last, result);
261+
}
258262
};
259263

260264
// A parameters structure for holding the type parameters for a btree_map.
@@ -332,6 +336,13 @@ struct set_slot_policy {
332336
static void move(Alloc * /*alloc*/, slot_type *src, slot_type *dest) {
333337
*dest = std::move(*src);
334338
}
339+
340+
template <typename Alloc>
341+
static void move(Alloc *alloc, slot_type *first, slot_type *last,
342+
slot_type *result) {
343+
for (slot_type *src = first, *dest = result; src != last; ++src, ++dest)
344+
move(alloc, src, dest);
345+
}
335346
};
336347

337348
// A parameters structure for holding the type parameters for a btree_set.
@@ -748,10 +759,14 @@ class btree_node {
748759
template <typename... Args>
749760
void emplace_value(size_type i, allocator_type *alloc, Args &&... args);
750761

751-
// Removes the values at positions [i, i + to_erase), shifting all existing
752-
// values and children after that range to the left by to_erase. Clears all
753-
// children between [i, i + to_erase).
754-
void remove_values(field_type i, field_type to_erase, allocator_type *alloc);
762+
// Removes the value at position i, shifting all existing values and children
763+
// at positions > i to the left by 1.
764+
void remove_value(int i, allocator_type *alloc);
765+
766+
// Removes the values at positions [i, i + to_erase), shifting all values
767+
// after that range to the left by to_erase. Does not change children at all.
768+
void remove_values_ignore_children(int i, int to_erase,
769+
allocator_type *alloc);
755770

756771
// Rebalances a node with its right sibling.
757772
void rebalance_right_to_left(int to_move, btree_node *right,
@@ -763,7 +778,7 @@ class btree_node {
763778
void split(int insert_position, btree_node *dest, allocator_type *alloc);
764779

765780
// Merges a node with its right sibling, moving all of the values and the
766-
// delimiting key in the parent node onto itself, and deleting the src node.
781+
// delimiting key in the parent node onto itself.
767782
void merge(btree_node *src, allocator_type *alloc);
768783

769784
// Node allocation/deletion routines.
@@ -784,27 +799,9 @@ class btree_node {
784799
absl::container_internal::SanitizerPoisonMemoryRegion(
785800
&mutable_child(start()), (kNodeValues + 1) * sizeof(btree_node *));
786801
}
787-
788-
// Deletes a node and all of its children.
789-
// TODO(ezb): don't use recursion here to avoid potential stack overflows.
790-
static void clear_and_delete(btree_node *node, allocator_type *alloc) {
791-
const field_type start = node->start();
792-
const field_type finish = node->finish();
793-
for (field_type i = start; i < finish; ++i) {
794-
node->value_destroy(i, alloc);
795-
}
796-
if (node->leaf()) {
797-
absl::container_internal::Deallocate<Alignment()>(
798-
alloc, node, LeafSize(node->max_count()));
799-
} else {
800-
// If the node is empty, then there are no children so don't try clearing.
801-
if (start < finish) {
802-
for (field_type i = start; i <= finish; ++i) {
803-
clear_and_delete(node->child(i), alloc);
804-
}
805-
}
806-
absl::container_internal::Deallocate<Alignment()>(alloc, node,
807-
InternalSize());
802+
void destroy(allocator_type *alloc) {
803+
for (int i = start(); i < finish(); ++i) {
804+
value_destroy(i, alloc);
808805
}
809806
}
810807

@@ -1426,8 +1423,25 @@ class btree {
14261423
}
14271424

14281425
// Deletion helper routines.
1426+
void erase_same_node(iterator begin, iterator end);
1427+
iterator erase_from_leaf_node(iterator begin, size_type to_erase);
14291428
iterator rebalance_after_delete(iterator iter);
14301429

1430+
// Deallocates a node of a certain size in bytes using the allocator.
1431+
void deallocate(const size_type size, node_type *node) {
1432+
absl::container_internal::Deallocate<node_type::Alignment()>(
1433+
mutable_allocator(), node, size);
1434+
}
1435+
1436+
void delete_internal_node(node_type *node) {
1437+
node->destroy(mutable_allocator());
1438+
deallocate(node_type::InternalSize(), node);
1439+
}
1440+
void delete_leaf_node(node_type *node) {
1441+
node->destroy(mutable_allocator());
1442+
deallocate(node_type::LeafSize(node->max_count()), node);
1443+
}
1444+
14311445
// Rebalances or splits the node iter points to.
14321446
void rebalance_or_split(iterator *iter);
14331447

@@ -1496,6 +1510,9 @@ class btree {
14961510
template <typename K>
14971511
iterator internal_find(const K &key) const;
14981512

1513+
// Deletes a node and all of its children.
1514+
void internal_clear(node_type *node);
1515+
14991516
// Verifies the tree structure of node.
15001517
int internal_verify(const node_type *node, const key_type *lo,
15011518
const key_type *hi) const;
@@ -1563,29 +1580,26 @@ inline void btree_node<P>::emplace_value(const size_type i,
15631580
}
15641581

15651582
template <typename P>
1566-
inline void btree_node<P>::remove_values(const field_type i,
1567-
const field_type to_erase,
1568-
allocator_type *alloc) {
1569-
// Transfer values after the removed range into their new places.
1570-
const field_type orig_finish = finish();
1571-
const field_type src_i = i + to_erase;
1572-
for (field_type j = i; j < src_i; ++j) {
1573-
value_destroy(j, alloc);
1583+
inline void btree_node<P>::remove_value(const int i, allocator_type *alloc) {
1584+
if (!leaf() && finish() > i + 1) {
1585+
assert(child(i + 1)->count() == 0);
1586+
for (size_type j = i + 1; j < finish(); ++j) {
1587+
set_child(j, child(j + 1));
1588+
}
1589+
clear_child(finish());
15741590
}
1575-
transfer_n(orig_finish - src_i, i, src_i, this, alloc);
15761591

1577-
if (!leaf()) {
1578-
// Delete all children between begin and end.
1579-
for (field_type j = 0; j < to_erase; ++j) {
1580-
clear_and_delete(child(i + j + 1), alloc);
1581-
}
1582-
// Rotate children after end into new positions.
1583-
for (field_type j = i + to_erase + 1; j <= orig_finish; ++j) {
1584-
set_child(j - to_erase, child(j));
1585-
clear_child(j);
1586-
}
1592+
remove_values_ignore_children(i, /*to_erase=*/1, alloc);
1593+
}
1594+
1595+
template <typename P>
1596+
inline void btree_node<P>::remove_values_ignore_children(
1597+
const int i, const int to_erase, allocator_type *alloc) {
1598+
params_type::move(alloc, slot(i + to_erase), finish_slot(), slot(i));
1599+
for (int j = finish() - to_erase; j < finish(); ++j) {
1600+
value_destroy(j, alloc);
15871601
}
1588-
set_finish(orig_finish - to_erase);
1602+
set_finish(finish() - to_erase);
15891603
}
15901604

15911605
template <typename P>
@@ -1737,8 +1751,8 @@ void btree_node<P>::merge(btree_node *src, allocator_type *alloc) {
17371751
set_finish(start() + 1 + count() + src->count());
17381752
src->set_finish(src->start());
17391753

1740-
// Remove the value on the parent node and delete the src node.
1741-
parent()->remove_values(position(), /*to_erase=*/1, alloc);
1754+
// Remove the value on the parent node.
1755+
parent()->remove_value(position(), alloc);
17421756
}
17431757

17441758
////
@@ -2020,7 +2034,7 @@ auto btree<P>::erase(iterator iter) -> iterator {
20202034
bool internal_delete = false;
20212035
if (!iter.node->leaf()) {
20222036
// Deletion of a value on an internal node. First, move the largest value
2023-
// from our left child here, then delete that position (in remove_values()
2037+
// from our left child here, then delete that position (in remove_value()
20242038
// below). We can get to the largest value from our left child by
20252039
// decrementing iter.
20262040
iterator internal_iter(iter);
@@ -2032,7 +2046,7 @@ auto btree<P>::erase(iterator iter) -> iterator {
20322046
}
20332047

20342048
// Delete the key from the leaf.
2035-
iter.node->remove_values(iter.position, /*to_erase=*/1, mutable_allocator());
2049+
iter.node->remove_value(iter.position, mutable_allocator());
20362050
--size_;
20372051

20382052
// We want to return the next value after the one we just erased. If we
@@ -2107,9 +2121,7 @@ auto btree<P>::erase_range(iterator begin, iterator end)
21072121
}
21082122

21092123
if (begin.node == end.node) {
2110-
assert(end.position > begin.position);
2111-
begin.node->remove_values(begin.position, end.position - begin.position,
2112-
mutable_allocator());
2124+
erase_same_node(begin, end);
21132125
size_ -= count;
21142126
return {count, rebalance_after_delete(begin)};
21152127
}
@@ -2119,18 +2131,60 @@ auto btree<P>::erase_range(iterator begin, iterator end)
21192131
if (begin.node->leaf()) {
21202132
const size_type remaining_to_erase = size_ - target_size;
21212133
const size_type remaining_in_node = begin.node->finish() - begin.position;
2122-
const size_type to_erase =
2123-
(std::min)(remaining_to_erase, remaining_in_node);
2124-
begin.node->remove_values(begin.position, to_erase, mutable_allocator());
2125-
size_ -= to_erase;
2126-
begin = rebalance_after_delete(begin);
2134+
begin = erase_from_leaf_node(
2135+
begin, (std::min)(remaining_to_erase, remaining_in_node));
21272136
} else {
21282137
begin = erase(begin);
21292138
}
21302139
}
21312140
return {count, begin};
21322141
}
21332142

2143+
template <typename P>
2144+
void btree<P>::erase_same_node(iterator begin, iterator end) {
2145+
assert(begin.node == end.node);
2146+
assert(end.position > begin.position);
2147+
2148+
node_type *node = begin.node;
2149+
size_type to_erase = end.position - begin.position;
2150+
if (!node->leaf()) {
2151+
// Delete all children between begin and end.
2152+
for (size_type i = 0; i < to_erase; ++i) {
2153+
internal_clear(node->child(begin.position + i + 1));
2154+
}
2155+
// Rotate children after end into new positions.
2156+
for (size_type i = begin.position + to_erase + 1; i <= node->finish();
2157+
++i) {
2158+
node->set_child(i - to_erase, node->child(i));
2159+
node->clear_child(i);
2160+
}
2161+
}
2162+
node->remove_values_ignore_children(begin.position, to_erase,
2163+
mutable_allocator());
2164+
2165+
// Do not need to update rightmost_, because
2166+
// * either end == this->end(), and therefore node == rightmost_, and still
2167+
// exists
2168+
// * or end != this->end(), and therefore rightmost_ hasn't been erased, since
2169+
// it wasn't covered in [begin, end)
2170+
}
2171+
2172+
template <typename P>
2173+
auto btree<P>::erase_from_leaf_node(iterator begin, size_type to_erase)
2174+
-> iterator {
2175+
node_type *node = begin.node;
2176+
assert(node->leaf());
2177+
assert(node->finish() > begin.position);
2178+
assert(begin.position + to_erase <= node->finish());
2179+
2180+
node->remove_values_ignore_children(begin.position, to_erase,
2181+
mutable_allocator());
2182+
2183+
size_ -= to_erase;
2184+
2185+
return rebalance_after_delete(begin);
2186+
}
2187+
21342188
template <typename P>
21352189
template <typename K>
21362190
auto btree<P>::erase_unique(const K &key) -> size_type {
@@ -2159,7 +2213,7 @@ auto btree<P>::erase_multi(const K &key) -> size_type {
21592213
template <typename P>
21602214
void btree<P>::clear() {
21612215
if (!empty()) {
2162-
node_type::clear_and_delete(root(), mutable_allocator());
2216+
internal_clear(root());
21632217
}
21642218
mutable_root() = EmptyNode();
21652219
rightmost_ = EmptyNode();
@@ -2300,7 +2354,12 @@ void btree<P>::rebalance_or_split(iterator *iter) {
23002354
template <typename P>
23012355
void btree<P>::merge_nodes(node_type *left, node_type *right) {
23022356
left->merge(right, mutable_allocator());
2303-
if (rightmost_ == right) rightmost_ = left;
2357+
if (right->leaf()) {
2358+
if (rightmost_ == right) rightmost_ = left;
2359+
delete_leaf_node(right);
2360+
} else {
2361+
delete_internal_node(right);
2362+
}
23042363
}
23052364

23062365
template <typename P>
@@ -2357,20 +2416,20 @@ bool btree<P>::try_merge_or_rebalance(iterator *iter) {
23572416

23582417
template <typename P>
23592418
void btree<P>::try_shrink() {
2360-
node_type *orig_root = root();
2361-
if (orig_root->count() > 0) {
2419+
if (root()->count() > 0) {
23622420
return;
23632421
}
23642422
// Deleted the last item on the root node, shrink the height of the tree.
2365-
if (orig_root->leaf()) {
2423+
if (root()->leaf()) {
23662424
assert(size() == 0);
2425+
delete_leaf_node(root());
23672426
mutable_root() = rightmost_ = EmptyNode();
23682427
} else {
2369-
node_type *child = orig_root->start_child();
2428+
node_type *child = root()->start_child();
23702429
child->make_root();
2430+
delete_internal_node(root());
23712431
mutable_root() = child;
23722432
}
2373-
node_type::clear_and_delete(orig_root, mutable_allocator());
23742433
}
23752434

23762435
template <typename P>
@@ -2415,7 +2474,7 @@ inline auto btree<P>::internal_emplace(iterator iter, Args &&... args)
24152474
old_root->start(), old_root, alloc);
24162475
new_root->set_finish(old_root->finish());
24172476
old_root->set_finish(old_root->start());
2418-
node_type::clear_and_delete(old_root, alloc);
2477+
delete_leaf_node(old_root);
24192478
mutable_root() = rightmost_ = new_root;
24202479
} else {
24212480
rebalance_or_split(&iter);
@@ -2518,6 +2577,18 @@ auto btree<P>::internal_find(const K &key) const -> iterator {
25182577
return {nullptr, 0};
25192578
}
25202579

2580+
template <typename P>
2581+
void btree<P>::internal_clear(node_type *node) {
2582+
if (!node->leaf()) {
2583+
for (int i = node->start(); i <= node->finish(); ++i) {
2584+
internal_clear(node->child(i));
2585+
}
2586+
delete_internal_node(node);
2587+
} else {
2588+
delete_leaf_node(node);
2589+
}
2590+
}
2591+
25212592
template <typename P>
25222593
int btree<P>::internal_verify(const node_type *node, const key_type *lo,
25232594
const key_type *hi) const {

absl/container/internal/container_memory.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,13 @@ struct map_slot_policy {
429429
std::move(src->value));
430430
}
431431
}
432+
433+
template <class Allocator>
434+
static void move(Allocator* alloc, slot_type* first, slot_type* last,
435+
slot_type* result) {
436+
for (slot_type *src = first, *dest = result; src != last; ++src, ++dest)
437+
move(alloc, src, dest);
438+
}
432439
};
433440

434441
} // namespace container_internal

absl/copts/GENERATED_AbseilCopts.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ list(APPEND ABSL_GCC_FLAGS
8181
"-Wmissing-declarations"
8282
"-Woverlength-strings"
8383
"-Wpointer-arith"
84+
"-Wundef"
8485
"-Wunused-local-typedefs"
8586
"-Wunused-result"
8687
"-Wvarargs"

absl/copts/GENERATED_copts.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ ABSL_GCC_FLAGS = [
8282
"-Wmissing-declarations",
8383
"-Woverlength-strings",
8484
"-Wpointer-arith",
85+
"-Wundef",
8586
"-Wunused-local-typedefs",
8687
"-Wunused-result",
8788
"-Wvarargs",

absl/copts/copts.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
"-Wmissing-declarations",
129129
"-Woverlength-strings",
130130
"-Wpointer-arith",
131+
"-Wundef",
131132
"-Wunused-local-typedefs",
132133
"-Wunused-result",
133134
"-Wvarargs",

0 commit comments

Comments
 (0)