File indexing completed on 2025-01-18 09:27:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 #ifndef ABSL_CONTAINER_INTERNAL_BTREE_H_
0046 #define ABSL_CONTAINER_INTERNAL_BTREE_H_
0047
0048 #include <algorithm>
0049 #include <cassert>
0050 #include <cstddef>
0051 #include <cstdint>
0052 #include <cstring>
0053 #include <functional>
0054 #include <iterator>
0055 #include <limits>
0056 #include <string>
0057 #include <type_traits>
0058 #include <utility>
0059
0060 #include "absl/base/config.h"
0061 #include "absl/base/internal/raw_logging.h"
0062 #include "absl/base/macros.h"
0063 #include "absl/container/internal/common.h"
0064 #include "absl/container/internal/common_policy_traits.h"
0065 #include "absl/container/internal/compressed_tuple.h"
0066 #include "absl/container/internal/container_memory.h"
0067 #include "absl/container/internal/layout.h"
0068 #include "absl/memory/memory.h"
0069 #include "absl/meta/type_traits.h"
0070 #include "absl/strings/cord.h"
0071 #include "absl/strings/string_view.h"
0072 #include "absl/types/compare.h"
0073
0074 namespace absl {
0075 ABSL_NAMESPACE_BEGIN
0076 namespace container_internal {
0077
0078 #ifdef ABSL_BTREE_ENABLE_GENERATIONS
0079 #error ABSL_BTREE_ENABLE_GENERATIONS cannot be directly set
0080 #elif (defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
0081 defined(ABSL_HAVE_HWADDRESS_SANITIZER) || \
0082 defined(ABSL_HAVE_MEMORY_SANITIZER)) && \
0083 !defined(NDEBUG_SANITIZER)
0084
0085
0086
0087 #define ABSL_BTREE_ENABLE_GENERATIONS
0088 #endif
0089
0090 #ifdef ABSL_BTREE_ENABLE_GENERATIONS
0091 constexpr bool BtreeGenerationsEnabled() { return true; }
0092 #else
0093 constexpr bool BtreeGenerationsEnabled() { return false; }
0094 #endif
0095
0096 template <typename Compare, typename T, typename U>
0097 using compare_result_t = absl::result_of_t<const Compare(const T &, const U &)>;
0098
0099
0100
0101 template <typename Compare, typename T>
0102 using btree_is_key_compare_to =
0103 std::is_convertible<compare_result_t<Compare, T, T>, absl::weak_ordering>;
0104
0105 struct StringBtreeDefaultLess {
0106 using is_transparent = void;
0107
0108 StringBtreeDefaultLess() = default;
0109
0110
0111 StringBtreeDefaultLess(std::less<std::string>) {}
0112 StringBtreeDefaultLess(std::less<absl::string_view>) {}
0113
0114
0115 explicit operator std::less<std::string>() const { return {}; }
0116 explicit operator std::less<absl::string_view>() const { return {}; }
0117 explicit operator std::less<absl::Cord>() const { return {}; }
0118
0119 absl::weak_ordering operator()(absl::string_view lhs,
0120 absl::string_view rhs) const {
0121 return compare_internal::compare_result_as_ordering(lhs.compare(rhs));
0122 }
0123 StringBtreeDefaultLess(std::less<absl::Cord>) {}
0124 absl::weak_ordering operator()(const absl::Cord &lhs,
0125 const absl::Cord &rhs) const {
0126 return compare_internal::compare_result_as_ordering(lhs.Compare(rhs));
0127 }
0128 absl::weak_ordering operator()(const absl::Cord &lhs,
0129 absl::string_view rhs) const {
0130 return compare_internal::compare_result_as_ordering(lhs.Compare(rhs));
0131 }
0132 absl::weak_ordering operator()(absl::string_view lhs,
0133 const absl::Cord &rhs) const {
0134 return compare_internal::compare_result_as_ordering(-rhs.Compare(lhs));
0135 }
0136 };
0137
0138 struct StringBtreeDefaultGreater {
0139 using is_transparent = void;
0140
0141 StringBtreeDefaultGreater() = default;
0142
0143 StringBtreeDefaultGreater(std::greater<std::string>) {}
0144 StringBtreeDefaultGreater(std::greater<absl::string_view>) {}
0145
0146
0147 explicit operator std::greater<std::string>() const { return {}; }
0148 explicit operator std::greater<absl::string_view>() const { return {}; }
0149 explicit operator std::greater<absl::Cord>() const { return {}; }
0150
0151 absl::weak_ordering operator()(absl::string_view lhs,
0152 absl::string_view rhs) const {
0153 return compare_internal::compare_result_as_ordering(rhs.compare(lhs));
0154 }
0155 StringBtreeDefaultGreater(std::greater<absl::Cord>) {}
0156 absl::weak_ordering operator()(const absl::Cord &lhs,
0157 const absl::Cord &rhs) const {
0158 return compare_internal::compare_result_as_ordering(rhs.Compare(lhs));
0159 }
0160 absl::weak_ordering operator()(const absl::Cord &lhs,
0161 absl::string_view rhs) const {
0162 return compare_internal::compare_result_as_ordering(-lhs.Compare(rhs));
0163 }
0164 absl::weak_ordering operator()(absl::string_view lhs,
0165 const absl::Cord &rhs) const {
0166 return compare_internal::compare_result_as_ordering(rhs.Compare(lhs));
0167 }
0168 };
0169
0170
0171 template <typename Compare, bool is_class = std::is_class<Compare>::value>
0172 struct checked_compare_base : Compare {
0173 using Compare::Compare;
0174 explicit checked_compare_base(Compare c) : Compare(std::move(c)) {}
0175 const Compare &comp() const { return *this; }
0176 };
0177 template <typename Compare>
0178 struct checked_compare_base<Compare, false> {
0179 explicit checked_compare_base(Compare c) : compare(std::move(c)) {}
0180 const Compare &comp() const { return compare; }
0181 Compare compare;
0182 };
0183
0184
0185 struct BtreeTestOnlyCheckedCompareOptOutBase {};
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 template <typename Compare, typename Key>
0198 struct key_compare_adapter {
0199
0200
0201
0202
0203
0204
0205
0206 struct checked_compare : checked_compare_base<Compare> {
0207 private:
0208 using Base = typename checked_compare::checked_compare_base;
0209 using Base::comp;
0210
0211
0212
0213
0214
0215 bool is_self_equivalent(const Key &k) const {
0216
0217 return comp()(k, k) == 0;
0218 }
0219
0220 template <typename T>
0221 bool is_self_equivalent(const T &) const {
0222 return true;
0223 }
0224
0225 public:
0226 using Base::Base;
0227 checked_compare(Compare comp) : Base(std::move(comp)) {}
0228
0229
0230 explicit operator Compare() const { return comp(); }
0231
0232 template <typename T, typename U,
0233 absl::enable_if_t<
0234 std::is_same<bool, compare_result_t<Compare, T, U>>::value,
0235 int> = 0>
0236 bool operator()(const T &lhs, const U &rhs) const {
0237
0238
0239
0240 assert(is_self_equivalent(lhs));
0241 assert(is_self_equivalent(rhs));
0242 const bool lhs_comp_rhs = comp()(lhs, rhs);
0243 assert(!lhs_comp_rhs || !comp()(rhs, lhs));
0244 return lhs_comp_rhs;
0245 }
0246
0247 template <
0248 typename T, typename U,
0249 absl::enable_if_t<std::is_convertible<compare_result_t<Compare, T, U>,
0250 absl::weak_ordering>::value,
0251 int> = 0>
0252 absl::weak_ordering operator()(const T &lhs, const U &rhs) const {
0253
0254
0255
0256 assert(is_self_equivalent(lhs));
0257 assert(is_self_equivalent(rhs));
0258 const absl::weak_ordering lhs_comp_rhs = comp()(lhs, rhs);
0259 #ifndef NDEBUG
0260 const absl::weak_ordering rhs_comp_lhs = comp()(rhs, lhs);
0261 if (lhs_comp_rhs > 0) {
0262 assert(rhs_comp_lhs < 0 && "lhs_comp_rhs > 0 -> rhs_comp_lhs < 0");
0263 } else if (lhs_comp_rhs == 0) {
0264 assert(rhs_comp_lhs == 0 && "lhs_comp_rhs == 0 -> rhs_comp_lhs == 0");
0265 } else {
0266 assert(rhs_comp_lhs > 0 && "lhs_comp_rhs < 0 -> rhs_comp_lhs > 0");
0267 }
0268 #endif
0269 return lhs_comp_rhs;
0270 }
0271 };
0272 using type = absl::conditional_t<
0273 std::is_base_of<BtreeTestOnlyCheckedCompareOptOutBase, Compare>::value,
0274 Compare, checked_compare>;
0275 };
0276
0277 template <>
0278 struct key_compare_adapter<std::less<std::string>, std::string> {
0279 using type = StringBtreeDefaultLess;
0280 };
0281
0282 template <>
0283 struct key_compare_adapter<std::greater<std::string>, std::string> {
0284 using type = StringBtreeDefaultGreater;
0285 };
0286
0287 template <>
0288 struct key_compare_adapter<std::less<absl::string_view>, absl::string_view> {
0289 using type = StringBtreeDefaultLess;
0290 };
0291
0292 template <>
0293 struct key_compare_adapter<std::greater<absl::string_view>, absl::string_view> {
0294 using type = StringBtreeDefaultGreater;
0295 };
0296
0297 template <>
0298 struct key_compare_adapter<std::less<absl::Cord>, absl::Cord> {
0299 using type = StringBtreeDefaultLess;
0300 };
0301
0302 template <>
0303 struct key_compare_adapter<std::greater<absl::Cord>, absl::Cord> {
0304 using type = StringBtreeDefaultGreater;
0305 };
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326 template <typename T, typename = void>
0327 struct has_linear_node_search_preference : std::false_type {};
0328 template <typename T, typename = void>
0329 struct prefers_linear_node_search : std::false_type {};
0330 template <typename T>
0331 struct has_linear_node_search_preference<
0332 T, absl::void_t<typename T::absl_btree_prefer_linear_node_search>>
0333 : std::true_type {};
0334 template <typename T>
0335 struct prefers_linear_node_search<
0336 T, absl::void_t<typename T::absl_btree_prefer_linear_node_search>>
0337 : T::absl_btree_prefer_linear_node_search {};
0338
0339 template <typename Compare, typename Key>
0340 constexpr bool compare_has_valid_result_type() {
0341 using compare_result_type = compare_result_t<Compare, Key, Key>;
0342 return std::is_same<compare_result_type, bool>::value ||
0343 std::is_convertible<compare_result_type, absl::weak_ordering>::value;
0344 }
0345
0346 template <typename original_key_compare, typename value_type>
0347 class map_value_compare {
0348 template <typename Params>
0349 friend class btree;
0350
0351
0352
0353 protected:
0354 explicit map_value_compare(original_key_compare c) : comp(std::move(c)) {}
0355
0356 original_key_compare comp;
0357
0358 public:
0359 auto operator()(const value_type &lhs, const value_type &rhs) const
0360 -> decltype(comp(lhs.first, rhs.first)) {
0361 return comp(lhs.first, rhs.first);
0362 }
0363 };
0364
0365 template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
0366 bool IsMulti, bool IsMap, typename SlotPolicy>
0367 struct common_params : common_policy_traits<SlotPolicy> {
0368 using original_key_compare = Compare;
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378 using key_compare =
0379 absl::conditional_t<!compare_has_valid_result_type<Compare, Key>(),
0380 Compare,
0381 typename key_compare_adapter<Compare, Key>::type>;
0382
0383 static constexpr bool kIsKeyCompareStringAdapted =
0384 std::is_same<key_compare, StringBtreeDefaultLess>::value ||
0385 std::is_same<key_compare, StringBtreeDefaultGreater>::value;
0386 static constexpr bool kIsKeyCompareTransparent =
0387 IsTransparent<original_key_compare>::value || kIsKeyCompareStringAdapted;
0388
0389
0390
0391 using is_key_compare_to = btree_is_key_compare_to<key_compare, Key>;
0392
0393 using allocator_type = Alloc;
0394 using key_type = Key;
0395 using size_type = size_t;
0396 using difference_type = ptrdiff_t;
0397
0398 using slot_policy = SlotPolicy;
0399 using slot_type = typename slot_policy::slot_type;
0400 using value_type = typename slot_policy::value_type;
0401 using init_type = typename slot_policy::mutable_value_type;
0402 using pointer = value_type *;
0403 using const_pointer = const value_type *;
0404 using reference = value_type &;
0405 using const_reference = const value_type &;
0406
0407 using value_compare =
0408 absl::conditional_t<IsMap,
0409 map_value_compare<original_key_compare, value_type>,
0410 original_key_compare>;
0411 using is_map_container = std::integral_constant<bool, IsMap>;
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421 template <typename LookupKey>
0422 constexpr static bool can_have_multiple_equivalent_keys() {
0423 return IsMulti || (IsTransparent<key_compare>::value &&
0424 !std::is_same<LookupKey, Key>::value &&
0425 !kIsKeyCompareStringAdapted);
0426 }
0427
0428 enum {
0429 kTargetNodeSize = TargetNodeSize,
0430
0431
0432
0433
0434 kNodeSlotSpace = TargetNodeSize - (sizeof(void *) + 4),
0435 };
0436
0437
0438
0439 using node_count_type =
0440 absl::conditional_t<(kNodeSlotSpace / sizeof(slot_type) >
0441 (std::numeric_limits<uint8_t>::max)()),
0442 uint16_t, uint8_t>;
0443 };
0444
0445
0446
0447
0448
0449 template <typename Compare>
0450 struct upper_bound_adapter {
0451 explicit upper_bound_adapter(const Compare &c) : comp(c) {}
0452 template <typename K1, typename K2>
0453 bool operator()(const K1 &a, const K2 &b) const {
0454
0455 return !compare_internal::compare_result_as_less_than(comp(b, a));
0456 }
0457
0458 private:
0459 Compare comp;
0460 };
0461
0462 enum class MatchKind : uint8_t { kEq, kNe };
0463
0464 template <typename V, bool IsCompareTo>
0465 struct SearchResult {
0466 V value;
0467 MatchKind match;
0468
0469 static constexpr bool HasMatch() { return true; }
0470 bool IsEq() const { return match == MatchKind::kEq; }
0471 };
0472
0473
0474
0475
0476 template <typename V>
0477 struct SearchResult<V, false> {
0478 SearchResult() = default;
0479 explicit SearchResult(V v) : value(v) {}
0480 SearchResult(V v, MatchKind ) : value(v) {}
0481
0482 V value;
0483
0484 static constexpr bool HasMatch() { return false; }
0485 static constexpr bool IsEq() { return false; }
0486 };
0487
0488
0489
0490
0491 template <typename Params>
0492 class btree_node {
0493 using is_key_compare_to = typename Params::is_key_compare_to;
0494 using field_type = typename Params::node_count_type;
0495 using allocator_type = typename Params::allocator_type;
0496 using slot_type = typename Params::slot_type;
0497 using original_key_compare = typename Params::original_key_compare;
0498
0499 public:
0500 using params_type = Params;
0501 using key_type = typename Params::key_type;
0502 using value_type = typename Params::value_type;
0503 using pointer = typename Params::pointer;
0504 using const_pointer = typename Params::const_pointer;
0505 using reference = typename Params::reference;
0506 using const_reference = typename Params::const_reference;
0507 using key_compare = typename Params::key_compare;
0508 using size_type = typename Params::size_type;
0509 using difference_type = typename Params::difference_type;
0510
0511
0512
0513
0514
0515
0516
0517
0518 using use_linear_search = std::integral_constant<
0519 bool, has_linear_node_search_preference<original_key_compare>::value
0520 ? prefers_linear_node_search<original_key_compare>::value
0521 : has_linear_node_search_preference<key_type>::value
0522 ? prefers_linear_node_search<key_type>::value
0523 : std::is_arithmetic<key_type>::value &&
0524 (std::is_same<std::less<key_type>,
0525 original_key_compare>::value ||
0526 std::is_same<std::greater<key_type>,
0527 original_key_compare>::value)>;
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572 ~btree_node() = default;
0573 btree_node(btree_node const &) = delete;
0574 btree_node &operator=(btree_node const &) = delete;
0575
0576 protected:
0577 btree_node() = default;
0578
0579 private:
0580 using layout_type =
0581 absl::container_internal::Layout<btree_node *, uint32_t, field_type,
0582 slot_type, btree_node *>;
0583 using leaf_layout_type = typename layout_type::template WithStaticSizes<
0584 1,
0585 BtreeGenerationsEnabled() ? 1 : 0,
0586 4>;
0587 constexpr static size_type SizeWithNSlots(size_type n) {
0588 return leaf_layout_type( n, 0).AllocSize();
0589 }
0590
0591 constexpr static size_type MinimumOverhead() {
0592 return SizeWithNSlots(1) - sizeof(slot_type);
0593 }
0594
0595
0596
0597 constexpr static size_type NodeTargetSlots(const size_type begin,
0598 const size_type end) {
0599 return begin == end ? begin
0600 : SizeWithNSlots((begin + end) / 2 + 1) >
0601 params_type::kTargetNodeSize
0602 ? NodeTargetSlots(begin, (begin + end) / 2)
0603 : NodeTargetSlots((begin + end) / 2 + 1, end);
0604 }
0605
0606 constexpr static size_type kTargetNodeSize = params_type::kTargetNodeSize;
0607 constexpr static size_type kNodeTargetSlots =
0608 NodeTargetSlots(0, kTargetNodeSize);
0609
0610
0611
0612
0613
0614
0615 constexpr static size_type kMinNodeSlots = 4;
0616
0617 constexpr static size_type kNodeSlots =
0618 kNodeTargetSlots >= kMinNodeSlots ? kNodeTargetSlots : kMinNodeSlots;
0619
0620 using internal_layout_type = typename layout_type::template WithStaticSizes<
0621 1,
0622 BtreeGenerationsEnabled() ? 1 : 0,
0623 4, kNodeSlots,
0624 kNodeSlots + 1>;
0625
0626
0627
0628 constexpr static field_type kInternalNodeMaxCount = 0;
0629
0630
0631 constexpr static leaf_layout_type LeafLayout(
0632 const size_type slot_count = kNodeSlots) {
0633 return leaf_layout_type(slot_count, 0);
0634 }
0635 constexpr static auto InternalLayout() { return internal_layout_type(); }
0636 constexpr static size_type LeafSize(const size_type slot_count = kNodeSlots) {
0637 return LeafLayout(slot_count).AllocSize();
0638 }
0639 constexpr static size_type InternalSize() {
0640 return InternalLayout().AllocSize();
0641 }
0642
0643 constexpr static size_type Alignment() {
0644 static_assert(LeafLayout(1).Alignment() == InternalLayout().Alignment(),
0645 "Alignment of all nodes must be equal.");
0646 return InternalLayout().Alignment();
0647 }
0648
0649
0650
0651 template <size_type N>
0652 inline typename layout_type::template ElementType<N> *GetField() {
0653
0654 assert(N < 4 || is_internal());
0655 return InternalLayout().template Pointer<N>(reinterpret_cast<char *>(this));
0656 }
0657 template <size_type N>
0658 inline const typename layout_type::template ElementType<N> *GetField() const {
0659 assert(N < 4 || is_internal());
0660 return InternalLayout().template Pointer<N>(
0661 reinterpret_cast<const char *>(this));
0662 }
0663 void set_parent(btree_node *p) { *GetField<0>() = p; }
0664 field_type &mutable_finish() { return GetField<2>()[2]; }
0665 slot_type *slot(size_type i) { return &GetField<3>()[i]; }
0666 slot_type *start_slot() { return slot(start()); }
0667 slot_type *finish_slot() { return slot(finish()); }
0668 const slot_type *slot(size_type i) const { return &GetField<3>()[i]; }
0669 void set_position(field_type v) { GetField<2>()[0] = v; }
0670 void set_start(field_type v) { GetField<2>()[1] = v; }
0671 void set_finish(field_type v) { GetField<2>()[2] = v; }
0672
0673 void set_max_count(field_type v) { GetField<2>()[3] = v; }
0674
0675 public:
0676
0677
0678 bool is_leaf() const { return GetField<2>()[3] != kInternalNodeMaxCount; }
0679
0680
0681 bool is_internal() const { return !is_leaf(); }
0682
0683
0684 field_type position() const { return GetField<2>()[0]; }
0685
0686
0687 field_type start() const {
0688
0689 assert(GetField<2>()[1] == 0);
0690 return 0;
0691 }
0692
0693
0694 field_type finish() const { return GetField<2>()[2]; }
0695
0696
0697 field_type count() const {
0698 assert(finish() >= start());
0699 return finish() - start();
0700 }
0701 field_type max_count() const {
0702
0703
0704 const field_type max_count = GetField<2>()[3];
0705 return max_count == field_type{kInternalNodeMaxCount}
0706 ? field_type{kNodeSlots}
0707 : max_count;
0708 }
0709
0710
0711 btree_node *parent() const { return *GetField<0>(); }
0712
0713
0714
0715 bool is_root() const { return parent()->is_leaf(); }
0716 void make_root() {
0717 assert(parent()->is_root());
0718 set_generation(parent()->generation());
0719 set_parent(parent()->parent());
0720 }
0721
0722
0723 uint32_t *get_root_generation() const {
0724 assert(BtreeGenerationsEnabled());
0725 const btree_node *curr = this;
0726 for (; !curr->is_root(); curr = curr->parent()) continue;
0727 return const_cast<uint32_t *>(&curr->GetField<1>()[0]);
0728 }
0729
0730
0731 uint32_t generation() const {
0732 return BtreeGenerationsEnabled() ? *get_root_generation() : 0;
0733 }
0734
0735
0736 void set_generation(uint32_t generation) {
0737 if (BtreeGenerationsEnabled()) GetField<1>()[0] = generation;
0738 }
0739
0740 void next_generation() {
0741 if (BtreeGenerationsEnabled()) ++*get_root_generation();
0742 }
0743
0744
0745 const key_type &key(size_type i) const { return params_type::key(slot(i)); }
0746 reference value(size_type i) { return params_type::element(slot(i)); }
0747 const_reference value(size_type i) const {
0748 return params_type::element(slot(i));
0749 }
0750
0751
0752 btree_node *child(field_type i) const { return GetField<4>()[i]; }
0753 btree_node *start_child() const { return child(start()); }
0754 btree_node *&mutable_child(field_type i) { return GetField<4>()[i]; }
0755 void clear_child(field_type i) {
0756 absl::container_internal::SanitizerPoisonObject(&mutable_child(i));
0757 }
0758 void set_child_noupdate_position(field_type i, btree_node *c) {
0759 absl::container_internal::SanitizerUnpoisonObject(&mutable_child(i));
0760 mutable_child(i) = c;
0761 }
0762 void set_child(field_type i, btree_node *c) {
0763 set_child_noupdate_position(i, c);
0764 c->set_position(i);
0765 }
0766 void init_child(field_type i, btree_node *c) {
0767 set_child(i, c);
0768 c->set_parent(this);
0769 }
0770
0771
0772 template <typename K>
0773 SearchResult<size_type, is_key_compare_to::value> lower_bound(
0774 const K &k, const key_compare &comp) const {
0775 return use_linear_search::value ? linear_search(k, comp)
0776 : binary_search(k, comp);
0777 }
0778
0779 template <typename K>
0780 size_type upper_bound(const K &k, const key_compare &comp) const {
0781 auto upper_compare = upper_bound_adapter<key_compare>(comp);
0782 return use_linear_search::value ? linear_search(k, upper_compare).value
0783 : binary_search(k, upper_compare).value;
0784 }
0785
0786 template <typename K, typename Compare>
0787 SearchResult<size_type, btree_is_key_compare_to<Compare, key_type>::value>
0788 linear_search(const K &k, const Compare &comp) const {
0789 return linear_search_impl(k, start(), finish(), comp,
0790 btree_is_key_compare_to<Compare, key_type>());
0791 }
0792
0793 template <typename K, typename Compare>
0794 SearchResult<size_type, btree_is_key_compare_to<Compare, key_type>::value>
0795 binary_search(const K &k, const Compare &comp) const {
0796 return binary_search_impl(k, start(), finish(), comp,
0797 btree_is_key_compare_to<Compare, key_type>());
0798 }
0799
0800
0801
0802 template <typename K, typename Compare>
0803 SearchResult<size_type, false> linear_search_impl(
0804 const K &k, size_type s, const size_type e, const Compare &comp,
0805 std::false_type ) const {
0806 while (s < e) {
0807 if (!comp(key(s), k)) {
0808 break;
0809 }
0810 ++s;
0811 }
0812 return SearchResult<size_type, false>{s};
0813 }
0814
0815
0816
0817 template <typename K, typename Compare>
0818 SearchResult<size_type, true> linear_search_impl(
0819 const K &k, size_type s, const size_type e, const Compare &comp,
0820 std::true_type ) const {
0821 while (s < e) {
0822 const absl::weak_ordering c = comp(key(s), k);
0823 if (c == 0) {
0824 return {s, MatchKind::kEq};
0825 } else if (c > 0) {
0826 break;
0827 }
0828 ++s;
0829 }
0830 return {s, MatchKind::kNe};
0831 }
0832
0833
0834
0835 template <typename K, typename Compare>
0836 SearchResult<size_type, false> binary_search_impl(
0837 const K &k, size_type s, size_type e, const Compare &comp,
0838 std::false_type ) const {
0839 while (s != e) {
0840 const size_type mid = (s + e) >> 1;
0841 if (comp(key(mid), k)) {
0842 s = mid + 1;
0843 } else {
0844 e = mid;
0845 }
0846 }
0847 return SearchResult<size_type, false>{s};
0848 }
0849
0850
0851
0852 template <typename K, typename CompareTo>
0853 SearchResult<size_type, true> binary_search_impl(
0854 const K &k, size_type s, size_type e, const CompareTo &comp,
0855 std::true_type ) const {
0856 if (params_type::template can_have_multiple_equivalent_keys<K>()) {
0857 MatchKind exact_match = MatchKind::kNe;
0858 while (s != e) {
0859 const size_type mid = (s + e) >> 1;
0860 const absl::weak_ordering c = comp(key(mid), k);
0861 if (c < 0) {
0862 s = mid + 1;
0863 } else {
0864 e = mid;
0865 if (c == 0) {
0866
0867
0868
0869 exact_match = MatchKind::kEq;
0870 }
0871 }
0872 }
0873 return {s, exact_match};
0874 } else {
0875 while (s != e) {
0876 const size_type mid = (s + e) >> 1;
0877 const absl::weak_ordering c = comp(key(mid), k);
0878 if (c < 0) {
0879 s = mid + 1;
0880 } else if (c > 0) {
0881 e = mid;
0882 } else {
0883 return {mid, MatchKind::kEq};
0884 }
0885 }
0886 return {s, MatchKind::kNe};
0887 }
0888 }
0889
0890
0891
0892
0893
0894 template <typename Compare>
0895 bool is_ordered_correctly(field_type i, const Compare &comp) const {
0896 if (std::is_base_of<BtreeTestOnlyCheckedCompareOptOutBase,
0897 Compare>::value ||
0898 params_type::kIsKeyCompareStringAdapted) {
0899 return true;
0900 }
0901
0902 const auto compare = [&](field_type a, field_type b) {
0903 const absl::weak_ordering cmp =
0904 compare_internal::do_three_way_comparison(comp, key(a), key(b));
0905 return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
0906 };
0907 int cmp = -1;
0908 constexpr bool kCanHaveEquivKeys =
0909 params_type::template can_have_multiple_equivalent_keys<key_type>();
0910 for (field_type j = start(); j < finish(); ++j) {
0911 if (j == i) {
0912 if (cmp > 0) return false;
0913 continue;
0914 }
0915 int new_cmp = compare(j, i);
0916 if (new_cmp < cmp || (!kCanHaveEquivKeys && new_cmp == 0)) return false;
0917 cmp = new_cmp;
0918 }
0919 return true;
0920 }
0921
0922
0923
0924 template <typename... Args>
0925 void emplace_value(field_type i, allocator_type *alloc, Args &&...args);
0926
0927
0928
0929
0930 void remove_values(field_type i, field_type to_erase, allocator_type *alloc);
0931
0932
0933 void rebalance_right_to_left(field_type to_move, btree_node *right,
0934 allocator_type *alloc);
0935 void rebalance_left_to_right(field_type to_move, btree_node *right,
0936 allocator_type *alloc);
0937
0938
0939 void split(int insert_position, btree_node *dest, allocator_type *alloc);
0940
0941
0942
0943 void merge(btree_node *src, allocator_type *alloc);
0944
0945
0946 void init_leaf(field_type position, field_type max_count,
0947 btree_node *parent) {
0948 set_generation(0);
0949 set_parent(parent);
0950 set_position(position);
0951 set_start(0);
0952 set_finish(0);
0953 set_max_count(max_count);
0954 absl::container_internal::SanitizerPoisonMemoryRegion(
0955 start_slot(), max_count * sizeof(slot_type));
0956 }
0957 void init_internal(field_type position, btree_node *parent) {
0958 init_leaf(position, kNodeSlots, parent);
0959
0960
0961 set_max_count(kInternalNodeMaxCount);
0962 absl::container_internal::SanitizerPoisonMemoryRegion(
0963 &mutable_child(start()), (kNodeSlots + 1) * sizeof(btree_node *));
0964 }
0965
0966 static void deallocate(const size_type size, btree_node *node,
0967 allocator_type *alloc) {
0968 absl::container_internal::SanitizerUnpoisonMemoryRegion(node, size);
0969 absl::container_internal::Deallocate<Alignment()>(alloc, node, size);
0970 }
0971
0972
0973 static void clear_and_delete(btree_node *node, allocator_type *alloc);
0974
0975 private:
0976 template <typename... Args>
0977 void value_init(const field_type i, allocator_type *alloc, Args &&...args) {
0978 next_generation();
0979 absl::container_internal::SanitizerUnpoisonObject(slot(i));
0980 params_type::construct(alloc, slot(i), std::forward<Args>(args)...);
0981 }
0982 void value_destroy(const field_type i, allocator_type *alloc) {
0983 next_generation();
0984 params_type::destroy(alloc, slot(i));
0985 absl::container_internal::SanitizerPoisonObject(slot(i));
0986 }
0987 void value_destroy_n(const field_type i, const field_type n,
0988 allocator_type *alloc) {
0989 next_generation();
0990 for (slot_type *s = slot(i), *end = slot(i + n); s != end; ++s) {
0991 params_type::destroy(alloc, s);
0992 absl::container_internal::SanitizerPoisonObject(s);
0993 }
0994 }
0995
0996 static void transfer(slot_type *dest, slot_type *src, allocator_type *alloc) {
0997 absl::container_internal::SanitizerUnpoisonObject(dest);
0998 params_type::transfer(alloc, dest, src);
0999 absl::container_internal::SanitizerPoisonObject(src);
1000 }
1001
1002
1003 void transfer(const size_type dest_i, const size_type src_i,
1004 btree_node *src_node, allocator_type *alloc) {
1005 next_generation();
1006 transfer(slot(dest_i), src_node->slot(src_i), alloc);
1007 }
1008
1009
1010
1011 void transfer_n(const size_type n, const size_type dest_i,
1012 const size_type src_i, btree_node *src_node,
1013 allocator_type *alloc) {
1014 next_generation();
1015 for (slot_type *src = src_node->slot(src_i), *end = src + n,
1016 *dest = slot(dest_i);
1017 src != end; ++src, ++dest) {
1018 transfer(dest, src, alloc);
1019 }
1020 }
1021
1022
1023
1024 void transfer_n_backward(const size_type n, const size_type dest_i,
1025 const size_type src_i, btree_node *src_node,
1026 allocator_type *alloc) {
1027 next_generation();
1028 for (slot_type *src = src_node->slot(src_i + n), *end = src - n,
1029 *dest = slot(dest_i + n);
1030 src != end; --src, --dest) {
1031
1032
1033
1034
1035
1036 transfer(dest - 1, src - 1, alloc);
1037 }
1038 }
1039
1040 template <typename P>
1041 friend class btree;
1042 template <typename N, typename R, typename P>
1043 friend class btree_iterator;
1044 friend class BtreeNodePeer;
1045 friend struct btree_access;
1046 };
1047
1048 template <typename Node>
1049 bool AreNodesFromSameContainer(const Node *node_a, const Node *node_b) {
1050
1051
1052
1053 if (node_a == nullptr || node_b == nullptr) return true;
1054 while (!node_a->is_root()) node_a = node_a->parent();
1055 while (!node_b->is_root()) node_b = node_b->parent();
1056 return node_a == node_b;
1057 }
1058
1059 class btree_iterator_generation_info_enabled {
1060 public:
1061 explicit btree_iterator_generation_info_enabled(uint32_t g)
1062 : generation_(g) {}
1063
1064
1065
1066 template <typename Node>
1067 void update_generation(const Node *node) {
1068 if (node != nullptr) generation_ = node->generation();
1069 }
1070 uint32_t generation() const { return generation_; }
1071
1072 template <typename Node>
1073 void assert_valid_generation(const Node *node) const {
1074 if (node != nullptr && node->generation() != generation_) {
1075 ABSL_INTERNAL_LOG(
1076 FATAL,
1077 "Attempting to use an invalidated iterator. The corresponding b-tree "
1078 "container has been mutated since this iterator was constructed.");
1079 }
1080 }
1081
1082 private:
1083
1084 uint32_t generation_;
1085 };
1086
1087 class btree_iterator_generation_info_disabled {
1088 public:
1089 explicit btree_iterator_generation_info_disabled(uint32_t) {}
1090 static void update_generation(const void *) {}
1091 static uint32_t generation() { return 0; }
1092 static void assert_valid_generation(const void *) {}
1093 };
1094
1095 #ifdef ABSL_BTREE_ENABLE_GENERATIONS
1096 using btree_iterator_generation_info = btree_iterator_generation_info_enabled;
1097 #else
1098 using btree_iterator_generation_info = btree_iterator_generation_info_disabled;
1099 #endif
1100
1101 template <typename Node, typename Reference, typename Pointer>
1102 class btree_iterator : private btree_iterator_generation_info {
1103 using field_type = typename Node::field_type;
1104 using key_type = typename Node::key_type;
1105 using size_type = typename Node::size_type;
1106 using params_type = typename Node::params_type;
1107 using is_map_container = typename params_type::is_map_container;
1108
1109 using node_type = Node;
1110 using normal_node = typename std::remove_const<Node>::type;
1111 using const_node = const Node;
1112 using normal_pointer = typename params_type::pointer;
1113 using normal_reference = typename params_type::reference;
1114 using const_pointer = typename params_type::const_pointer;
1115 using const_reference = typename params_type::const_reference;
1116 using slot_type = typename params_type::slot_type;
1117
1118
1119 using iterator = absl::conditional_t<
1120 is_map_container::value,
1121 btree_iterator<normal_node, normal_reference, normal_pointer>,
1122 btree_iterator<normal_node, const_reference, const_pointer>>;
1123 using const_iterator =
1124 btree_iterator<const_node, const_reference, const_pointer>;
1125
1126 public:
1127
1128 using difference_type = typename Node::difference_type;
1129 using value_type = typename params_type::value_type;
1130 using pointer = Pointer;
1131 using reference = Reference;
1132 using iterator_category = std::bidirectional_iterator_tag;
1133
1134 btree_iterator() : btree_iterator(nullptr, -1) {}
1135 explicit btree_iterator(Node *n) : btree_iterator(n, n->start()) {}
1136 btree_iterator(Node *n, int p)
1137 : btree_iterator_generation_info(n != nullptr ? n->generation()
1138 : ~uint32_t{}),
1139 node_(n),
1140 position_(p) {}
1141
1142
1143
1144
1145 template <typename N, typename R, typename P,
1146 absl::enable_if_t<
1147 std::is_same<btree_iterator<N, R, P>, iterator>::value &&
1148 std::is_same<btree_iterator, const_iterator>::value,
1149 int> = 0>
1150 btree_iterator(const btree_iterator<N, R, P> other)
1151 : btree_iterator_generation_info(other),
1152 node_(other.node_),
1153 position_(other.position_) {}
1154
1155 bool operator==(const iterator &other) const {
1156 return Equals(other);
1157 }
1158 bool operator==(const const_iterator &other) const {
1159 return Equals(other);
1160 }
1161 bool operator!=(const iterator &other) const {
1162 return !Equals(other);
1163 }
1164 bool operator!=(const const_iterator &other) const {
1165 return !Equals(other);
1166 }
1167
1168
1169
1170 difference_type operator-(const_iterator other) const {
1171 if (node_ == other.node_) {
1172 if (node_->is_leaf()) return position_ - other.position_;
1173 if (position_ == other.position_) return 0;
1174 }
1175 return distance_slow(other);
1176 }
1177
1178
1179 reference operator*() const {
1180 ABSL_HARDENING_ASSERT(node_ != nullptr);
1181 assert_valid_generation(node_);
1182 ABSL_HARDENING_ASSERT(position_ >= node_->start());
1183 if (position_ >= node_->finish()) {
1184 ABSL_HARDENING_ASSERT(!IsEndIterator() && "Dereferencing end() iterator");
1185 ABSL_HARDENING_ASSERT(position_ < node_->finish());
1186 }
1187 return node_->value(static_cast<field_type>(position_));
1188 }
1189 pointer operator->() const { return &operator*(); }
1190
1191 btree_iterator &operator++() {
1192 increment();
1193 return *this;
1194 }
1195 btree_iterator &operator--() {
1196 decrement();
1197 return *this;
1198 }
1199 btree_iterator operator++(int) {
1200 btree_iterator tmp = *this;
1201 ++*this;
1202 return tmp;
1203 }
1204 btree_iterator operator--(int) {
1205 btree_iterator tmp = *this;
1206 --*this;
1207 return tmp;
1208 }
1209
1210 private:
1211 friend iterator;
1212 friend const_iterator;
1213 template <typename Params>
1214 friend class btree;
1215 template <typename Tree>
1216 friend class btree_container;
1217 template <typename Tree>
1218 friend class btree_set_container;
1219 template <typename Tree>
1220 friend class btree_map_container;
1221 template <typename Tree>
1222 friend class btree_multiset_container;
1223 template <typename TreeType, typename CheckerType>
1224 friend class base_checker;
1225 friend struct btree_access;
1226
1227
1228
1229
1230
1231 template <typename N, typename R, typename P,
1232 absl::enable_if_t<
1233 std::is_same<btree_iterator<N, R, P>, const_iterator>::value &&
1234 std::is_same<btree_iterator, iterator>::value,
1235 int> = 0>
1236 explicit btree_iterator(const btree_iterator<N, R, P> other)
1237 : btree_iterator_generation_info(other.generation()),
1238 node_(const_cast<node_type *>(other.node_)),
1239 position_(other.position_) {}
1240
1241 bool Equals(const const_iterator other) const {
1242 ABSL_HARDENING_ASSERT(((node_ == nullptr && other.node_ == nullptr) ||
1243 (node_ != nullptr && other.node_ != nullptr)) &&
1244 "Comparing default-constructed iterator with "
1245 "non-default-constructed iterator.");
1246
1247
1248
1249 assert(AreNodesFromSameContainer(node_, other.node_) &&
1250 "Comparing iterators from different containers.");
1251 assert_valid_generation(node_);
1252 other.assert_valid_generation(other.node_);
1253 return node_ == other.node_ && position_ == other.position_;
1254 }
1255
1256 bool IsEndIterator() const {
1257 if (position_ != node_->finish()) return false;
1258 node_type *node = node_;
1259 while (!node->is_root()) {
1260 if (node->position() != node->parent()->finish()) return false;
1261 node = node->parent();
1262 }
1263 return true;
1264 }
1265
1266
1267
1268
1269 difference_type distance_slow(const_iterator other) const;
1270
1271
1272 void increment() {
1273 assert_valid_generation(node_);
1274 if (node_->is_leaf() && ++position_ < node_->finish()) {
1275 return;
1276 }
1277 increment_slow();
1278 }
1279 void increment_slow();
1280
1281 void decrement() {
1282 assert_valid_generation(node_);
1283 if (node_->is_leaf() && --position_ >= node_->start()) {
1284 return;
1285 }
1286 decrement_slow();
1287 }
1288 void decrement_slow();
1289
1290 const key_type &key() const {
1291 return node_->key(static_cast<size_type>(position_));
1292 }
1293 decltype(std::declval<Node *>()->slot(0)) slot() {
1294 return node_->slot(static_cast<size_type>(position_));
1295 }
1296
1297 void update_generation() {
1298 btree_iterator_generation_info::update_generation(node_);
1299 }
1300
1301
1302 Node *node_;
1303
1304
1305
1306 int position_;
1307 };
1308
1309 template <typename Params>
1310 class btree {
1311 using node_type = btree_node<Params>;
1312 using is_key_compare_to = typename Params::is_key_compare_to;
1313 using field_type = typename node_type::field_type;
1314
1315
1316
1317 struct EmptyNodeType : node_type {
1318 using field_type = typename node_type::field_type;
1319 node_type *parent;
1320 #ifdef ABSL_BTREE_ENABLE_GENERATIONS
1321 uint32_t generation = 0;
1322 #endif
1323 field_type position = 0;
1324 field_type start = 0;
1325 field_type finish = 0;
1326
1327
1328 field_type max_count = node_type::kInternalNodeMaxCount + 1;
1329
1330 constexpr EmptyNodeType() : parent(this) {}
1331 };
1332
1333 static node_type *EmptyNode() {
1334 alignas(node_type::Alignment()) static constexpr EmptyNodeType empty_node;
1335 return const_cast<EmptyNodeType *>(&empty_node);
1336 }
1337
1338 enum : uint32_t {
1339 kNodeSlots = node_type::kNodeSlots,
1340 kMinNodeValues = kNodeSlots / 2,
1341 };
1342
1343 struct node_stats {
1344 using size_type = typename Params::size_type;
1345
1346 node_stats(size_type l, size_type i) : leaf_nodes(l), internal_nodes(i) {}
1347
1348 node_stats &operator+=(const node_stats &other) {
1349 leaf_nodes += other.leaf_nodes;
1350 internal_nodes += other.internal_nodes;
1351 return *this;
1352 }
1353
1354 size_type leaf_nodes;
1355 size_type internal_nodes;
1356 };
1357
1358 public:
1359 using key_type = typename Params::key_type;
1360 using value_type = typename Params::value_type;
1361 using size_type = typename Params::size_type;
1362 using difference_type = typename Params::difference_type;
1363 using key_compare = typename Params::key_compare;
1364 using original_key_compare = typename Params::original_key_compare;
1365 using value_compare = typename Params::value_compare;
1366 using allocator_type = typename Params::allocator_type;
1367 using reference = typename Params::reference;
1368 using const_reference = typename Params::const_reference;
1369 using pointer = typename Params::pointer;
1370 using const_pointer = typename Params::const_pointer;
1371 using iterator =
1372 typename btree_iterator<node_type, reference, pointer>::iterator;
1373 using const_iterator = typename iterator::const_iterator;
1374 using reverse_iterator = std::reverse_iterator<iterator>;
1375 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1376 using node_handle_type = node_handle<Params, Params, allocator_type>;
1377
1378
1379 using params_type = Params;
1380 using slot_type = typename Params::slot_type;
1381
1382 private:
1383
1384
1385
1386
1387 template <typename Btree>
1388 void copy_or_move_values_in_order(Btree &other);
1389
1390
1391 constexpr static bool static_assert_validation();
1392
1393 public:
1394 btree(const key_compare &comp, const allocator_type &alloc)
1395 : root_(EmptyNode()), rightmost_(comp, alloc, EmptyNode()), size_(0) {}
1396
1397 btree(const btree &other) : btree(other, other.allocator()) {}
1398 btree(const btree &other, const allocator_type &alloc)
1399 : btree(other.key_comp(), alloc) {
1400 copy_or_move_values_in_order(other);
1401 }
1402 btree(btree &&other) noexcept
1403 : root_(std::exchange(other.root_, EmptyNode())),
1404 rightmost_(std::move(other.rightmost_)),
1405 size_(std::exchange(other.size_, 0u)) {
1406 other.mutable_rightmost() = EmptyNode();
1407 }
1408 btree(btree &&other, const allocator_type &alloc)
1409 : btree(other.key_comp(), alloc) {
1410 if (alloc == other.allocator()) {
1411 swap(other);
1412 } else {
1413
1414 copy_or_move_values_in_order(other);
1415 }
1416 }
1417
1418 ~btree() {
1419
1420
1421 static_assert(static_assert_validation(), "This call must be elided.");
1422 clear();
1423 }
1424
1425
1426 btree &operator=(const btree &other);
1427 btree &operator=(btree &&other) noexcept;
1428
1429 iterator begin() { return iterator(leftmost()); }
1430 const_iterator begin() const { return const_iterator(leftmost()); }
1431 iterator end() { return iterator(rightmost(), rightmost()->finish()); }
1432 const_iterator end() const {
1433 return const_iterator(rightmost(), rightmost()->finish());
1434 }
1435 reverse_iterator rbegin() { return reverse_iterator(end()); }
1436 const_reverse_iterator rbegin() const {
1437 return const_reverse_iterator(end());
1438 }
1439 reverse_iterator rend() { return reverse_iterator(begin()); }
1440 const_reverse_iterator rend() const {
1441 return const_reverse_iterator(begin());
1442 }
1443
1444
1445 template <typename K>
1446 iterator lower_bound(const K &key) {
1447 return internal_end(internal_lower_bound(key).value);
1448 }
1449 template <typename K>
1450 const_iterator lower_bound(const K &key) const {
1451 return internal_end(internal_lower_bound(key).value);
1452 }
1453
1454
1455
1456 template <typename K>
1457 std::pair<iterator, bool> lower_bound_equal(const K &key) const;
1458
1459
1460 template <typename K>
1461 iterator upper_bound(const K &key) {
1462 return internal_end(internal_upper_bound(key));
1463 }
1464 template <typename K>
1465 const_iterator upper_bound(const K &key) const {
1466 return internal_end(internal_upper_bound(key));
1467 }
1468
1469
1470
1471
1472 template <typename K>
1473 std::pair<iterator, iterator> equal_range(const K &key);
1474 template <typename K>
1475 std::pair<const_iterator, const_iterator> equal_range(const K &key) const {
1476 return const_cast<btree *>(this)->equal_range(key);
1477 }
1478
1479
1480
1481
1482
1483 template <typename K, typename... Args>
1484 std::pair<iterator, bool> insert_unique(const K &key, Args &&...args);
1485
1486
1487
1488
1489
1490
1491
1492 template <typename K, typename... Args>
1493 std::pair<iterator, bool> insert_hint_unique(iterator position, const K &key,
1494 Args &&...args);
1495
1496
1497
1498
1499 template <typename InputIterator,
1500 typename = decltype(std::declval<const key_compare &>()(
1501 params_type::key(*std::declval<InputIterator>()),
1502 std::declval<const key_type &>()))>
1503 void insert_iterator_unique(InputIterator b, InputIterator e, int);
1504
1505
1506 template <typename InputIterator>
1507 void insert_iterator_unique(InputIterator b, InputIterator e, char);
1508
1509
1510 template <typename ValueType>
1511 iterator insert_multi(const key_type &key, ValueType &&v);
1512
1513
1514 template <typename ValueType>
1515 iterator insert_multi(ValueType &&v) {
1516 return insert_multi(params_type::key(v), std::forward<ValueType>(v));
1517 }
1518
1519
1520
1521
1522
1523 template <typename ValueType>
1524 iterator insert_hint_multi(iterator position, ValueType &&v);
1525
1526
1527 template <typename InputIterator>
1528 void insert_iterator_multi(InputIterator b,
1529 InputIterator e);
1530
1531
1532
1533
1534
1535 iterator erase(iterator iter);
1536
1537
1538
1539 std::pair<size_type, iterator> erase_range(iterator begin, iterator end);
1540
1541
1542
1543 template <typename K>
1544 iterator find(const K &key) {
1545 return internal_end(internal_find(key));
1546 }
1547 template <typename K>
1548 const_iterator find(const K &key) const {
1549 return internal_end(internal_find(key));
1550 }
1551
1552
1553 void clear();
1554
1555
1556 void swap(btree &other);
1557
1558 const key_compare &key_comp() const noexcept {
1559 return rightmost_.template get<0>();
1560 }
1561 template <typename K1, typename K2>
1562 bool compare_keys(const K1 &a, const K2 &b) const {
1563 return compare_internal::compare_result_as_less_than(key_comp()(a, b));
1564 }
1565
1566 value_compare value_comp() const {
1567 return value_compare(original_key_compare(key_comp()));
1568 }
1569
1570
1571 void verify() const;
1572
1573
1574 size_type size() const { return size_; }
1575 size_type max_size() const { return (std::numeric_limits<size_type>::max)(); }
1576 bool empty() const { return size_ == 0; }
1577
1578
1579 size_type height() const {
1580 size_type h = 0;
1581 if (!empty()) {
1582
1583
1584
1585
1586 const node_type *n = root();
1587 do {
1588 ++h;
1589 n = n->parent();
1590 } while (n != root());
1591 }
1592 return h;
1593 }
1594
1595
1596 size_type leaf_nodes() const { return internal_stats(root()).leaf_nodes; }
1597 size_type internal_nodes() const {
1598 return internal_stats(root()).internal_nodes;
1599 }
1600 size_type nodes() const {
1601 node_stats stats = internal_stats(root());
1602 return stats.leaf_nodes + stats.internal_nodes;
1603 }
1604
1605
1606
1607 size_type bytes_used() const {
1608 node_stats stats = internal_stats(root());
1609 if (stats.leaf_nodes == 1 && stats.internal_nodes == 0) {
1610 return sizeof(*this) + node_type::LeafSize(root()->max_count());
1611 } else {
1612 return sizeof(*this) + stats.leaf_nodes * node_type::LeafSize() +
1613 stats.internal_nodes * node_type::InternalSize();
1614 }
1615 }
1616
1617
1618
1619 static double average_bytes_per_value() {
1620
1621
1622 const double expected_values_per_node = (kNodeSlots + kMinNodeValues) / 2.0;
1623 return node_type::LeafSize() / expected_values_per_node;
1624 }
1625
1626
1627
1628
1629
1630
1631 double fullness() const {
1632 if (empty()) return 0.0;
1633 return static_cast<double>(size()) / (nodes() * kNodeSlots);
1634 }
1635
1636
1637
1638
1639 double overhead() const {
1640 if (empty()) return 0.0;
1641 return (bytes_used() - size() * sizeof(value_type)) /
1642 static_cast<double>(size());
1643 }
1644
1645
1646 allocator_type get_allocator() const { return allocator(); }
1647
1648 private:
1649 friend struct btree_access;
1650
1651
1652 node_type *root() { return root_; }
1653 const node_type *root() const { return root_; }
1654 node_type *&mutable_root() noexcept { return root_; }
1655 node_type *rightmost() { return rightmost_.template get<2>(); }
1656 const node_type *rightmost() const { return rightmost_.template get<2>(); }
1657 node_type *&mutable_rightmost() noexcept {
1658 return rightmost_.template get<2>();
1659 }
1660 key_compare *mutable_key_comp() noexcept {
1661 return &rightmost_.template get<0>();
1662 }
1663
1664
1665 node_type *leftmost() { return root()->parent(); }
1666 const node_type *leftmost() const { return root()->parent(); }
1667
1668
1669 allocator_type *mutable_allocator() noexcept {
1670 return &rightmost_.template get<1>();
1671 }
1672 const allocator_type &allocator() const noexcept {
1673 return rightmost_.template get<1>();
1674 }
1675
1676
1677
1678 node_type *allocate(size_type size) {
1679 return reinterpret_cast<node_type *>(
1680 absl::container_internal::Allocate<node_type::Alignment()>(
1681 mutable_allocator(), size));
1682 }
1683
1684
1685 node_type *new_internal_node(field_type position, node_type *parent) {
1686 node_type *n = allocate(node_type::InternalSize());
1687 n->init_internal(position, parent);
1688 return n;
1689 }
1690 node_type *new_leaf_node(field_type position, node_type *parent) {
1691 node_type *n = allocate(node_type::LeafSize());
1692 n->init_leaf(position, kNodeSlots, parent);
1693 return n;
1694 }
1695 node_type *new_leaf_root_node(field_type max_count) {
1696 node_type *n = allocate(node_type::LeafSize(max_count));
1697 n->init_leaf(0, max_count, n);
1698 return n;
1699 }
1700
1701
1702 iterator rebalance_after_delete(iterator iter);
1703
1704
1705 void rebalance_or_split(iterator *iter);
1706
1707
1708
1709 void merge_nodes(node_type *left, node_type *right);
1710
1711
1712
1713
1714
1715 bool try_merge_or_rebalance(iterator *iter);
1716
1717
1718 void try_shrink();
1719
1720 iterator internal_end(iterator iter) {
1721 return iter.node_ != nullptr ? iter : end();
1722 }
1723 const_iterator internal_end(const_iterator iter) const {
1724 return iter.node_ != nullptr ? iter : end();
1725 }
1726
1727
1728
1729 template <typename... Args>
1730 iterator internal_emplace(iterator iter, Args &&...args);
1731
1732
1733
1734
1735
1736 template <typename IterType>
1737 static IterType internal_last(IterType iter);
1738
1739
1740
1741
1742
1743
1744
1745 template <typename K>
1746 SearchResult<iterator, is_key_compare_to::value> internal_locate(
1747 const K &key) const;
1748
1749
1750 template <typename K>
1751 SearchResult<iterator, is_key_compare_to::value> internal_lower_bound(
1752 const K &key) const;
1753
1754
1755 template <typename K>
1756 iterator internal_upper_bound(const K &key) const;
1757
1758
1759 template <typename K>
1760 iterator internal_find(const K &key) const;
1761
1762
1763 size_type internal_verify(const node_type *node, const key_type *lo,
1764 const key_type *hi) const;
1765
1766 node_stats internal_stats(const node_type *node) const {
1767
1768 if (node == nullptr || (node == root() && empty())) {
1769 return node_stats(0, 0);
1770 }
1771 if (node->is_leaf()) {
1772 return node_stats(1, 0);
1773 }
1774 node_stats res(0, 1);
1775 for (int i = node->start(); i <= node->finish(); ++i) {
1776 res += internal_stats(node->child(i));
1777 }
1778 return res;
1779 }
1780
1781 node_type *root_;
1782
1783
1784
1785
1786 absl::container_internal::CompressedTuple<key_compare, allocator_type,
1787 node_type *>
1788 rightmost_;
1789
1790
1791 size_type size_;
1792 };
1793
1794
1795
1796 template <typename P>
1797 template <typename... Args>
1798 inline void btree_node<P>::emplace_value(const field_type i,
1799 allocator_type *alloc,
1800 Args &&...args) {
1801 assert(i >= start());
1802 assert(i <= finish());
1803
1804
1805 if (i < finish()) {
1806 transfer_n_backward(finish() - i, i + 1, i, this,
1807 alloc);
1808 }
1809 value_init(static_cast<field_type>(i), alloc, std::forward<Args>(args)...);
1810 set_finish(finish() + 1);
1811
1812 if (is_internal() && finish() > i + 1) {
1813 for (field_type j = finish(); j > i + 1; --j) {
1814 set_child(j, child(j - 1));
1815 }
1816 clear_child(i + 1);
1817 }
1818 }
1819
1820 template <typename P>
1821 inline void btree_node<P>::remove_values(const field_type i,
1822 const field_type to_erase,
1823 allocator_type *alloc) {
1824
1825 value_destroy_n(i, to_erase, alloc);
1826 const field_type orig_finish = finish();
1827 const field_type src_i = i + to_erase;
1828 transfer_n(orig_finish - src_i, i, src_i, this, alloc);
1829
1830 if (is_internal()) {
1831
1832 for (field_type j = 0; j < to_erase; ++j) {
1833 clear_and_delete(child(i + j + 1), alloc);
1834 }
1835
1836 for (field_type j = i + to_erase + 1; j <= orig_finish; ++j) {
1837 set_child(j - to_erase, child(j));
1838 clear_child(j);
1839 }
1840 }
1841 set_finish(orig_finish - to_erase);
1842 }
1843
1844 template <typename P>
1845 void btree_node<P>::rebalance_right_to_left(field_type to_move,
1846 btree_node *right,
1847 allocator_type *alloc) {
1848 assert(parent() == right->parent());
1849 assert(position() + 1 == right->position());
1850 assert(right->count() >= count());
1851 assert(to_move >= 1);
1852 assert(to_move <= right->count());
1853
1854
1855 transfer(finish(), position(), parent(), alloc);
1856
1857
1858 transfer_n(to_move - 1, finish() + 1, right->start(), right, alloc);
1859
1860
1861 parent()->transfer(position(), right->start() + to_move - 1, right, alloc);
1862
1863
1864 right->transfer_n(right->count() - to_move, right->start(),
1865 right->start() + to_move, right, alloc);
1866
1867 if (is_internal()) {
1868
1869 for (field_type i = 0; i < to_move; ++i) {
1870 init_child(finish() + i + 1, right->child(i));
1871 }
1872 for (field_type i = right->start(); i <= right->finish() - to_move; ++i) {
1873 assert(i + to_move <= right->max_count());
1874 right->init_child(i, right->child(i + to_move));
1875 right->clear_child(i + to_move);
1876 }
1877 }
1878
1879
1880 set_finish(finish() + to_move);
1881 right->set_finish(right->finish() - to_move);
1882 }
1883
1884 template <typename P>
1885 void btree_node<P>::rebalance_left_to_right(field_type to_move,
1886 btree_node *right,
1887 allocator_type *alloc) {
1888 assert(parent() == right->parent());
1889 assert(position() + 1 == right->position());
1890 assert(count() >= right->count());
1891 assert(to_move >= 1);
1892 assert(to_move <= count());
1893
1894
1895
1896
1897
1898
1899
1900
1901 right->transfer_n_backward(right->count(), right->start() + to_move,
1902 right->start(), right, alloc);
1903
1904
1905 right->transfer(right->start() + to_move - 1, position(), parent(), alloc);
1906
1907
1908 right->transfer_n(to_move - 1, right->start(), finish() - (to_move - 1), this,
1909 alloc);
1910
1911
1912 parent()->transfer(position(), finish() - to_move, this, alloc);
1913
1914 if (is_internal()) {
1915
1916 for (field_type i = right->finish() + 1; i > right->start(); --i) {
1917 right->init_child(i - 1 + to_move, right->child(i - 1));
1918 right->clear_child(i - 1);
1919 }
1920 for (field_type i = 1; i <= to_move; ++i) {
1921 right->init_child(i - 1, child(finish() - to_move + i));
1922 clear_child(finish() - to_move + i);
1923 }
1924 }
1925
1926
1927 set_finish(finish() - to_move);
1928 right->set_finish(right->finish() + to_move);
1929 }
1930
1931 template <typename P>
1932 void btree_node<P>::split(const int insert_position, btree_node *dest,
1933 allocator_type *alloc) {
1934 assert(dest->count() == 0);
1935 assert(max_count() == kNodeSlots);
1936 assert(position() + 1 == dest->position());
1937 assert(parent() == dest->parent());
1938
1939
1940
1941
1942
1943 if (insert_position == start()) {
1944 dest->set_finish(dest->start() + finish() - 1);
1945 } else if (insert_position == kNodeSlots) {
1946 dest->set_finish(dest->start());
1947 } else {
1948 dest->set_finish(dest->start() + count() / 2);
1949 }
1950 set_finish(finish() - dest->count());
1951 assert(count() >= 1);
1952
1953
1954 dest->transfer_n(dest->count(), dest->start(), finish(), this, alloc);
1955
1956
1957 --mutable_finish();
1958 parent()->emplace_value(position(), alloc, finish_slot());
1959 value_destroy(finish(), alloc);
1960 parent()->set_child_noupdate_position(position() + 1, dest);
1961
1962 if (is_internal()) {
1963 for (field_type i = dest->start(), j = finish() + 1; i <= dest->finish();
1964 ++i, ++j) {
1965 assert(child(j) != nullptr);
1966 dest->init_child(i, child(j));
1967 clear_child(j);
1968 }
1969 }
1970 }
1971
1972 template <typename P>
1973 void btree_node<P>::merge(btree_node *src, allocator_type *alloc) {
1974 assert(parent() == src->parent());
1975 assert(position() + 1 == src->position());
1976
1977
1978 value_init(finish(), alloc, parent()->slot(position()));
1979
1980
1981 transfer_n(src->count(), finish() + 1, src->start(), src, alloc);
1982
1983 if (is_internal()) {
1984
1985 for (field_type i = src->start(), j = finish() + 1; i <= src->finish();
1986 ++i, ++j) {
1987 init_child(j, src->child(i));
1988 src->clear_child(i);
1989 }
1990 }
1991
1992
1993 set_finish(start() + 1 + count() + src->count());
1994 src->set_finish(src->start());
1995
1996
1997 parent()->remove_values(position(), 1, alloc);
1998 }
1999
2000 template <typename P>
2001 void btree_node<P>::clear_and_delete(btree_node *node, allocator_type *alloc) {
2002 if (node->is_leaf()) {
2003 node->value_destroy_n(node->start(), node->count(), alloc);
2004 deallocate(LeafSize(node->max_count()), node, alloc);
2005 return;
2006 }
2007 if (node->count() == 0) {
2008 deallocate(InternalSize(), node, alloc);
2009 return;
2010 }
2011
2012
2013 btree_node *delete_root_parent = node->parent();
2014
2015
2016 while (node->is_internal()) node = node->start_child();
2017 #ifdef ABSL_BTREE_ENABLE_GENERATIONS
2018
2019
2020
2021
2022
2023 btree_node *leftmost_leaf = node;
2024 #endif
2025
2026
2027 size_type pos = node->position();
2028 btree_node *parent = node->parent();
2029 for (;;) {
2030
2031 assert(pos <= parent->finish());
2032 do {
2033 node = parent->child(static_cast<field_type>(pos));
2034 if (node->is_internal()) {
2035
2036 while (node->is_internal()) node = node->start_child();
2037 pos = node->position();
2038 parent = node->parent();
2039 }
2040 node->value_destroy_n(node->start(), node->count(), alloc);
2041 #ifdef ABSL_BTREE_ENABLE_GENERATIONS
2042 if (leftmost_leaf != node)
2043 #endif
2044 deallocate(LeafSize(node->max_count()), node, alloc);
2045 ++pos;
2046 } while (pos <= parent->finish());
2047
2048
2049 assert(pos > parent->finish());
2050 do {
2051 node = parent;
2052 pos = node->position();
2053 parent = node->parent();
2054 node->value_destroy_n(node->start(), node->count(), alloc);
2055 deallocate(InternalSize(), node, alloc);
2056 if (parent == delete_root_parent) {
2057 #ifdef ABSL_BTREE_ENABLE_GENERATIONS
2058 deallocate(LeafSize(leftmost_leaf->max_count()), leftmost_leaf, alloc);
2059 #endif
2060 return;
2061 }
2062 ++pos;
2063 } while (pos > parent->finish());
2064 }
2065 }
2066
2067
2068
2069
2070
2071 template <typename N, typename R, typename P>
2072 auto btree_iterator<N, R, P>::distance_slow(const_iterator other) const
2073 -> difference_type {
2074 const_iterator begin = other;
2075 const_iterator end = *this;
2076 assert(begin.node_ != end.node_ || !begin.node_->is_leaf() ||
2077 begin.position_ != end.position_);
2078
2079 const node_type *node = begin.node_;
2080
2081 difference_type count = node->is_leaf() ? -begin.position_ : 0;
2082
2083
2084 if (node->is_internal()) {
2085 ++count;
2086 node = node->child(begin.position_ + 1);
2087 }
2088 while (node->is_internal()) node = node->start_child();
2089
2090
2091
2092 size_type pos = node->position();
2093 const node_type *parent = node->parent();
2094 for (;;) {
2095
2096 assert(pos <= parent->finish());
2097 do {
2098 node = parent->child(static_cast<field_type>(pos));
2099 if (node->is_internal()) {
2100
2101 while (node->is_internal()) node = node->start_child();
2102 pos = node->position();
2103 parent = node->parent();
2104 }
2105 if (node == end.node_) return count + end.position_;
2106 if (parent == end.node_ && pos == static_cast<size_type>(end.position_))
2107 return count + node->count();
2108
2109 count += node->count() + 1;
2110 ++pos;
2111 } while (pos <= parent->finish());
2112
2113
2114 assert(pos > parent->finish());
2115 do {
2116 node = parent;
2117 pos = node->position();
2118 parent = node->parent();
2119
2120 if (parent == end.node_ && pos == static_cast<size_type>(end.position_))
2121 return count - 1;
2122 ++pos;
2123 } while (pos > parent->finish());
2124 }
2125 }
2126
2127 template <typename N, typename R, typename P>
2128 void btree_iterator<N, R, P>::increment_slow() {
2129 if (node_->is_leaf()) {
2130 assert(position_ >= node_->finish());
2131 btree_iterator save(*this);
2132 while (position_ == node_->finish() && !node_->is_root()) {
2133 assert(node_->parent()->child(node_->position()) == node_);
2134 position_ = node_->position();
2135 node_ = node_->parent();
2136 }
2137
2138 if (position_ == node_->finish()) {
2139 *this = save;
2140 }
2141 } else {
2142 assert(position_ < node_->finish());
2143 node_ = node_->child(static_cast<field_type>(position_ + 1));
2144 while (node_->is_internal()) {
2145 node_ = node_->start_child();
2146 }
2147 position_ = node_->start();
2148 }
2149 }
2150
2151 template <typename N, typename R, typename P>
2152 void btree_iterator<N, R, P>::decrement_slow() {
2153 if (node_->is_leaf()) {
2154 assert(position_ <= -1);
2155 btree_iterator save(*this);
2156 while (position_ < node_->start() && !node_->is_root()) {
2157 assert(node_->parent()->child(node_->position()) == node_);
2158 position_ = node_->position() - 1;
2159 node_ = node_->parent();
2160 }
2161
2162 if (position_ < node_->start()) {
2163 *this = save;
2164 }
2165 } else {
2166 assert(position_ >= node_->start());
2167 node_ = node_->child(static_cast<field_type>(position_));
2168 while (node_->is_internal()) {
2169 node_ = node_->child(node_->finish());
2170 }
2171 position_ = node_->finish() - 1;
2172 }
2173 }
2174
2175
2176
2177 template <typename P>
2178 template <typename Btree>
2179 void btree<P>::copy_or_move_values_in_order(Btree &other) {
2180 static_assert(std::is_same<btree, Btree>::value ||
2181 std::is_same<const btree, Btree>::value,
2182 "Btree type must be same or const.");
2183 assert(empty());
2184
2185
2186
2187 auto iter = other.begin();
2188 if (iter == other.end()) return;
2189 insert_multi(iter.slot());
2190 ++iter;
2191 for (; iter != other.end(); ++iter) {
2192
2193
2194 internal_emplace(end(), iter.slot());
2195 }
2196 }
2197
2198 template <typename P>
2199 constexpr bool btree<P>::static_assert_validation() {
2200 static_assert(std::is_nothrow_copy_constructible<key_compare>::value,
2201 "Key comparison must be nothrow copy constructible");
2202 static_assert(std::is_nothrow_copy_constructible<allocator_type>::value,
2203 "Allocator must be nothrow copy constructible");
2204 static_assert(std::is_trivially_copyable<iterator>::value,
2205 "iterator not trivially copyable.");
2206
2207
2208
2209 static_assert(
2210 kNodeSlots < (1 << (8 * sizeof(typename node_type::field_type))),
2211 "target node size too large");
2212
2213
2214 static_assert(
2215 compare_has_valid_result_type<key_compare, key_type>(),
2216 "key comparison function must return absl::{weak,strong}_ordering or "
2217 "bool.");
2218
2219
2220 static_assert(node_type::MinimumOverhead() >= sizeof(void *) + 4,
2221 "node space assumption incorrect");
2222
2223 return true;
2224 }
2225
2226 template <typename P>
2227 template <typename K>
2228 auto btree<P>::lower_bound_equal(const K &key) const
2229 -> std::pair<iterator, bool> {
2230 const SearchResult<iterator, is_key_compare_to::value> res =
2231 internal_lower_bound(key);
2232 const iterator lower = iterator(internal_end(res.value));
2233 const bool equal = res.HasMatch()
2234 ? res.IsEq()
2235 : lower != end() && !compare_keys(key, lower.key());
2236 return {lower, equal};
2237 }
2238
2239 template <typename P>
2240 template <typename K>
2241 auto btree<P>::equal_range(const K &key) -> std::pair<iterator, iterator> {
2242 const std::pair<iterator, bool> lower_and_equal = lower_bound_equal(key);
2243 const iterator lower = lower_and_equal.first;
2244 if (!lower_and_equal.second) {
2245 return {lower, lower};
2246 }
2247
2248 const iterator next = std::next(lower);
2249 if (!params_type::template can_have_multiple_equivalent_keys<K>()) {
2250
2251
2252
2253
2254 assert(next == end() || compare_keys(key, next.key()));
2255 return {lower, next};
2256 }
2257
2258
2259
2260
2261 if (next == end() || compare_keys(key, next.key())) return {lower, next};
2262
2263
2264
2265 return {lower, upper_bound(key)};
2266 }
2267
2268 template <typename P>
2269 template <typename K, typename... Args>
2270 auto btree<P>::insert_unique(const K &key, Args &&...args)
2271 -> std::pair<iterator, bool> {
2272 if (empty()) {
2273 mutable_root() = mutable_rightmost() = new_leaf_root_node(1);
2274 }
2275
2276 SearchResult<iterator, is_key_compare_to::value> res = internal_locate(key);
2277 iterator iter = res.value;
2278
2279 if (res.HasMatch()) {
2280 if (res.IsEq()) {
2281
2282 return {iter, false};
2283 }
2284 } else {
2285 iterator last = internal_last(iter);
2286 if (last.node_ && !compare_keys(key, last.key())) {
2287
2288 return {last, false};
2289 }
2290 }
2291 return {internal_emplace(iter, std::forward<Args>(args)...), true};
2292 }
2293
2294 template <typename P>
2295 template <typename K, typename... Args>
2296 inline auto btree<P>::insert_hint_unique(iterator position, const K &key,
2297 Args &&...args)
2298 -> std::pair<iterator, bool> {
2299 if (!empty()) {
2300 if (position == end() || compare_keys(key, position.key())) {
2301 if (position == begin() || compare_keys(std::prev(position).key(), key)) {
2302
2303 return {internal_emplace(position, std::forward<Args>(args)...), true};
2304 }
2305 } else if (compare_keys(position.key(), key)) {
2306 ++position;
2307 if (position == end() || compare_keys(key, position.key())) {
2308
2309 return {internal_emplace(position, std::forward<Args>(args)...), true};
2310 }
2311 } else {
2312
2313 return {position, false};
2314 }
2315 }
2316 return insert_unique(key, std::forward<Args>(args)...);
2317 }
2318
2319 template <typename P>
2320 template <typename InputIterator, typename>
2321 void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, int) {
2322 for (; b != e; ++b) {
2323 insert_hint_unique(end(), params_type::key(*b), *b);
2324 }
2325 }
2326
2327 template <typename P>
2328 template <typename InputIterator>
2329 void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, char) {
2330 for (; b != e; ++b) {
2331
2332 auto node_handle =
2333 CommonAccess::Construct<node_handle_type>(get_allocator(), *b);
2334 slot_type *slot = CommonAccess::GetSlot(node_handle);
2335 insert_hint_unique(end(), params_type::key(slot), slot);
2336 }
2337 }
2338
2339 template <typename P>
2340 template <typename ValueType>
2341 auto btree<P>::insert_multi(const key_type &key, ValueType &&v) -> iterator {
2342 if (empty()) {
2343 mutable_root() = mutable_rightmost() = new_leaf_root_node(1);
2344 }
2345
2346 iterator iter = internal_upper_bound(key);
2347 if (iter.node_ == nullptr) {
2348 iter = end();
2349 }
2350 return internal_emplace(iter, std::forward<ValueType>(v));
2351 }
2352
2353 template <typename P>
2354 template <typename ValueType>
2355 auto btree<P>::insert_hint_multi(iterator position, ValueType &&v) -> iterator {
2356 if (!empty()) {
2357 const key_type &key = params_type::key(v);
2358 if (position == end() || !compare_keys(position.key(), key)) {
2359 if (position == begin() ||
2360 !compare_keys(key, std::prev(position).key())) {
2361
2362 return internal_emplace(position, std::forward<ValueType>(v));
2363 }
2364 } else {
2365 ++position;
2366 if (position == end() || !compare_keys(position.key(), key)) {
2367
2368 return internal_emplace(position, std::forward<ValueType>(v));
2369 }
2370 }
2371 }
2372 return insert_multi(std::forward<ValueType>(v));
2373 }
2374
2375 template <typename P>
2376 template <typename InputIterator>
2377 void btree<P>::insert_iterator_multi(InputIterator b, InputIterator e) {
2378 for (; b != e; ++b) {
2379 insert_hint_multi(end(), *b);
2380 }
2381 }
2382
2383 template <typename P>
2384 auto btree<P>::operator=(const btree &other) -> btree & {
2385 if (this != &other) {
2386 clear();
2387
2388 *mutable_key_comp() = other.key_comp();
2389 if (absl::allocator_traits<
2390 allocator_type>::propagate_on_container_copy_assignment::value) {
2391 *mutable_allocator() = other.allocator();
2392 }
2393
2394 copy_or_move_values_in_order(other);
2395 }
2396 return *this;
2397 }
2398
2399 template <typename P>
2400 auto btree<P>::operator=(btree &&other) noexcept -> btree & {
2401 if (this != &other) {
2402 clear();
2403
2404 using std::swap;
2405 if (absl::allocator_traits<
2406 allocator_type>::propagate_on_container_move_assignment::value) {
2407 swap(root_, other.root_);
2408
2409 swap(rightmost_, other.rightmost_);
2410 swap(size_, other.size_);
2411 } else {
2412 if (allocator() == other.allocator()) {
2413 swap(mutable_root(), other.mutable_root());
2414 swap(*mutable_key_comp(), *other.mutable_key_comp());
2415 swap(mutable_rightmost(), other.mutable_rightmost());
2416 swap(size_, other.size_);
2417 } else {
2418
2419
2420
2421
2422
2423 *mutable_key_comp() = other.key_comp();
2424 copy_or_move_values_in_order(other);
2425 }
2426 }
2427 }
2428 return *this;
2429 }
2430
2431 template <typename P>
2432 auto btree<P>::erase(iterator iter) -> iterator {
2433 iter.node_->value_destroy(static_cast<field_type>(iter.position_),
2434 mutable_allocator());
2435 iter.update_generation();
2436
2437 const bool internal_delete = iter.node_->is_internal();
2438 if (internal_delete) {
2439
2440
2441
2442 iterator internal_iter(iter);
2443 --iter;
2444 assert(iter.node_->is_leaf());
2445 internal_iter.node_->transfer(
2446 static_cast<size_type>(internal_iter.position_),
2447 static_cast<size_type>(iter.position_), iter.node_,
2448 mutable_allocator());
2449 } else {
2450
2451
2452 const field_type transfer_from =
2453 static_cast<field_type>(iter.position_ + 1);
2454 const field_type num_to_transfer = iter.node_->finish() - transfer_from;
2455 iter.node_->transfer_n(num_to_transfer,
2456 static_cast<size_type>(iter.position_),
2457 transfer_from, iter.node_, mutable_allocator());
2458 }
2459
2460 iter.node_->set_finish(iter.node_->finish() - 1);
2461 --size_;
2462
2463
2464
2465
2466
2467
2468
2469
2470 iterator res = rebalance_after_delete(iter);
2471
2472
2473 if (internal_delete) {
2474 ++res;
2475 }
2476 return res;
2477 }
2478
2479 template <typename P>
2480 auto btree<P>::rebalance_after_delete(iterator iter) -> iterator {
2481
2482 iterator res(iter);
2483 bool first_iteration = true;
2484 for (;;) {
2485 if (iter.node_ == root()) {
2486 try_shrink();
2487 if (empty()) {
2488 return end();
2489 }
2490 break;
2491 }
2492 if (iter.node_->count() >= kMinNodeValues) {
2493 break;
2494 }
2495 bool merged = try_merge_or_rebalance(&iter);
2496
2497
2498 if (first_iteration) {
2499 res = iter;
2500 first_iteration = false;
2501 }
2502 if (!merged) {
2503 break;
2504 }
2505 iter.position_ = iter.node_->position();
2506 iter.node_ = iter.node_->parent();
2507 }
2508 res.update_generation();
2509
2510
2511
2512 if (res.position_ == res.node_->finish()) {
2513 res.position_ = res.node_->finish() - 1;
2514 ++res;
2515 }
2516
2517 return res;
2518 }
2519
2520
2521
2522
2523
2524 template <typename P>
2525 auto btree<P>::erase_range(iterator begin, iterator end)
2526 -> std::pair<size_type, iterator> {
2527 size_type count = static_cast<size_type>(end - begin);
2528 assert(count >= 0);
2529
2530 if (count == 0) {
2531 return {0, begin};
2532 }
2533
2534 if (static_cast<size_type>(count) == size_) {
2535 clear();
2536 return {count, this->end()};
2537 }
2538
2539 if (begin.node_ == end.node_) {
2540 assert(end.position_ > begin.position_);
2541 begin.node_->remove_values(
2542 static_cast<field_type>(begin.position_),
2543 static_cast<field_type>(end.position_ - begin.position_),
2544 mutable_allocator());
2545 size_ -= count;
2546 return {count, rebalance_after_delete(begin)};
2547 }
2548
2549 const size_type target_size = size_ - count;
2550 while (size_ > target_size) {
2551 if (begin.node_->is_leaf()) {
2552 const size_type remaining_to_erase = size_ - target_size;
2553 const size_type remaining_in_node =
2554 static_cast<size_type>(begin.node_->finish() - begin.position_);
2555 const field_type to_erase = static_cast<field_type>(
2556 (std::min)(remaining_to_erase, remaining_in_node));
2557 begin.node_->remove_values(static_cast<field_type>(begin.position_),
2558 to_erase, mutable_allocator());
2559 size_ -= to_erase;
2560 begin = rebalance_after_delete(begin);
2561 } else {
2562 begin = erase(begin);
2563 }
2564 }
2565 begin.update_generation();
2566 return {count, begin};
2567 }
2568
2569 template <typename P>
2570 void btree<P>::clear() {
2571 if (!empty()) {
2572 node_type::clear_and_delete(root(), mutable_allocator());
2573 }
2574 mutable_root() = mutable_rightmost() = EmptyNode();
2575 size_ = 0;
2576 }
2577
2578 template <typename P>
2579 void btree<P>::swap(btree &other) {
2580 using std::swap;
2581 if (absl::allocator_traits<
2582 allocator_type>::propagate_on_container_swap::value) {
2583
2584 swap(rightmost_, other.rightmost_);
2585 } else {
2586
2587 assert(allocator() == other.allocator());
2588 swap(mutable_rightmost(), other.mutable_rightmost());
2589 swap(*mutable_key_comp(), *other.mutable_key_comp());
2590 }
2591 swap(mutable_root(), other.mutable_root());
2592 swap(size_, other.size_);
2593 }
2594
2595 template <typename P>
2596 void btree<P>::verify() const {
2597 assert(root() != nullptr);
2598 assert(leftmost() != nullptr);
2599 assert(rightmost() != nullptr);
2600 assert(empty() || size() == internal_verify(root(), nullptr, nullptr));
2601 assert(leftmost() == (++const_iterator(root(), -1)).node_);
2602 assert(rightmost() == (--const_iterator(root(), root()->finish())).node_);
2603 assert(leftmost()->is_leaf());
2604 assert(rightmost()->is_leaf());
2605 }
2606
2607 template <typename P>
2608 void btree<P>::rebalance_or_split(iterator *iter) {
2609 node_type *&node = iter->node_;
2610 int &insert_position = iter->position_;
2611 assert(node->count() == node->max_count());
2612 assert(kNodeSlots == node->max_count());
2613
2614
2615 node_type *parent = node->parent();
2616 if (node != root()) {
2617 if (node->position() > parent->start()) {
2618
2619 node_type *left = parent->child(node->position() - 1);
2620 assert(left->max_count() == kNodeSlots);
2621 if (left->count() < kNodeSlots) {
2622
2623
2624
2625 field_type to_move =
2626 (kNodeSlots - left->count()) /
2627 (1 + (static_cast<field_type>(insert_position) < kNodeSlots));
2628 to_move = (std::max)(field_type{1}, to_move);
2629
2630 if (static_cast<field_type>(insert_position) - to_move >=
2631 node->start() ||
2632 left->count() + to_move < kNodeSlots) {
2633 left->rebalance_right_to_left(to_move, node, mutable_allocator());
2634
2635 assert(node->max_count() - node->count() == to_move);
2636 insert_position = static_cast<int>(
2637 static_cast<field_type>(insert_position) - to_move);
2638 if (insert_position < node->start()) {
2639 insert_position = insert_position + left->count() + 1;
2640 node = left;
2641 }
2642
2643 assert(node->count() < node->max_count());
2644 return;
2645 }
2646 }
2647 }
2648
2649 if (node->position() < parent->finish()) {
2650
2651 node_type *right = parent->child(node->position() + 1);
2652 assert(right->max_count() == kNodeSlots);
2653 if (right->count() < kNodeSlots) {
2654
2655
2656
2657 field_type to_move = (kNodeSlots - right->count()) /
2658 (1 + (insert_position > node->start()));
2659 to_move = (std::max)(field_type{1}, to_move);
2660
2661 if (static_cast<field_type>(insert_position) <=
2662 node->finish() - to_move ||
2663 right->count() + to_move < kNodeSlots) {
2664 node->rebalance_left_to_right(to_move, right, mutable_allocator());
2665
2666 if (insert_position > node->finish()) {
2667 insert_position = insert_position - node->count() - 1;
2668 node = right;
2669 }
2670
2671 assert(node->count() < node->max_count());
2672 return;
2673 }
2674 }
2675 }
2676
2677
2678
2679 assert(parent->max_count() == kNodeSlots);
2680 if (parent->count() == kNodeSlots) {
2681 iterator parent_iter(parent, node->position());
2682 rebalance_or_split(&parent_iter);
2683 parent = node->parent();
2684 }
2685 } else {
2686
2687
2688
2689 parent = new_internal_node(0, parent);
2690 parent->set_generation(root()->generation());
2691 parent->init_child(parent->start(), node);
2692 mutable_root() = parent;
2693
2694 assert(parent->start_child()->is_internal() ||
2695 parent->start_child() == rightmost());
2696 }
2697
2698
2699 node_type *split_node;
2700 if (node->is_leaf()) {
2701 split_node = new_leaf_node(node->position() + 1, parent);
2702 node->split(insert_position, split_node, mutable_allocator());
2703 if (rightmost() == node) mutable_rightmost() = split_node;
2704 } else {
2705 split_node = new_internal_node(node->position() + 1, parent);
2706 node->split(insert_position, split_node, mutable_allocator());
2707 }
2708
2709 if (insert_position > node->finish()) {
2710 insert_position = insert_position - node->count() - 1;
2711 node = split_node;
2712 }
2713 }
2714
2715 template <typename P>
2716 void btree<P>::merge_nodes(node_type *left, node_type *right) {
2717 left->merge(right, mutable_allocator());
2718 if (rightmost() == right) mutable_rightmost() = left;
2719 }
2720
2721 template <typename P>
2722 bool btree<P>::try_merge_or_rebalance(iterator *iter) {
2723 node_type *parent = iter->node_->parent();
2724 if (iter->node_->position() > parent->start()) {
2725
2726 node_type *left = parent->child(iter->node_->position() - 1);
2727 assert(left->max_count() == kNodeSlots);
2728 if (1U + left->count() + iter->node_->count() <= kNodeSlots) {
2729 iter->position_ += 1 + left->count();
2730 merge_nodes(left, iter->node_);
2731 iter->node_ = left;
2732 return true;
2733 }
2734 }
2735 if (iter->node_->position() < parent->finish()) {
2736
2737 node_type *right = parent->child(iter->node_->position() + 1);
2738 assert(right->max_count() == kNodeSlots);
2739 if (1U + iter->node_->count() + right->count() <= kNodeSlots) {
2740 merge_nodes(iter->node_, right);
2741 return true;
2742 }
2743
2744
2745
2746
2747 if (right->count() > kMinNodeValues &&
2748 (iter->node_->count() == 0 || iter->position_ > iter->node_->start())) {
2749 field_type to_move = (right->count() - iter->node_->count()) / 2;
2750 to_move =
2751 (std::min)(to_move, static_cast<field_type>(right->count() - 1));
2752 iter->node_->rebalance_right_to_left(to_move, right, mutable_allocator());
2753 return false;
2754 }
2755 }
2756 if (iter->node_->position() > parent->start()) {
2757
2758
2759
2760
2761 node_type *left = parent->child(iter->node_->position() - 1);
2762 if (left->count() > kMinNodeValues &&
2763 (iter->node_->count() == 0 ||
2764 iter->position_ < iter->node_->finish())) {
2765 field_type to_move = (left->count() - iter->node_->count()) / 2;
2766 to_move = (std::min)(to_move, static_cast<field_type>(left->count() - 1));
2767 left->rebalance_left_to_right(to_move, iter->node_, mutable_allocator());
2768 iter->position_ += to_move;
2769 return false;
2770 }
2771 }
2772 return false;
2773 }
2774
2775 template <typename P>
2776 void btree<P>::try_shrink() {
2777 node_type *orig_root = root();
2778 if (orig_root->count() > 0) {
2779 return;
2780 }
2781
2782 if (orig_root->is_leaf()) {
2783 assert(size() == 0);
2784 mutable_root() = mutable_rightmost() = EmptyNode();
2785 } else {
2786 node_type *child = orig_root->start_child();
2787 child->make_root();
2788 mutable_root() = child;
2789 }
2790 node_type::clear_and_delete(orig_root, mutable_allocator());
2791 }
2792
2793 template <typename P>
2794 template <typename IterType>
2795 inline IterType btree<P>::internal_last(IterType iter) {
2796 assert(iter.node_ != nullptr);
2797 while (iter.position_ == iter.node_->finish()) {
2798 iter.position_ = iter.node_->position();
2799 iter.node_ = iter.node_->parent();
2800 if (iter.node_->is_leaf()) {
2801 iter.node_ = nullptr;
2802 break;
2803 }
2804 }
2805 iter.update_generation();
2806 return iter;
2807 }
2808
2809 template <typename P>
2810 template <typename... Args>
2811 inline auto btree<P>::internal_emplace(iterator iter, Args &&...args)
2812 -> iterator {
2813 if (iter.node_->is_internal()) {
2814
2815
2816 --iter;
2817 ++iter.position_;
2818 }
2819 const field_type max_count = iter.node_->max_count();
2820 allocator_type *alloc = mutable_allocator();
2821
2822 const auto transfer_and_delete = [&](node_type *old_node,
2823 node_type *new_node) {
2824 new_node->transfer_n(old_node->count(), new_node->start(),
2825 old_node->start(), old_node, alloc);
2826 new_node->set_finish(old_node->finish());
2827 old_node->set_finish(old_node->start());
2828 new_node->set_generation(old_node->generation());
2829 node_type::clear_and_delete(old_node, alloc);
2830 };
2831 const auto replace_leaf_root_node = [&](field_type new_node_size) {
2832 assert(iter.node_ == root());
2833 node_type *old_root = iter.node_;
2834 node_type *new_root = iter.node_ = new_leaf_root_node(new_node_size);
2835 transfer_and_delete(old_root, new_root);
2836 mutable_root() = mutable_rightmost() = new_root;
2837 };
2838
2839 bool replaced_node = false;
2840 if (iter.node_->count() == max_count) {
2841
2842 if (max_count < kNodeSlots) {
2843
2844
2845 replace_leaf_root_node(static_cast<field_type>(
2846 (std::min)(static_cast<int>(kNodeSlots), 2 * max_count)));
2847 replaced_node = true;
2848 } else {
2849 rebalance_or_split(&iter);
2850 }
2851 }
2852 (void)replaced_node;
2853 #if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
2854 defined(ABSL_HAVE_HWADDRESS_SANITIZER)
2855 if (!replaced_node) {
2856 assert(iter.node_->is_leaf());
2857 if (iter.node_->is_root()) {
2858 replace_leaf_root_node(max_count);
2859 } else {
2860 node_type *old_node = iter.node_;
2861 const bool was_rightmost = rightmost() == old_node;
2862 const bool was_leftmost = leftmost() == old_node;
2863 node_type *parent = old_node->parent();
2864 const field_type position = old_node->position();
2865 node_type *new_node = iter.node_ = new_leaf_node(position, parent);
2866 parent->set_child_noupdate_position(position, new_node);
2867 transfer_and_delete(old_node, new_node);
2868 if (was_rightmost) mutable_rightmost() = new_node;
2869
2870 if (was_leftmost) root()->set_parent(new_node);
2871 }
2872 }
2873 #endif
2874 iter.node_->emplace_value(static_cast<field_type>(iter.position_), alloc,
2875 std::forward<Args>(args)...);
2876 assert(
2877 iter.node_->is_ordered_correctly(static_cast<field_type>(iter.position_),
2878 original_key_compare(key_comp())) &&
2879 "If this assert fails, then either (1) the comparator may violate "
2880 "transitivity, i.e. comp(a,b) && comp(b,c) -> comp(a,c) (see "
2881 "https://en.cppreference.com/w/cpp/named_req/Compare), or (2) a "
2882 "key may have been mutated after it was inserted into the tree.");
2883 ++size_;
2884 iter.update_generation();
2885 return iter;
2886 }
2887
2888 template <typename P>
2889 template <typename K>
2890 inline auto btree<P>::internal_locate(const K &key) const
2891 -> SearchResult<iterator, is_key_compare_to::value> {
2892 iterator iter(const_cast<node_type *>(root()));
2893 for (;;) {
2894 SearchResult<size_type, is_key_compare_to::value> res =
2895 iter.node_->lower_bound(key, key_comp());
2896 iter.position_ = static_cast<int>(res.value);
2897 if (res.IsEq()) {
2898 return {iter, MatchKind::kEq};
2899 }
2900
2901
2902
2903
2904 if (iter.node_->is_leaf()) {
2905 break;
2906 }
2907 iter.node_ = iter.node_->child(static_cast<field_type>(iter.position_));
2908 }
2909
2910
2911 return {iter, MatchKind::kNe};
2912 }
2913
2914 template <typename P>
2915 template <typename K>
2916 auto btree<P>::internal_lower_bound(const K &key) const
2917 -> SearchResult<iterator, is_key_compare_to::value> {
2918 if (!params_type::template can_have_multiple_equivalent_keys<K>()) {
2919 SearchResult<iterator, is_key_compare_to::value> ret = internal_locate(key);
2920 ret.value = internal_last(ret.value);
2921 return ret;
2922 }
2923 iterator iter(const_cast<node_type *>(root()));
2924 SearchResult<size_type, is_key_compare_to::value> res;
2925 bool seen_eq = false;
2926 for (;;) {
2927 res = iter.node_->lower_bound(key, key_comp());
2928 iter.position_ = static_cast<int>(res.value);
2929 if (iter.node_->is_leaf()) {
2930 break;
2931 }
2932 seen_eq = seen_eq || res.IsEq();
2933 iter.node_ = iter.node_->child(static_cast<field_type>(iter.position_));
2934 }
2935 if (res.IsEq()) return {iter, MatchKind::kEq};
2936 return {internal_last(iter), seen_eq ? MatchKind::kEq : MatchKind::kNe};
2937 }
2938
2939 template <typename P>
2940 template <typename K>
2941 auto btree<P>::internal_upper_bound(const K &key) const -> iterator {
2942 iterator iter(const_cast<node_type *>(root()));
2943 for (;;) {
2944 iter.position_ = static_cast<int>(iter.node_->upper_bound(key, key_comp()));
2945 if (iter.node_->is_leaf()) {
2946 break;
2947 }
2948 iter.node_ = iter.node_->child(static_cast<field_type>(iter.position_));
2949 }
2950 return internal_last(iter);
2951 }
2952
2953 template <typename P>
2954 template <typename K>
2955 auto btree<P>::internal_find(const K &key) const -> iterator {
2956 SearchResult<iterator, is_key_compare_to::value> res = internal_locate(key);
2957 if (res.HasMatch()) {
2958 if (res.IsEq()) {
2959 return res.value;
2960 }
2961 } else {
2962 const iterator iter = internal_last(res.value);
2963 if (iter.node_ != nullptr && !compare_keys(key, iter.key())) {
2964 return iter;
2965 }
2966 }
2967 return {nullptr, 0};
2968 }
2969
2970 template <typename P>
2971 typename btree<P>::size_type btree<P>::internal_verify(
2972 const node_type *node, const key_type *lo, const key_type *hi) const {
2973 assert(node->count() > 0);
2974 assert(node->count() <= node->max_count());
2975 if (lo) {
2976 assert(!compare_keys(node->key(node->start()), *lo));
2977 }
2978 if (hi) {
2979 assert(!compare_keys(*hi, node->key(node->finish() - 1)));
2980 }
2981 for (int i = node->start() + 1; i < node->finish(); ++i) {
2982 assert(!compare_keys(node->key(i), node->key(i - 1)));
2983 }
2984 size_type count = node->count();
2985 if (node->is_internal()) {
2986 for (field_type i = node->start(); i <= node->finish(); ++i) {
2987 assert(node->child(i) != nullptr);
2988 assert(node->child(i)->parent() == node);
2989 assert(node->child(i)->position() == i);
2990 count += internal_verify(node->child(i),
2991 i == node->start() ? lo : &node->key(i - 1),
2992 i == node->finish() ? hi : &node->key(i));
2993 }
2994 }
2995 return count;
2996 }
2997
2998 struct btree_access {
2999 template <typename BtreeContainer, typename Pred>
3000 static auto erase_if(BtreeContainer &container, Pred pred) ->
3001 typename BtreeContainer::size_type {
3002 const auto initial_size = container.size();
3003 auto &tree = container.tree_;
3004 auto *alloc = tree.mutable_allocator();
3005 for (auto it = container.begin(); it != container.end();) {
3006 if (!pred(*it)) {
3007 ++it;
3008 continue;
3009 }
3010 auto *node = it.node_;
3011 if (node->is_internal()) {
3012
3013 it = container.erase(it);
3014 continue;
3015 }
3016
3017
3018
3019
3020 int to_pos = it.position_;
3021 node->value_destroy(it.position_, alloc);
3022 while (++it.position_ < node->finish()) {
3023 it.update_generation();
3024 if (pred(*it)) {
3025 node->value_destroy(it.position_, alloc);
3026 } else {
3027 node->transfer(node->slot(to_pos++), node->slot(it.position_), alloc);
3028 }
3029 }
3030 const int num_deleted = node->finish() - to_pos;
3031 tree.size_ -= num_deleted;
3032 node->set_finish(to_pos);
3033 it.position_ = to_pos;
3034 it = tree.rebalance_after_delete(it);
3035 }
3036 return initial_size - container.size();
3037 }
3038 };
3039
3040 #undef ABSL_BTREE_ENABLE_GENERATIONS
3041
3042 }
3043 ABSL_NAMESPACE_END
3044 }
3045
3046 #endif