45 #ifndef ABSL_CONTAINER_INTERNAL_BTREE_H_
46 #define ABSL_CONTAINER_INTERNAL_BTREE_H_
58 #include <type_traits>
61 #include "absl/base/macros.h"
62 #include "absl/container/internal/common.h"
63 #include "absl/container/internal/compressed_tuple.h"
64 #include "absl/container/internal/container_memory.h"
65 #include "absl/container/internal/layout.h"
66 #include "absl/memory/memory.h"
67 #include "absl/meta/type_traits.h"
68 #include "absl/strings/cord.h"
69 #include "absl/strings/string_view.h"
70 #include "absl/types/compare.h"
71 #include "absl/utility/utility.h"
75 namespace container_internal {
79 template <
typename Compare,
typename T>
84 struct StringBtreeDefaultLess {
112 struct StringBtreeDefaultGreater {
150 template <
typename Compare>
204 template <
typename T,
typename =
void>
206 template <
typename T,
typename =
void>
208 template <
typename T>
209 struct has_linear_node_search_preference<
210 T,
absl::
void_t<typename T::absl_btree_prefer_linear_node_search>>
212 template <
typename T>
213 struct prefers_linear_node_search<
214 T,
absl::
void_t<typename T::absl_btree_prefer_linear_node_search>>
215 : T::absl_btree_prefer_linear_node_search {};
217 template <
typename Key,
typename Compare,
typename Alloc,
int TargetNodeSize,
218 bool Multi,
typename SlotPolicy>
219 struct common_params {
235 using init_type =
typename slot_policy::mutable_value_type;
249 template <
typename LookupKey>
265 TargetNodeSize - (
sizeof(
void *) + 4),
283 template <
class...
Args>
307 template <
typename Key,
typename Data,
typename Compare,
typename Alloc,
308 int TargetNodeSize,
bool Multi>
309 struct map_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi,
310 map_slot_policy<Key, Data>> {
326 template <
typename T,
typename U>
328 -> decltype(std::declval<key_compare>()(left.first, right.first)) {
329 return key_compare::operator()(left.first, right.first);
334 template <
typename V>
342 -> decltype(slot_policy::mutable_key(s)) {
343 return slot_policy::mutable_key(
s);
350 template <
typename Key>
351 struct set_slot_policy {
362 std::forward<Args>(
args)...);
365 template <
typename Alloc>
370 template <
typename Alloc>
375 template <
typename Alloc>
381 template <
typename Alloc>
389 template <
typename Key,
typename Compare,
typename Alloc,
int TargetNodeSize,
391 struct set_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi,
392 set_slot_policy<Key>> {
394 using slot_type =
typename set_params::common_params::slot_type;
398 template <
typename V>
408 template <
typename Compare>
409 struct upper_bound_adapter {
411 template <
typename K1,
typename K2>
423 template <
typename V,
bool IsCompareTo>
424 struct SearchResult {
435 template <
typename V>
436 struct SearchResult<V,
false> {
444 static constexpr
bool IsEq() {
return false; }
450 template <
typename Params>
484 std::is_same<std::greater<key_type>,
530 "Alignment of all nodes must be equal.");
557 params_type::kTargetNodeSize
578 kInternalNodeMaxCount = 0,
603 template <
size_type N>
606 assert(
N < 3 || !
leaf());
607 return InternalLayout().template Pointer<N>(
reinterpret_cast<char *
>(
this));
609 template <
size_type N>
611 assert(
N < 3 || !
leaf());
613 reinterpret_cast<const char *
>(
this));
630 bool leaf()
const {
return GetField<1>()[3] != kInternalNodeMaxCount; }
638 assert(GetField<1>()[1] == 0);
693 template <
typename K>
700 template <
typename K>
707 template <
typename K,
typename Compare>
714 template <
typename K,
typename Compare>
723 template <
typename K,
typename Compare>
725 const K &
k,
int s,
const int e,
const Compare &comp,
728 if (!comp(
key(
s),
k)) {
738 template <
typename K,
typename Compare>
740 const K &
k,
int s,
const int e,
const Compare &comp,
756 template <
typename K,
typename Compare>
758 const K &
k,
int s,
int e,
const Compare &comp,
761 const int mid = (
s +
e) >> 1;
762 if (comp(
key(mid),
k)) {
773 template <
typename K,
typename CompareTo>
775 const K &
k,
int s,
int e,
const CompareTo &comp,
780 const int mid = (
s +
e) >> 1;
794 return {
s, exact_match};
797 const int mid = (
s +
e) >> 1;
813 template <
typename...
Args>
855 absl::container_internal::Deallocate<Alignment()>(
alloc, node,
size);
862 template <
typename...
Args>
908 for (
slot_type *src = src_node->slot(src_i +
n - 1), *
end = src -
n,
915 template <
typename P>
917 template <
typename N,
typename R,
typename P>
922 template <
typename Node,
typename Reference,
typename Po
inter>
959 template <
typename N,
typename R,
typename P,
972 template <
typename N,
typename R,
typename P,
982 if (
node->leaf() && ++position < node->
finish()) {
1042 template <
typename Params>
1044 template <
typename Tree>
1046 template <
typename Tree>
1048 template <
typename Tree>
1050 template <
typename Tree>
1052 template <
typename TreeType,
typename CheckerType>
1066 template <
typename Params>
1075 struct alignas(node_type::Alignment()) EmptyNodeType :
node_type {
1095 static EmptyNodeType *empty_node =
new EmptyNodeType;
1097 assert(empty_node->parent == empty_node);
1100 static constexpr EmptyNodeType empty_node(
1101 const_cast<EmptyNodeType *
>(&empty_node));
1102 return const_cast<EmptyNodeType *
>(&empty_node);
1162 template <
typename Btree>
1185 if (
alloc == other.allocator()) {
1220 template <
typename K>
1224 template <
typename K>
1231 template <
typename K>
1235 template <
typename K>
1239 template <
typename K>
1247 template <
typename K>
1249 template <
typename K>
1258 template <
typename K,
typename...
Args>
1267 template <
typename K,
typename...
Args>
1275 template <
typename InputIterator,
1276 typename = decltype(std::declval<const key_compare &>()(
1278 std::declval<const key_type &>()))>
1282 template <
typename InputIterator>
1286 template <
typename ValueType>
1290 template <
typename ValueType>
1299 template <
typename ValueType>
1303 template <
typename InputIterator>
1318 template <
typename K>
1322 template <
typename K>
1334 return root_.template get<0>();
1336 template <
typename K1,
typename K2>
1363 }
while (
n !=
root());
1375 return stats.leaf_nodes +
stats.internal_nodes;
1381 if (
stats.leaf_nodes == 1 &&
stats.internal_nodes == 0) {
1394 const double expected_values_per_node =
1405 if (
empty())
return 0.0;
1413 if (
empty())
return 0.0;
1415 static_cast<double>(
size());
1434 return &
root_.template get<1>();
1437 return root_.template get<1>();
1444 absl::container_internal::Allocate<node_type::Alignment()>(
1451 n->init_internal(parent);
1461 n->init_leaf(
n, max_count);
1493 template <
typename...
Args>
1501 template <
typename IterType>
1510 template <
typename K>
1512 const K &
key)
const;
1515 template <
typename K>
1517 const K &
key)
const;
1520 template <
typename K>
1524 template <
typename K>
1533 if (node ==
nullptr || (node ==
root() &&
empty())) {
1534 return node_stats(0, 0);
1537 return node_stats(1, 0);
1539 node_stats res(0, 1);
1562 template <
typename P>
1563 template <
typename...
Args>
1565 allocator_type *
alloc,
1572 transfer_n_backward(
finish() -
i,
i + 1,
i,
this,
1576 set_finish(
finish() + 1);
1578 if (!leaf() &&
finish() > i + 1) {
1579 for (
int j =
finish(); j >
i + 1; --j) {
1580 set_child(j,
child(j - 1));
1586 template <
typename P>
1589 allocator_type *
alloc) {
1591 value_destroy_n(i, to_erase,
alloc);
1594 transfer_n(orig_finish - src_i, i, src_i,
this,
alloc);
1598 for (
int j = 0;
j < to_erase; ++
j) {
1602 for (
int j = i + to_erase + 1;
j <= orig_finish; ++
j) {
1603 set_child(j - to_erase,
child(j));
1607 set_finish(orig_finish - to_erase);
1610 template <
typename P>
1613 allocator_type *
alloc) {
1614 assert(parent() == right->parent());
1615 assert(
position() + 1 == right->position());
1616 assert(right->count() >=
count());
1617 assert(to_move >= 1);
1618 assert(to_move <= right->
count());
1624 transfer_n(to_move - 1,
finish() + 1, right->start(), right,
alloc);
1627 parent()->transfer(
position(), right->start() + to_move - 1, right,
alloc);
1630 right->transfer_n(right->count() - to_move, right->start(),
1631 right->start() + to_move, right,
alloc);
1635 for (
int i = 0;
i < to_move; ++
i) {
1636 init_child(
finish() + i + 1, right->child(i));
1638 for (
int i = right->start(); i <= right->
finish() - to_move; ++
i) {
1639 assert(i + to_move <= right->max_count());
1640 right->init_child(i, right->child(i + to_move));
1641 right->clear_child(i + to_move);
1646 set_finish(
finish() + to_move);
1647 right->set_finish(right->finish() - to_move);
1650 template <
typename P>
1653 allocator_type *
alloc) {
1654 assert(parent() == right->parent());
1655 assert(
position() + 1 == right->position());
1656 assert(
count() >= right->count());
1657 assert(to_move >= 1);
1658 assert(to_move <=
count());
1667 right->transfer_n_backward(right->count(), right->start() + to_move,
1668 right->start(), right,
alloc);
1671 right->transfer(right->start() + to_move - 1,
position(), parent(),
alloc);
1674 right->transfer_n(to_move - 1, right->start(),
finish() - (to_move - 1),
this,
1682 for (
int i = right->finish(); i >= right->start(); --i) {
1683 right->init_child(i + to_move, right->child(i));
1684 right->clear_child(i);
1686 for (
int i = 1;
i <= to_move; ++
i) {
1687 right->init_child(i - 1,
child(
finish() - to_move + i));
1688 clear_child(
finish() - to_move + i);
1693 set_finish(
finish() - to_move);
1694 right->set_finish(right->finish() + to_move);
1697 template <
typename P>
1699 allocator_type *
alloc) {
1700 assert(
dest->count() == 0);
1701 assert(max_count() == kNodeSlots);
1707 if (insert_position ==
start()) {
1709 }
else if (insert_position == kNodeSlots) {
1715 assert(
count() >= 1);
1729 assert(
child(j) !=
nullptr);
1736 template <
typename P>
1738 assert(parent() == src->parent());
1739 assert(
position() + 1 == src->position());
1745 transfer_n(src->count(),
finish() + 1, src->start(), src,
alloc);
1749 for (
int i = src->start(), j =
finish() + 1;
i <= src->finish(); ++
i, ++
j) {
1750 init_child(j, src->child(i));
1751 src->clear_child(i);
1756 set_finish(
start() + 1 +
count() + src->count());
1757 src->set_finish(src->start());
1763 template <
typename P>
1766 node->value_destroy_n(node->start(), node->count(),
alloc);
1767 deallocate(LeafSize(node->max_count()), node,
alloc);
1770 if (node->count() == 0) {
1771 deallocate(InternalSize(), node,
alloc);
1776 btree_node *delete_root_parent = node->parent();
1779 while (!node->leaf()) node = node->start_child();
1782 int pos = node->position();
1783 btree_node *parent = node->parent();
1786 assert(pos <= parent->
finish());
1788 node = parent->child(
pos);
1789 if (!node->leaf()) {
1791 while (!node->leaf()) node = node->start_child();
1792 pos = node->position();
1793 parent = node->parent();
1795 node->value_destroy_n(node->start(), node->count(),
alloc);
1796 deallocate(LeafSize(node->max_count()), node,
alloc);
1798 }
while (pos <= parent->
finish());
1801 assert(
pos > parent->finish());
1804 pos = node->position();
1805 parent = node->parent();
1806 node->value_destroy_n(node->start(), node->count(),
alloc);
1807 deallocate(InternalSize(), node,
alloc);
1808 if (parent == delete_root_parent)
return;
1810 }
while (
pos > parent->finish());
1816 template <
typename N,
typename R,
typename P>
1819 assert(
position >= node->finish());
1820 btree_iterator
save(*
this);
1821 while (
position == node->finish() && !node->is_root()) {
1822 assert(node->parent()->child(node->position()) == node);
1824 node = node->parent();
1831 assert(position < node->
finish());
1833 while (!node->leaf()) {
1834 node = node->start_child();
1840 template <
typename N,
typename R,
typename P>
1844 btree_iterator
save(*
this);
1845 while (position < node->
start() && !node->is_root()) {
1846 assert(node->parent()->child(node->position()) == node);
1848 node = node->parent();
1851 if (position < node->
start()) {
1857 while (!node->leaf()) {
1858 node = node->child(node->finish());
1866 template <
typename P>
1867 template <
typename Btree>
1871 "Btree type must be same or const.");
1876 auto iter = other.begin();
1877 if (
iter == other.end())
return;
1878 insert_multi(maybe_move_from_iterator(
iter));
1880 for (;
iter != other.end(); ++
iter) {
1883 internal_emplace(
end(), maybe_move_from_iterator(
iter));
1887 template <
typename P>
1890 "Key comparison must be nothrow copy constructible");
1892 "Allocator must be nothrow copy constructible");
1894 "iterator not trivially copyable.");
1900 "target node size too large");
1903 using compare_result_type =
1908 "key comparison function must return absl::{weak,strong}_ordering or "
1912 static_assert(node_type::MinimumOverhead() >=
sizeof(
void *) + 4,
1913 "node space assumption incorrect");
1918 template <
typename P>
1919 template <
typename K>
1921 -> std::pair<iterator, bool> {
1922 const SearchResult<iterator, is_key_compare_to::value> res =
1923 internal_lower_bound(
key);
1925 const bool equal = res.HasMatch()
1927 : lower !=
end() && !compare_keys(
key, lower.key());
1928 return {lower,
equal};
1931 template <
typename P>
1932 template <
typename K>
1934 const std::pair<iterator, bool> lower_and_equal = lower_bound_equal(
key);
1935 const iterator lower = lower_and_equal.first;
1936 if (!lower_and_equal.second) {
1937 return {lower, lower};
1947 return {lower,
next};
1957 return {lower, upper_bound(
key)};
1960 template <
typename P>
1961 template <
typename K,
typename...
Args>
1963 -> std::pair<iterator, bool> {
1965 mutable_root() = rightmost_ = new_leaf_root_node(1);
1968 SearchResult<iterator, is_key_compare_to::value> res = internal_locate(
key);
1971 if (res.HasMatch()) {
1974 return {
iter,
false};
1978 if (last.node && !compare_keys(
key, last.key())) {
1980 return {last,
false};
1983 return {internal_emplace(
iter, std::forward<Args>(
args)...),
true};
1986 template <
typename P>
1987 template <
typename K,
typename...
Args>
1990 -> std::pair<iterator, bool> {
1995 return {internal_emplace(
position, std::forward<Args>(
args)...),
true};
2001 return {internal_emplace(
position, std::forward<Args>(
args)...),
true};
2008 return insert_unique(
key, std::forward<Args>(
args)...);
2011 template <
typename P>
2012 template <
typename InputIterator,
typename>
2014 for (;
b !=
e; ++
b) {
2019 template <
typename P>
2020 template <
typename InputIterator>
2022 for (;
b !=
e; ++
b) {
2028 template <
typename P>
2029 template <
typename ValueType>
2032 mutable_root() = rightmost_ = new_leaf_root_node(1);
2036 if (
iter.node ==
nullptr) {
2039 return internal_emplace(
iter, std::forward<ValueType>(
v));
2042 template <
typename P>
2043 template <
typename ValueType>
2051 return internal_emplace(
position, std::forward<ValueType>(
v));
2057 return internal_emplace(
position, std::forward<ValueType>(
v));
2061 return insert_multi(std::forward<ValueType>(
v));
2064 template <
typename P>
2065 template <
typename InputIterator>
2067 for (;
b !=
e; ++
b) {
2068 insert_hint_multi(
end(), *
b);
2072 template <
typename P>
2074 if (
this != &other) {
2077 *mutable_key_comp() = other.key_comp();
2080 *mutable_allocator() = other.allocator();
2083 copy_or_move_values_in_order(other);
2088 template <
typename P>
2090 if (
this != &other) {
2098 swap(rightmost_, other.rightmost_);
2101 if (allocator() == other.allocator()) {
2102 swap(mutable_root(), other.mutable_root());
2103 swap(*mutable_key_comp(), *other.mutable_key_comp());
2104 swap(rightmost_, other.rightmost_);
2112 *mutable_key_comp() = other.key_comp();
2113 copy_or_move_values_in_order(other);
2120 template <
typename P>
2122 bool internal_delete =
false;
2123 if (!
iter.node->leaf()) {
2130 assert(
iter.node->leaf());
2132 internal_iter.node->slot(internal_iter.position));
2133 internal_delete =
true;
2137 iter.node->remove_values(
iter.position, 1, mutable_allocator());
2150 if (internal_delete) {
2156 template <
typename P>
2160 bool first_iteration =
true;
2169 if (
iter.node->count() >= kMinNodeValues) {
2172 bool merged = try_merge_or_rebalance(&
iter);
2175 if (first_iteration) {
2177 first_iteration =
false;
2182 iter.position =
iter.node->position();
2188 if (res.position == res.node->finish()) {
2189 res.position = res.node->finish() - 1;
2196 template <
typename P>
2198 -> std::pair<size_type, iterator> {
2212 assert(
end.position >
begin.position);
2214 mutable_allocator());
2216 return {
count, rebalance_after_delete(
begin)};
2220 while (
size_ > target_size) {
2221 if (
begin.node->leaf()) {
2222 const size_type remaining_to_erase =
size_ - target_size;
2223 const size_type remaining_in_node =
begin.node->finish() -
begin.position;
2224 const size_type to_erase =
2225 (
std::min)(remaining_to_erase, remaining_in_node);
2226 begin.node->remove_values(
begin.position, to_erase, mutable_allocator());
2236 template <
typename P>
2239 node_type::clear_and_delete(
root(), mutable_allocator());
2241 mutable_root() = EmptyNode();
2242 rightmost_ = EmptyNode();
2246 template <
typename P>
2255 assert(allocator() == other.allocator());
2256 swap(mutable_root(), other.mutable_root());
2257 swap(*mutable_key_comp(), *other.mutable_key_comp());
2259 swap(rightmost_, other.rightmost_);
2263 template <
typename P>
2265 assert(
root() !=
nullptr);
2266 assert(leftmost() !=
nullptr);
2267 assert(rightmost_ !=
nullptr);
2269 assert(leftmost() == (++const_iterator(
root(), -1)).node);
2270 assert(rightmost_ == (--const_iterator(
root(),
root()->
finish())).node);
2271 assert(leftmost()->leaf());
2272 assert(rightmost_->leaf());
2275 template <
typename P>
2277 node_type *&node =
iter->node;
2278 int &insert_position =
iter->position;
2279 assert(node->count() == node->max_count());
2280 assert(kNodeSlots == node->max_count());
2283 node_type *parent = node->parent();
2284 if (node !=
root()) {
2285 if (node->position() > parent->start()) {
2287 node_type *left = parent->child(node->position() - 1);
2288 assert(left->max_count() == kNodeSlots);
2289 if (left->count() < kNodeSlots) {
2293 int to_move = (kNodeSlots - left->count()) /
2294 (1 + (insert_position <
static_cast<int>(kNodeSlots)));
2297 if (insert_position - to_move >= node->start() ||
2298 left->count() + to_move < static_cast<int>(kNodeSlots)) {
2299 left->rebalance_right_to_left(to_move, node, mutable_allocator());
2301 assert(node->max_count() - node->count() == to_move);
2302 insert_position = insert_position - to_move;
2303 if (insert_position < node->
start()) {
2304 insert_position = insert_position + left->count() + 1;
2308 assert(node->count() < node->max_count());
2314 if (node->position() < parent->finish()) {
2316 node_type *right = parent->child(node->position() + 1);
2317 assert(right->max_count() == kNodeSlots);
2318 if (right->count() < kNodeSlots) {
2322 int to_move = (
static_cast<int>(kNodeSlots) - right->count()) /
2323 (1 + (insert_position > node->start()));
2326 if (insert_position <= node->
finish() - to_move ||
2327 right->count() + to_move < static_cast<int>(kNodeSlots)) {
2328 node->rebalance_left_to_right(to_move, right, mutable_allocator());
2330 if (insert_position > node->finish()) {
2331 insert_position = insert_position - node->count() - 1;
2335 assert(node->count() < node->max_count());
2343 assert(parent->max_count() == kNodeSlots);
2344 if (parent->count() == kNodeSlots) {
2345 iterator parent_iter(node->parent(), node->position());
2346 rebalance_or_split(&parent_iter);
2352 parent = new_internal_node(parent);
2353 parent->init_child(parent->start(),
root());
2354 mutable_root() = parent;
2356 assert(!parent->start_child()->leaf() ||
2357 parent->start_child() == rightmost_);
2361 node_type *split_node;
2363 split_node = new_leaf_node(parent);
2364 node->split(insert_position, split_node, mutable_allocator());
2365 if (rightmost_ == node) rightmost_ = split_node;
2367 split_node = new_internal_node(parent);
2368 node->split(insert_position, split_node, mutable_allocator());
2371 if (insert_position > node->finish()) {
2372 insert_position = insert_position - node->count() - 1;
2377 template <
typename P>
2379 left->merge(right, mutable_allocator());
2380 if (rightmost_ == right) rightmost_ = left;
2383 template <
typename P>
2385 node_type *parent =
iter->node->parent();
2386 if (
iter->node->position() > parent->start()) {
2388 node_type *left = parent->child(
iter->node->position() - 1);
2389 assert(left->max_count() == kNodeSlots);
2390 if (1U + left->count() +
iter->node->count() <= kNodeSlots) {
2391 iter->position += 1 + left->count();
2392 merge_nodes(left,
iter->node);
2397 if (
iter->node->position() < parent->finish()) {
2399 node_type *right = parent->child(
iter->node->position() + 1);
2400 assert(right->max_count() == kNodeSlots);
2401 if (1U +
iter->node->count() + right->count() <= kNodeSlots) {
2402 merge_nodes(
iter->node, right);
2409 if (right->count() > kMinNodeValues &&
2410 (
iter->node->count() == 0 ||
iter->position >
iter->node->start())) {
2411 int to_move = (right->count() -
iter->node->count()) / 2;
2412 to_move = (
std::min)(to_move, right->count() - 1);
2413 iter->node->rebalance_right_to_left(to_move, right, mutable_allocator());
2417 if (
iter->node->position() > parent->start()) {
2422 node_type *left = parent->child(
iter->node->position() - 1);
2423 if (left->count() > kMinNodeValues &&
2424 (
iter->node->count() == 0 ||
iter->position <
iter->node->finish())) {
2425 int to_move = (left->count() -
iter->node->count()) / 2;
2426 to_move = (
std::min)(to_move, left->count() - 1);
2427 left->rebalance_left_to_right(to_move,
iter->node, mutable_allocator());
2428 iter->position += to_move;
2435 template <
typename P>
2437 node_type *orig_root =
root();
2438 if (orig_root->count() > 0) {
2442 if (orig_root->leaf()) {
2443 assert(
size() == 0);
2444 mutable_root() = rightmost_ = EmptyNode();
2446 node_type *
child = orig_root->start_child();
2448 mutable_root() =
child;
2450 node_type::clear_and_delete(orig_root, mutable_allocator());
2453 template <
typename P>
2454 template <
typename IterType>
2456 assert(
iter.node !=
nullptr);
2457 while (
iter.position ==
iter.node->finish()) {
2458 iter.position =
iter.node->position();
2460 if (
iter.node->leaf()) {
2461 iter.node =
nullptr;
2468 template <
typename P>
2469 template <
typename...
Args>
2472 if (!
iter.node->leaf()) {
2479 allocator_type *
alloc = mutable_allocator();
2480 if (
iter.node->count() == max_count) {
2482 if (max_count < kNodeSlots) {
2487 new_leaf_root_node((std::min<int>)(kNodeSlots, 2 * max_count));
2489 node_type *old_root =
root();
2490 node_type *new_root =
iter.node;
2491 new_root->transfer_n(old_root->count(), new_root->start(),
2492 old_root->start(), old_root,
alloc);
2493 new_root->set_finish(old_root->finish());
2494 old_root->set_finish(old_root->start());
2495 node_type::clear_and_delete(old_root,
alloc);
2496 mutable_root() = rightmost_ = new_root;
2498 rebalance_or_split(&
iter);
2506 template <
typename P>
2507 template <
typename K>
2509 -> SearchResult<iterator, is_key_compare_to::value> {
2512 SearchResult<int, is_key_compare_to::value> res =
2513 iter.node->lower_bound(
key, key_comp());
2514 iter.position = res.value;
2522 if (
iter.node->leaf()) {
2532 template <
typename P>
2533 template <
typename K>
2535 -> SearchResult<iterator, is_key_compare_to::value> {
2537 SearchResult<iterator, is_key_compare_to::value>
ret = internal_locate(
key);
2538 ret.value = internal_last(
ret.value);
2542 SearchResult<int, is_key_compare_to::value> res;
2543 bool seen_eq =
false;
2545 res =
iter.node->lower_bound(
key, key_comp());
2546 iter.position = res.value;
2547 if (
iter.node->leaf()) {
2550 seen_eq = seen_eq || res.IsEq();
2557 template <
typename P>
2558 template <
typename K>
2562 iter.position =
iter.node->upper_bound(
key, key_comp());
2563 if (
iter.node->leaf()) {
2568 return internal_last(
iter);
2571 template <
typename P>
2572 template <
typename K>
2574 SearchResult<iterator, is_key_compare_to::value> res = internal_locate(
key);
2575 if (res.HasMatch()) {
2581 if (
iter.node !=
nullptr && !compare_keys(
key,
iter.key())) {
2585 return {
nullptr, 0};
2588 template <
typename P>
2591 assert(node->count() > 0);
2592 assert(node->count() <= node->max_count());
2594 assert(!compare_keys(node->key(node->start()), *lo));
2597 assert(!compare_keys(*hi, node->key(node->finish() - 1)));
2599 for (
int i = node->start() + 1; i < node->
finish(); ++
i) {
2600 assert(!compare_keys(node->key(i), node->key(i - 1)));
2602 int count = node->count();
2603 if (!node->leaf()) {
2604 for (
int i = node->start(); i <= node->
finish(); ++
i) {
2605 assert(node->child(i) !=
nullptr);
2606 assert(node->child(i)->parent() == node);
2607 assert(node->child(i)->position() == i);
2609 i == node->start() ? lo : &node->key(i - 1),
2610 i == node->finish() ? hi : &node->key(i));
2620 #endif // ABSL_CONTAINER_INTERNAL_BTREE_H_