bloaty/third_party/abseil-cpp/absl/container/internal/btree.h
Go to the documentation of this file.
1 // Copyright 2018 The Abseil Authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // A btree implementation of the STL set and map interfaces. A btree is smaller
16 // and generally also faster than STL set/map (refer to the benchmarks below).
17 // The red-black tree implementation of STL set/map has an overhead of 3
18 // pointers (left, right and parent) plus the node color information for each
19 // stored value. So a set<int32_t> consumes 40 bytes for each value stored in
20 // 64-bit mode. This btree implementation stores multiple values on fixed
21 // size nodes (usually 256 bytes) and doesn't store child pointers for leaf
22 // nodes. The result is that a btree_set<int32_t> may use much less memory per
23 // stored value. For the random insertion benchmark in btree_bench.cc, a
24 // btree_set<int32_t> with node-size of 256 uses 5.1 bytes per stored value.
25 //
26 // The packing of multiple values on to each node of a btree has another effect
27 // besides better space utilization: better cache locality due to fewer cache
28 // lines being accessed. Better cache locality translates into faster
29 // operations.
30 //
31 // CAVEATS
32 //
33 // Insertions and deletions on a btree can cause splitting, merging or
34 // rebalancing of btree nodes. And even without these operations, insertions
35 // and deletions on a btree will move values around within a node. In both
36 // cases, the result is that insertions and deletions can invalidate iterators
37 // pointing to values other than the one being inserted/deleted. Therefore, this
38 // container does not provide pointer stability. This is notably different from
39 // STL set/map which takes care to not invalidate iterators on insert/erase
40 // except, of course, for iterators pointing to the value being erased. A
41 // partial workaround when erasing is available: erase() returns an iterator
42 // pointing to the item just after the one that was erased (or end() if none
43 // exists).
44 
45 #ifndef ABSL_CONTAINER_INTERNAL_BTREE_H_
46 #define ABSL_CONTAINER_INTERNAL_BTREE_H_
47 
48 #include <algorithm>
49 #include <cassert>
50 #include <cstddef>
51 #include <cstdint>
52 #include <cstring>
53 #include <functional>
54 #include <iterator>
55 #include <limits>
56 #include <new>
57 #include <string>
58 #include <type_traits>
59 #include <utility>
60 
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"
72 
73 namespace absl {
75 namespace container_internal {
76 
77 // A helper class that indicates if the Compare parameter is a key-compare-to
78 // comparator.
79 template <typename Compare, typename T>
81  std::is_convertible<absl::result_of_t<Compare(const T &, const T &)>,
83 
84 struct StringBtreeDefaultLess {
85  using is_transparent = void;
86 
87  StringBtreeDefaultLess() = default;
88 
89  // Compatibility constructor.
90  StringBtreeDefaultLess(std::less<std::string>) {} // NOLINT
91  StringBtreeDefaultLess(std::less<string_view>) {} // NOLINT
92 
94  absl::string_view rhs) const {
96  }
97  StringBtreeDefaultLess(std::less<absl::Cord>) {} // NOLINT
99  const absl::Cord &rhs) const {
101  }
103  absl::string_view rhs) const {
105  }
107  const absl::Cord &rhs) const {
109  }
110 };
111 
112 struct StringBtreeDefaultGreater {
113  using is_transparent = void;
114 
115  StringBtreeDefaultGreater() = default;
116 
117  StringBtreeDefaultGreater(std::greater<std::string>) {} // NOLINT
118  StringBtreeDefaultGreater(std::greater<string_view>) {} // NOLINT
119 
121  absl::string_view rhs) const {
123  }
124  StringBtreeDefaultGreater(std::greater<absl::Cord>) {} // NOLINT
126  const absl::Cord &rhs) const {
128  }
130  absl::string_view rhs) const {
132  }
134  const absl::Cord &rhs) const {
136  }
137 };
138 
139 // A helper class to convert a boolean comparison into a three-way "compare-to"
140 // comparison that returns an `absl::weak_ordering`. This helper
141 // class is specialized for less<std::string>, greater<std::string>,
142 // less<string_view>, greater<string_view>, less<absl::Cord>, and
143 // greater<absl::Cord>.
144 //
145 // key_compare_to_adapter is provided so that btree users
146 // automatically get the more efficient compare-to code when using common
147 // Abseil string types with common comparison functors.
148 // These string-like specializations also turn on heterogeneous lookup by
149 // default.
150 template <typename Compare>
152  using type = Compare;
153 };
154 
155 template <>
156 struct key_compare_to_adapter<std::less<std::string>> {
158 };
159 
160 template <>
161 struct key_compare_to_adapter<std::greater<std::string>> {
163 };
164 
165 template <>
166 struct key_compare_to_adapter<std::less<absl::string_view>> {
168 };
169 
170 template <>
171 struct key_compare_to_adapter<std::greater<absl::string_view>> {
173 };
174 
175 template <>
176 struct key_compare_to_adapter<std::less<absl::Cord>> {
178 };
179 
180 template <>
181 struct key_compare_to_adapter<std::greater<absl::Cord>> {
183 };
184 
185 // Detects an 'absl_btree_prefer_linear_node_search' member. This is
186 // a protocol used as an opt-in or opt-out of linear search.
187 //
188 // For example, this would be useful for key types that wrap an integer
189 // and define their own cheap operator<(). For example:
190 //
191 // class K {
192 // public:
193 // using absl_btree_prefer_linear_node_search = std::true_type;
194 // ...
195 // private:
196 // friend bool operator<(K a, K b) { return a.k_ < b.k_; }
197 // int k_;
198 // };
199 //
200 // btree_map<K, V> m; // Uses linear search
201 //
202 // If T has the preference tag, then it has a preference.
203 // Btree will use the tag's truth value.
204 template <typename T, typename = void>
206 template <typename T, typename = void>
207 struct prefers_linear_node_search : std::false_type {};
208 template <typename T>
209 struct has_linear_node_search_preference<
210  T, absl::void_t<typename T::absl_btree_prefer_linear_node_search>>
211  : std::true_type {};
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 {};
216 
217 template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
218  bool Multi, typename SlotPolicy>
219 struct common_params {
220  // If Compare is a common comparator for a string-like type, then we adapt it
221  // to use heterogeneous lookup and to be a key-compare-to comparator.
223  // A type which indicates if we have a key-compare-to functor or a plain old
224  // key-compare functor.
226 
228  using key_type = Key;
230  using difference_type = ptrdiff_t;
231 
232  using slot_policy = SlotPolicy;
233  using slot_type = typename slot_policy::slot_type;
235  using init_type = typename slot_policy::mutable_value_type;
236  using pointer = value_type *;
237  using const_pointer = const value_type *;
239  using const_reference = const value_type &;
240 
241  // For the given lookup key type, returns whether we can have multiple
242  // equivalent keys in the btree. If this is a multi-container, then we can.
243  // Otherwise, we can have multiple equivalent keys only if all of the
244  // following conditions are met:
245  // - The comparator is transparent.
246  // - The lookup key type is not the same as key_type.
247  // - The comparator is not a StringBtreeDefault{Less,Greater} comparator
248  // that we know has the same equivalence classes for all lookup types.
249  template <typename LookupKey>
250  constexpr static bool can_have_multiple_equivalent_keys() {
251  return Multi ||
256  }
257 
258  enum {
259  kTargetNodeSize = TargetNodeSize,
260 
261  // Upper bound for the available space for values. This is largest for leaf
262  // nodes, which have overhead of at least a pointer + 4 bytes (for storing
263  // 3 field_types and an enum).
265  TargetNodeSize - /*minimum overhead=*/(sizeof(void *) + 4),
266  };
267 
268  // This is an integral type large enough to hold as many
269  // ValueSize-values as will fit a node of TargetNodeSize bytes.
270  using node_count_type =
273  uint16_t, uint8_t>; // NOLINT
274 
275  // The following methods are necessary for passing this struct as PolicyTraits
276  // for node_handle and/or are used within btree.
277  static value_type &element(slot_type *slot) {
278  return slot_policy::element(slot);
279  }
280  static const value_type &element(const slot_type *slot) {
281  return slot_policy::element(slot);
282  }
283  template <class... Args>
284  static void construct(Alloc *alloc, slot_type *slot, Args &&... args) {
285  slot_policy::construct(alloc, slot, std::forward<Args>(args)...);
286  }
287  static void construct(Alloc *alloc, slot_type *slot, slot_type *other) {
288  slot_policy::construct(alloc, slot, other);
289  }
290  static void destroy(Alloc *alloc, slot_type *slot) {
292  }
293  static void transfer(Alloc *alloc, slot_type *new_slot, slot_type *old_slot) {
294  construct(alloc, new_slot, old_slot);
295  destroy(alloc, old_slot);
296  }
297  static void swap(Alloc *alloc, slot_type *a, slot_type *b) {
299  }
300  static void move(Alloc *alloc, slot_type *src, slot_type *dest) {
302  }
303 };
304 
305 // A parameters structure for holding the type parameters for a btree_map.
306 // Compare and Alloc should be nothrow copy-constructible.
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>> {
311  using super_type = typename map_params::common_params;
312  using mapped_type = Data;
313  // This type allows us to move keys when it is safe to do so. It is safe
314  // for maps in which value_type and mutable_value_type are layout compatible.
315  using slot_policy = typename super_type::slot_policy;
316  using slot_type = typename super_type::slot_type;
318  using init_type = typename super_type::init_type;
319 
320  using key_compare = typename super_type::key_compare;
321  // Inherit from key_compare for empty base class optimization.
322  struct value_compare : private key_compare {
323  value_compare() = default;
324  explicit value_compare(const key_compare &cmp) : key_compare(cmp) {}
325 
326  template <typename T, typename U>
327  auto operator()(const T &left, const U &right) const
328  -> decltype(std::declval<key_compare>()(left.first, right.first)) {
329  return key_compare::operator()(left.first, right.first);
330  }
331  };
333 
334  template <typename V>
335  static auto key(const V &value) -> decltype(value.first) {
336  return value.first;
337  }
338  static const Key &key(const slot_type *s) { return slot_policy::key(s); }
339  static const Key &key(slot_type *s) { return slot_policy::key(s); }
340  // For use in node handle.
341  static auto mutable_key(slot_type *s)
342  -> decltype(slot_policy::mutable_key(s)) {
343  return slot_policy::mutable_key(s);
344  }
345  static mapped_type &value(value_type *value) { return value->second; }
346 };
347 
348 // This type implements the necessary functions from the
349 // absl::container_internal::slot_type interface.
350 template <typename Key>
351 struct set_slot_policy {
352  using slot_type = Key;
353  using value_type = Key;
355 
356  static value_type &element(slot_type *slot) { return *slot; }
357  static const value_type &element(const slot_type *slot) { return *slot; }
358 
359  template <typename Alloc, class... Args>
360  static void construct(Alloc *alloc, slot_type *slot, Args &&... args) {
362  std::forward<Args>(args)...);
363  }
364 
365  template <typename Alloc>
366  static void construct(Alloc *alloc, slot_type *slot, slot_type *other) {
368  }
369 
370  template <typename Alloc>
371  static void destroy(Alloc *alloc, slot_type *slot) {
373  }
374 
375  template <typename Alloc>
376  static void swap(Alloc * /*alloc*/, slot_type *a, slot_type *b) {
377  using std::swap;
378  swap(*a, *b);
379  }
380 
381  template <typename Alloc>
382  static void move(Alloc * /*alloc*/, slot_type *src, slot_type *dest) {
383  *dest = std::move(*src);
384  }
385 };
386 
387 // A parameters structure for holding the type parameters for a btree_set.
388 // Compare and Alloc should be nothrow copy-constructible.
389 template <typename Key, typename Compare, typename Alloc, int TargetNodeSize,
390  bool Multi>
391 struct set_params : common_params<Key, Compare, Alloc, TargetNodeSize, Multi,
392  set_slot_policy<Key>> {
393  using value_type = Key;
394  using slot_type = typename set_params::common_params::slot_type;
395  using value_compare = typename set_params::common_params::key_compare;
397 
398  template <typename V>
399  static const V &key(const V &value) { return value; }
400  static const Key &key(const slot_type *slot) { return *slot; }
401  static const Key &key(slot_type *slot) { return *slot; }
402 };
403 
404 // An adapter class that converts a lower-bound compare into an upper-bound
405 // compare. Note: there is no need to make a version of this adapter specialized
406 // for key-compare-to functors because the upper-bound (the first value greater
407 // than the input) is never an exact match.
408 template <typename Compare>
409 struct upper_bound_adapter {
410  explicit upper_bound_adapter(const Compare &c) : comp(c) {}
411  template <typename K1, typename K2>
412  bool operator()(const K1 &a, const K2 &b) const {
413  // Returns true when a is not greater than b.
415  }
416 
417  private:
418  Compare comp;
419 };
420 
421 enum class MatchKind : uint8_t { kEq, kNe };
422 
423 template <typename V, bool IsCompareTo>
424 struct SearchResult {
425  V value;
427 
428  static constexpr bool HasMatch() { return true; }
429  bool IsEq() const { return match == MatchKind::kEq; }
430 };
431 
432 // When we don't use CompareTo, `match` is not present.
433 // This ensures that callers can't use it accidentally when it provides no
434 // useful information.
435 template <typename V>
436 struct SearchResult<V, false> {
438  explicit SearchResult(V value) : value(value) {}
439  SearchResult(V value, MatchKind /*match*/) : value(value) {}
440 
441  V value;
442 
443  static constexpr bool HasMatch() { return false; }
444  static constexpr bool IsEq() { return false; }
445 };
446 
447 // A node in the btree holding. The same node type is used for both internal
448 // and leaf nodes in the btree, though the nodes are allocated in such a way
449 // that the children array is only valid in internal nodes.
450 template <typename Params>
451 class btree_node {
452  using is_key_compare_to = typename Params::is_key_compare_to;
453  using field_type = typename Params::node_count_type;
454  using allocator_type = typename Params::allocator_type;
455  using slot_type = typename Params::slot_type;
456 
457  public:
458  using params_type = Params;
459  using key_type = typename Params::key_type;
460  using value_type = typename Params::value_type;
461  using pointer = typename Params::pointer;
463  using reference = typename Params::reference;
465  using key_compare = typename Params::key_compare;
466  using size_type = typename Params::size_type;
467  using difference_type = typename Params::difference_type;
468 
469  // Btree decides whether to use linear node search as follows:
470  // - If the comparator expresses a preference, use that.
471  // - If the key expresses a preference, use that.
472  // - If the key is arithmetic and the comparator is std::less or
473  // std::greater, choose linear.
474  // - Otherwise, choose binary.
475  // TODO(ezb): Might make sense to add condition(s) based on node-size.
476  using use_linear_search = std::integral_constant<
477  bool,
483  (std::is_same<std::less<key_type>, key_compare>::value ||
484  std::is_same<std::greater<key_type>,
486 
487  // This class is organized by absl::container_internal::Layout as if it had
488  // the following structure:
489  // // A pointer to the node's parent.
490  // btree_node *parent;
491  //
492  // // The position of the node in the node's parent.
493  // field_type position;
494  // // The index of the first populated value in `values`.
495  // // TODO(ezb): right now, `start` is always 0. Update insertion/merge
496  // // logic to allow for floating storage within nodes.
497  // field_type start;
498  // // The index after the last populated value in `values`. Currently, this
499  // // is the same as the count of values.
500  // field_type finish;
501  // // The maximum number of values the node can hold. This is an integer in
502  // // [1, kNodeSlots] for root leaf nodes, kNodeSlots for non-root leaf
503  // // nodes, and kInternalNodeMaxCount (as a sentinel value) for internal
504  // // nodes (even though there are still kNodeSlots values in the node).
505  // // TODO(ezb): make max_count use only 4 bits and record log2(capacity)
506  // // to free extra bits for is_root, etc.
507  // field_type max_count;
508  //
509  // // The array of values. The capacity is `max_count` for leaf nodes and
510  // // kNodeSlots for internal nodes. Only the values in
511  // // [start, finish) have been initialized and are valid.
512  // slot_type values[max_count];
513  //
514  // // The array of child pointers. The keys in children[i] are all less
515  // // than key(i). The keys in children[i + 1] are all greater than key(i).
516  // // There are 0 children for leaf nodes and kNodeSlots + 1 children for
517  // // internal nodes.
518  // btree_node *children[kNodeSlots + 1];
519  //
520  // This class is only constructed by EmptyNodeType. Normally, pointers to the
521  // layout above are allocated, cast to btree_node*, and de-allocated within
522  // the btree implementation.
523  ~btree_node() = default;
524  btree_node(btree_node const &) = delete;
525  btree_node &operator=(btree_node const &) = delete;
526 
527  // Public for EmptyNodeType.
528  constexpr static size_type Alignment() {
529  static_assert(LeafLayout(1).Alignment() == InternalLayout().Alignment(),
530  "Alignment of all nodes must be equal.");
531  return InternalLayout().Alignment();
532  }
533 
534  protected:
535  btree_node() = default;
536 
537  private:
540  constexpr static size_type SizeWithNSlots(size_type n) {
541  return layout_type(/*parent*/ 1,
542  /*position, start, finish, max_count*/ 4,
543  /*slots*/ n,
544  /*children*/ 0)
545  .AllocSize();
546  }
547  // A lower bound for the overhead of fields other than values in a leaf node.
548  constexpr static size_type MinimumOverhead() {
549  return SizeWithNSlots(1) - sizeof(value_type);
550  }
551 
552  // Compute how many values we can fit onto a leaf node taking into account
553  // padding.
554  constexpr static size_type NodeTargetSlots(const int begin, const int end) {
555  return begin == end ? begin
556  : SizeWithNSlots((begin + end) / 2 + 1) >
557  params_type::kTargetNodeSize
558  ? NodeTargetSlots(begin, (begin + end) / 2)
559  : NodeTargetSlots((begin + end) / 2 + 1, end);
560  }
561 
562  enum {
563  kTargetNodeSize = params_type::kTargetNodeSize,
564  kNodeTargetSlots = NodeTargetSlots(0, params_type::kTargetNodeSize),
565 
566  // We need a minimum of 3 slots per internal node in order to perform
567  // splitting (1 value for the two nodes involved in the split and 1 value
568  // propagated to the parent as the delimiter for the split). For performance
569  // reasons, we don't allow 3 slots-per-node due to bad worst case occupancy
570  // of 1/3 (for a node, not a b-tree).
571  kMinNodeSlots = 4,
572 
573  kNodeSlots =
575 
576  // The node is internal (i.e. is not a leaf node) if and only if `max_count`
577  // has this value.
578  kInternalNodeMaxCount = 0,
579  };
580 
581  // Leaves can have less than kNodeSlots values.
582  constexpr static layout_type LeafLayout(const int slot_count = kNodeSlots) {
583  return layout_type(/*parent*/ 1,
584  /*position, start, finish, max_count*/ 4,
585  /*slots*/ slot_count,
586  /*children*/ 0);
587  }
588  constexpr static layout_type InternalLayout() {
589  return layout_type(/*parent*/ 1,
590  /*position, start, finish, max_count*/ 4,
591  /*slots*/ kNodeSlots,
592  /*children*/ kNodeSlots + 1);
593  }
594  constexpr static size_type LeafSize(const int slot_count = kNodeSlots) {
595  return LeafLayout(slot_count).AllocSize();
596  }
597  constexpr static size_type InternalSize() {
598  return InternalLayout().AllocSize();
599  }
600 
601  // N is the index of the type in the Layout definition.
602  // ElementType<N> is the Nth type in the Layout definition.
603  template <size_type N>
604  inline typename layout_type::template ElementType<N> *GetField() {
605  // We assert that we don't read from values that aren't there.
606  assert(N < 3 || !leaf());
607  return InternalLayout().template Pointer<N>(reinterpret_cast<char *>(this));
608  }
609  template <size_type N>
610  inline const typename layout_type::template ElementType<N> *GetField() const {
611  assert(N < 3 || !leaf());
612  return InternalLayout().template Pointer<N>(
613  reinterpret_cast<const char *>(this));
614  }
615  void set_parent(btree_node *p) { *GetField<0>() = p; }
616  field_type &mutable_finish() { return GetField<1>()[2]; }
617  slot_type *slot(int i) { return &GetField<2>()[i]; }
618  slot_type *start_slot() { return slot(start()); }
619  slot_type *finish_slot() { return slot(finish()); }
620  const slot_type *slot(int i) const { return &GetField<2>()[i]; }
621  void set_position(field_type v) { GetField<1>()[0] = v; }
622  void set_start(field_type v) { GetField<1>()[1] = v; }
623  void set_finish(field_type v) { GetField<1>()[2] = v; }
624  // This method is only called by the node init methods.
625  void set_max_count(field_type v) { GetField<1>()[3] = v; }
626 
627  public:
628  // Whether this is a leaf node or not. This value doesn't change after the
629  // node is created.
630  bool leaf() const { return GetField<1>()[3] != kInternalNodeMaxCount; }
631 
632  // Getter for the position of this node in its parent.
633  field_type position() const { return GetField<1>()[0]; }
634 
635  // Getter for the offset of the first value in the `values` array.
636  field_type start() const {
637  // TODO(ezb): when floating storage is implemented, return GetField<1>()[1];
638  assert(GetField<1>()[1] == 0);
639  return 0;
640  }
641 
642  // Getter for the offset after the last value in the `values` array.
643  field_type finish() const { return GetField<1>()[2]; }
644 
645  // Getters for the number of values stored in this node.
646  field_type count() const {
647  assert(finish() >= start());
648  return finish() - start();
649  }
651  // Internal nodes have max_count==kInternalNodeMaxCount.
652  // Leaf nodes have max_count in [1, kNodeSlots].
653  const field_type max_count = GetField<1>()[3];
654  return max_count == field_type{kInternalNodeMaxCount}
655  ? field_type{kNodeSlots}
656  : max_count;
657  }
658 
659  // Getter for the parent of this node.
660  btree_node *parent() const { return *GetField<0>(); }
661  // Getter for whether the node is the root of the tree. The parent of the
662  // root of the tree is the leftmost node in the tree which is guaranteed to
663  // be a leaf.
664  bool is_root() const { return parent()->leaf(); }
665  void make_root() {
666  assert(parent()->is_root());
667  set_parent(parent()->parent());
668  }
669 
670  // Getters for the key/value at position i in the node.
671  const key_type &key(int i) const { return params_type::key(slot(i)); }
673  const_reference value(int i) const { return params_type::element(slot(i)); }
674 
675  // Getters/setter for the child at position i in the node.
676  btree_node *child(int i) const { return GetField<3>()[i]; }
677  btree_node *start_child() const { return child(start()); }
678  btree_node *&mutable_child(int i) { return GetField<3>()[i]; }
679  void clear_child(int i) {
681  }
682  void set_child(int i, btree_node *c) {
684  mutable_child(i) = c;
685  c->set_position(i);
686  }
687  void init_child(int i, btree_node *c) {
688  set_child(i, c);
689  c->set_parent(this);
690  }
691 
692  // Returns the position of the first value whose key is not less than k.
693  template <typename K>
695  const K &k, const key_compare &comp) const {
697  : binary_search(k, comp);
698  }
699  // Returns the position of the first value whose key is greater than k.
700  template <typename K>
701  int upper_bound(const K &k, const key_compare &comp) const {
702  auto upper_compare = upper_bound_adapter<key_compare>(comp);
703  return use_linear_search::value ? linear_search(k, upper_compare).value
704  : binary_search(k, upper_compare).value;
705  }
706 
707  template <typename K, typename Compare>
709  linear_search(const K &k, const Compare &comp) const {
710  return linear_search_impl(k, start(), finish(), comp,
712  }
713 
714  template <typename K, typename Compare>
716  binary_search(const K &k, const Compare &comp) const {
717  return binary_search_impl(k, start(), finish(), comp,
719  }
720 
721  // Returns the position of the first value whose key is not less than k using
722  // linear search performed using plain compare.
723  template <typename K, typename Compare>
725  const K &k, int s, const int e, const Compare &comp,
726  std::false_type /* IsCompareTo */) const {
727  while (s < e) {
728  if (!comp(key(s), k)) {
729  break;
730  }
731  ++s;
732  }
733  return SearchResult<int, false>{s};
734  }
735 
736  // Returns the position of the first value whose key is not less than k using
737  // linear search performed using compare-to.
738  template <typename K, typename Compare>
740  const K &k, int s, const int e, const Compare &comp,
741  std::true_type /* IsCompareTo */) const {
742  while (s < e) {
743  const absl::weak_ordering c = comp(key(s), k);
744  if (c == 0) {
745  return {s, MatchKind::kEq};
746  } else if (c > 0) {
747  break;
748  }
749  ++s;
750  }
751  return {s, MatchKind::kNe};
752  }
753 
754  // Returns the position of the first value whose key is not less than k using
755  // binary search performed using plain compare.
756  template <typename K, typename Compare>
758  const K &k, int s, int e, const Compare &comp,
759  std::false_type /* IsCompareTo */) const {
760  while (s != e) {
761  const int mid = (s + e) >> 1;
762  if (comp(key(mid), k)) {
763  s = mid + 1;
764  } else {
765  e = mid;
766  }
767  }
768  return SearchResult<int, false>{s};
769  }
770 
771  // Returns the position of the first value whose key is not less than k using
772  // binary search performed using compare-to.
773  template <typename K, typename CompareTo>
775  const K &k, int s, int e, const CompareTo &comp,
776  std::true_type /* IsCompareTo */) const {
777  if (params_type::template can_have_multiple_equivalent_keys<K>()) {
778  MatchKind exact_match = MatchKind::kNe;
779  while (s != e) {
780  const int mid = (s + e) >> 1;
781  const absl::weak_ordering c = comp(key(mid), k);
782  if (c < 0) {
783  s = mid + 1;
784  } else {
785  e = mid;
786  if (c == 0) {
787  // Need to return the first value whose key is not less than k,
788  // which requires continuing the binary search if there could be
789  // multiple equivalent keys.
790  exact_match = MatchKind::kEq;
791  }
792  }
793  }
794  return {s, exact_match};
795  } else { // Can't have multiple equivalent keys.
796  while (s != e) {
797  const int mid = (s + e) >> 1;
798  const absl::weak_ordering c = comp(key(mid), k);
799  if (c < 0) {
800  s = mid + 1;
801  } else if (c > 0) {
802  e = mid;
803  } else {
804  return {mid, MatchKind::kEq};
805  }
806  }
807  return {s, MatchKind::kNe};
808  }
809  }
810 
811  // Emplaces a value at position i, shifting all existing values and
812  // children at positions >= i to the right by 1.
813  template <typename... Args>
815 
816  // Removes the values at positions [i, i + to_erase), shifting all existing
817  // values and children after that range to the left by to_erase. Clears all
818  // children between [i, i + to_erase).
820 
821  // Rebalances a node with its right sibling.
822  void rebalance_right_to_left(int to_move, btree_node *right,
824  void rebalance_left_to_right(int to_move, btree_node *right,
826 
827  // Splits a node, moving a portion of the node's values to its right sibling.
828  void split(int insert_position, btree_node *dest, allocator_type *alloc);
829 
830  // Merges a node with its right sibling, moving all of the values and the
831  // delimiting key in the parent node onto itself, and deleting the src node.
832  void merge(btree_node *src, allocator_type *alloc);
833 
834  // Node allocation/deletion routines.
837  set_position(0);
838  set_start(0);
839  set_finish(0);
842  start_slot(), max_count * sizeof(slot_type));
843  }
845  init_leaf(parent, kNodeSlots);
846  // Set `max_count` to a sentinel value to indicate that this node is
847  // internal.
848  set_max_count(kInternalNodeMaxCount);
850  &mutable_child(start()), (kNodeSlots + 1) * sizeof(btree_node *));
851  }
852 
853  static void deallocate(const size_type size, btree_node *node,
855  absl::container_internal::Deallocate<Alignment()>(alloc, node, size);
856  }
857 
858  // Deletes a node and all of its children.
859  static void clear_and_delete(btree_node *node, allocator_type *alloc);
860 
861  private:
862  template <typename... Args>
865  params_type::construct(alloc, slot(i), std::forward<Args>(args)...);
866  }
870  }
871  void value_destroy_n(const field_type i, const field_type n,
873  for (slot_type *s = slot(i), *end = slot(i + n); s != end; ++s) {
876  }
877  }
878 
883  }
884 
885  // Transfers value from slot `src_i` in `src_node` to slot `dest_i` in `this`.
886  void transfer(const size_type dest_i, const size_type src_i,
887  btree_node *src_node, allocator_type *alloc) {
888  transfer(slot(dest_i), src_node->slot(src_i), alloc);
889  }
890 
891  // Transfers `n` values starting at value `src_i` in `src_node` into the
892  // values starting at value `dest_i` in `this`.
893  void transfer_n(const size_type n, const size_type dest_i,
894  const size_type src_i, btree_node *src_node,
896  for (slot_type *src = src_node->slot(src_i), *end = src + n,
897  *dest = slot(dest_i);
898  src != end; ++src, ++dest) {
899  transfer(dest, src, alloc);
900  }
901  }
902 
903  // Same as above, except that we start at the end and work our way to the
904  // beginning.
905  void transfer_n_backward(const size_type n, const size_type dest_i,
906  const size_type src_i, btree_node *src_node,
908  for (slot_type *src = src_node->slot(src_i + n - 1), *end = src - n,
909  *dest = slot(dest_i + n - 1);
910  src != end; --src, --dest) {
911  transfer(dest, src, alloc);
912  }
913  }
914 
915  template <typename P>
916  friend class btree;
917  template <typename N, typename R, typename P>
918  friend struct btree_iterator;
919  friend class BtreeNodePeer;
920 };
921 
922 template <typename Node, typename Reference, typename Pointer>
923 struct btree_iterator {
924  private:
925  using key_type = typename Node::key_type;
926  using size_type = typename Node::size_type;
927  using params_type = typename Node::params_type;
928  using is_map_container = typename params_type::is_map_container;
929 
930  using node_type = Node;
932  using const_node = const Node;
933  using normal_pointer = typename params_type::pointer;
934  using normal_reference = typename params_type::reference;
937  using slot_type = typename params_type::slot_type;
938 
939  using iterator =
941  using const_iterator =
943 
944  public:
945  // These aliases are public for std::iterator_traits.
946  using difference_type = typename Node::difference_type;
948  using pointer = Pointer;
950  using iterator_category = std::bidirectional_iterator_tag;
951 
952  btree_iterator() : node(nullptr), position(-1) {}
953  explicit btree_iterator(Node *n) : node(n), position(n->start()) {}
954  btree_iterator(Node *n, int p) : node(n), position(p) {}
955 
956  // NOTE: this SFINAE allows for implicit conversions from iterator to
957  // const_iterator, but it specifically avoids hiding the copy constructor so
958  // that the trivial one will be used when possible.
959  template <typename N, typename R, typename P,
961  std::is_same<btree_iterator<N, R, P>, iterator>::value &&
963  int> = 0>
965  : node(other.node), position(other.position) {}
966 
967  private:
968  // This SFINAE allows explicit conversions from const_iterator to
969  // iterator, but also avoids hiding the copy constructor.
970  // NOTE: the const_cast is safe because this constructor is only called by
971  // non-const methods and the container owns the nodes.
972  template <typename N, typename R, typename P,
974  std::is_same<btree_iterator<N, R, P>, const_iterator>::value &&
976  int> = 0>
978  : node(const_cast<node_type *>(other.node)), position(other.position) {}
979 
980  // Increment/decrement the iterator.
981  void increment() {
982  if (node->leaf() && ++position < node->finish()) {
983  return;
984  }
985  increment_slow();
986  }
987  void increment_slow();
988 
989  void decrement() {
990  if (node->leaf() && --position >= node->start()) {
991  return;
992  }
993  decrement_slow();
994  }
995  void decrement_slow();
996 
997  public:
998  bool operator==(const iterator &other) const {
999  return node == other.node && position == other.position;
1000  }
1001  bool operator==(const const_iterator &other) const {
1002  return node == other.node && position == other.position;
1003  }
1004  bool operator!=(const iterator &other) const {
1005  return node != other.node || position != other.position;
1006  }
1007  bool operator!=(const const_iterator &other) const {
1008  return node != other.node || position != other.position;
1009  }
1010 
1011  // Accessors for the key/value the iterator is pointing at.
1013  ABSL_HARDENING_ASSERT(node != nullptr);
1014  ABSL_HARDENING_ASSERT(node->start() <= position);
1015  ABSL_HARDENING_ASSERT(node->finish() > position);
1016  return node->value(position);
1017  }
1018  pointer operator->() const { return &operator*(); }
1019 
1021  increment();
1022  return *this;
1023  }
1025  decrement();
1026  return *this;
1027  }
1029  btree_iterator tmp = *this;
1030  ++*this;
1031  return tmp;
1032  }
1034  btree_iterator tmp = *this;
1035  --*this;
1036  return tmp;
1037  }
1038 
1039  private:
1040  friend iterator;
1041  friend const_iterator;
1042  template <typename Params>
1043  friend class btree;
1044  template <typename Tree>
1045  friend class btree_container;
1046  template <typename Tree>
1047  friend class btree_set_container;
1048  template <typename Tree>
1049  friend class btree_map_container;
1050  template <typename Tree>
1052  template <typename TreeType, typename CheckerType>
1053  friend class base_checker;
1054 
1055  const key_type &key() const { return node->key(position); }
1056  slot_type *slot() { return node->slot(position); }
1057 
1058  // The node in the tree the iterator is pointing at.
1060  // The position within the node of the tree the iterator is pointing at.
1061  // NOTE: this is an int rather than a field_type because iterators can point
1062  // to invalid positions (such as -1) in certain circumstances.
1064 };
1065 
1066 template <typename Params>
1067 class btree {
1069  using is_key_compare_to = typename Params::is_key_compare_to;
1070  using init_type = typename Params::init_type;
1072 
1073  // We use a static empty node for the root/leftmost/rightmost of empty btrees
1074  // in order to avoid branching in begin()/end().
1075  struct alignas(node_type::Alignment()) EmptyNodeType : node_type {
1077  node_type *parent;
1078  field_type position = 0;
1079  field_type start = 0;
1080  field_type finish = 0;
1081  // max_count must be != kInternalNodeMaxCount (so that this node is regarded
1082  // as a leaf node). max_count() is never called when the tree is empty.
1083  field_type max_count = node_type::kInternalNodeMaxCount + 1;
1084 
1085 #ifdef _MSC_VER
1086  // MSVC has constexpr code generations bugs here.
1087  EmptyNodeType() : parent(this) {}
1088 #else
1089  constexpr EmptyNodeType(node_type *p) : parent(p) {}
1090 #endif
1091  };
1092 
1093  static node_type *EmptyNode() {
1094 #ifdef _MSC_VER
1095  static EmptyNodeType *empty_node = new EmptyNodeType;
1096  // This assert fails on some other construction methods.
1097  assert(empty_node->parent == empty_node);
1098  return empty_node;
1099 #else
1100  static constexpr EmptyNodeType empty_node(
1101  const_cast<EmptyNodeType *>(&empty_node));
1102  return const_cast<EmptyNodeType *>(&empty_node);
1103 #endif
1104  }
1105 
1106  enum : uint32_t {
1107  kNodeSlots = node_type::kNodeSlots,
1108  kMinNodeValues = kNodeSlots / 2,
1109  };
1110 
1111  struct node_stats {
1112  using size_type = typename Params::size_type;
1113 
1115 
1117  leaf_nodes += other.leaf_nodes;
1118  internal_nodes += other.internal_nodes;
1119  return *this;
1120  }
1121 
1124  };
1125 
1126  public:
1127  using key_type = typename Params::key_type;
1128  using value_type = typename Params::value_type;
1129  using size_type = typename Params::size_type;
1130  using difference_type = typename Params::difference_type;
1131  using key_compare = typename Params::key_compare;
1132  using value_compare = typename Params::value_compare;
1133  using allocator_type = typename Params::allocator_type;
1134  using reference = typename Params::reference;
1136  using pointer = typename Params::pointer;
1138  using iterator =
1140  using const_iterator = typename iterator::const_iterator;
1141  using reverse_iterator = std::reverse_iterator<iterator>;
1142  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
1144 
1145  // Internal types made public for use by btree_container types.
1146  using params_type = Params;
1147  using slot_type = typename Params::slot_type;
1148 
1149  private:
1150  // For use in copy_or_move_values_in_order.
1153  // This is a destructive operation on the other container so it's safe for
1154  // us to const_cast and move from the keys here even if it's a set.
1155  return std::move(const_cast<value_type &>(*it));
1156  }
1157 
1158  // Copies or moves (depending on the template parameter) the values in
1159  // other into this btree in their order in other. This btree must be empty
1160  // before this method is called. This method is used in copy construction,
1161  // copy assignment, and move assignment.
1162  template <typename Btree>
1163  void copy_or_move_values_in_order(Btree &other);
1164 
1165  // Validates that various assumptions/requirements are true at compile time.
1166  constexpr static bool static_assert_validation();
1167 
1168  public:
1169  btree(const key_compare &comp, const allocator_type &alloc)
1170  : root_(comp, alloc, EmptyNode()), rightmost_(EmptyNode()), size_(0) {}
1171 
1172  btree(const btree &other) : btree(other, other.allocator()) {}
1173  btree(const btree &other, const allocator_type &alloc)
1174  : btree(other.key_comp(), alloc) {
1176  }
1177  btree(btree &&other) noexcept
1178  : root_(std::move(other.root_)),
1179  rightmost_(absl::exchange(other.rightmost_, EmptyNode())),
1180  size_(absl::exchange(other.size_, 0)) {
1181  other.mutable_root() = EmptyNode();
1182  }
1183  btree(btree &&other, const allocator_type &alloc)
1184  : btree(other.key_comp(), alloc) {
1185  if (alloc == other.allocator()) {
1186  swap(other);
1187  } else {
1188  // Move values from `other` one at a time when allocators are different.
1190  }
1191  }
1192 
1194  // Put static_asserts in destructor to avoid triggering them before the type
1195  // is complete.
1196  static_assert(static_assert_validation(), "This call must be elided.");
1197  clear();
1198  }
1199 
1200  // Assign the contents of other to *this.
1201  btree &operator=(const btree &other);
1202  btree &operator=(btree &&other) noexcept;
1203 
1204  iterator begin() { return iterator(leftmost()); }
1206  iterator end() { return iterator(rightmost_, rightmost_->finish()); }
1208  return const_iterator(rightmost_, rightmost_->finish());
1209  }
1212  return const_reverse_iterator(end());
1213  }
1216  return const_reverse_iterator(begin());
1217  }
1218 
1219  // Finds the first element whose key is not less than `key`.
1220  template <typename K>
1223  }
1224  template <typename K>
1225  const_iterator lower_bound(const K &key) const {
1227  }
1228 
1229  // Finds the first element whose key is not less than `key` and also returns
1230  // whether that element is equal to `key`.
1231  template <typename K>
1232  std::pair<iterator, bool> lower_bound_equal(const K &key) const;
1233 
1234  // Finds the first element whose key is greater than `key`.
1235  template <typename K>
1238  }
1239  template <typename K>
1240  const_iterator upper_bound(const K &key) const {
1242  }
1243 
1244  // Finds the range of values which compare equal to key. The first member of
1245  // the returned pair is equal to lower_bound(key). The second member of the
1246  // pair is equal to upper_bound(key).
1247  template <typename K>
1248  std::pair<iterator, iterator> equal_range(const K &key);
1249  template <typename K>
1250  std::pair<const_iterator, const_iterator> equal_range(const K &key) const {
1251  return const_cast<btree *>(this)->equal_range(key);
1252  }
1253 
1254  // Inserts a value into the btree only if it does not already exist. The
1255  // boolean return value indicates whether insertion succeeded or failed.
1256  // Requirement: if `key` already exists in the btree, does not consume `args`.
1257  // Requirement: `key` is never referenced after consuming `args`.
1258  template <typename K, typename... Args>
1259  std::pair<iterator, bool> insert_unique(const K &key, Args &&... args);
1260 
1261  // Inserts with hint. Checks to see if the value should be placed immediately
1262  // before `position` in the tree. If so, then the insertion will take
1263  // amortized constant time. If not, the insertion will take amortized
1264  // logarithmic time as if a call to insert_unique() were made.
1265  // Requirement: if `key` already exists in the btree, does not consume `args`.
1266  // Requirement: `key` is never referenced after consuming `args`.
1267  template <typename K, typename... Args>
1268  std::pair<iterator, bool> insert_hint_unique(iterator position,
1269  const K &key,
1270  Args &&... args);
1271 
1272  // Insert a range of values into the btree.
1273  // Note: the first overload avoids constructing a value_type if the key
1274  // already exists in the btree.
1275  template <typename InputIterator,
1276  typename = decltype(std::declval<const key_compare &>()(
1277  params_type::key(*std::declval<InputIterator>()),
1278  std::declval<const key_type &>()))>
1279  void insert_iterator_unique(InputIterator b, InputIterator e, int);
1280  // We need the second overload for cases in which we need to construct a
1281  // value_type in order to compare it with the keys already in the btree.
1282  template <typename InputIterator>
1283  void insert_iterator_unique(InputIterator b, InputIterator e, char);
1284 
1285  // Inserts a value into the btree.
1286  template <typename ValueType>
1288 
1289  // Inserts a value into the btree.
1290  template <typename ValueType>
1292  return insert_multi(params_type::key(v), std::forward<ValueType>(v));
1293  }
1294 
1295  // Insert with hint. Check to see if the value should be placed immediately
1296  // before position in the tree. If it does, then the insertion will take
1297  // amortized constant time. If not, the insertion will take amortized
1298  // logarithmic time as if a call to insert_multi(v) were made.
1299  template <typename ValueType>
1301 
1302  // Insert a range of values into the btree.
1303  template <typename InputIterator>
1304  void insert_iterator_multi(InputIterator b, InputIterator e);
1305 
1306  // Erase the specified iterator from the btree. The iterator must be valid
1307  // (i.e. not equal to end()). Return an iterator pointing to the node after
1308  // the one that was erased (or end() if none exists).
1309  // Requirement: does not read the value at `*iter`.
1311 
1312  // Erases range. Returns the number of keys erased and an iterator pointing
1313  // to the element after the last erased element.
1314  std::pair<size_type, iterator> erase_range(iterator begin, iterator end);
1315 
1316  // Finds an element with key equivalent to `key` or returns `end()` if `key`
1317  // is not present.
1318  template <typename K>
1319  iterator find(const K &key) {
1320  return internal_end(internal_find(key));
1321  }
1322  template <typename K>
1323  const_iterator find(const K &key) const {
1324  return internal_end(internal_find(key));
1325  }
1326 
1327  // Clear the btree, deleting all of the values it contains.
1328  void clear();
1329 
1330  // Swaps the contents of `this` and `other`.
1331  void swap(btree &other);
1332 
1333  const key_compare &key_comp() const noexcept {
1334  return root_.template get<0>();
1335  }
1336  template <typename K1, typename K2>
1337  bool compare_keys(const K1 &a, const K2 &b) const {
1339  }
1340 
1342 
1343  // Verifies the structure of the btree.
1344  void verify() const;
1345 
1346  // Size routines.
1347  size_type size() const { return size_; }
1349  bool empty() const { return size_ == 0; }
1350 
1351  // The height of the btree. An empty tree will have height 0.
1352  size_type height() const {
1353  size_type h = 0;
1354  if (!empty()) {
1355  // Count the length of the chain from the leftmost node up to the
1356  // root. We actually count from the root back around to the level below
1357  // the root, but the calculation is the same because of the circularity
1358  // of that traversal.
1359  const node_type *n = root();
1360  do {
1361  ++h;
1362  n = n->parent();
1363  } while (n != root());
1364  }
1365  return h;
1366  }
1367 
1368  // The number of internal, leaf and total nodes used by the btree.
1372  }
1373  size_type nodes() const {
1374  node_stats stats = internal_stats(root());
1375  return stats.leaf_nodes + stats.internal_nodes;
1376  }
1377 
1378  // The total number of bytes used by the btree.
1380  node_stats stats = internal_stats(root());
1381  if (stats.leaf_nodes == 1 && stats.internal_nodes == 0) {
1382  return sizeof(*this) + node_type::LeafSize(root()->max_count());
1383  } else {
1384  return sizeof(*this) + stats.leaf_nodes * node_type::LeafSize() +
1385  stats.internal_nodes * node_type::InternalSize();
1386  }
1387  }
1388 
1389  // The average number of bytes used per value stored in the btree assuming
1390  // random insertion order.
1391  static double average_bytes_per_value() {
1392  // The expected number of values per node with random insertion order is the
1393  // average of the maximum and minimum numbers of values per node.
1394  const double expected_values_per_node =
1395  (kNodeSlots + kMinNodeValues) / 2.0;
1396  return node_type::LeafSize() / expected_values_per_node;
1397  }
1398 
1399  // The fullness of the btree. Computed as the number of elements in the btree
1400  // divided by the maximum number of elements a tree with the current number
1401  // of nodes could hold. A value of 1 indicates perfect space
1402  // utilization. Smaller values indicate space wastage.
1403  // Returns 0 for empty trees.
1404  double fullness() const {
1405  if (empty()) return 0.0;
1406  return static_cast<double>(size()) / (nodes() * kNodeSlots);
1407  }
1408  // The overhead of the btree structure in bytes per node. Computed as the
1409  // total number of bytes used by the btree minus the number of bytes used for
1410  // storing elements divided by the number of elements.
1411  // Returns 0 for empty trees.
1412  double overhead() const {
1413  if (empty()) return 0.0;
1414  return (bytes_used() - size() * sizeof(value_type)) /
1415  static_cast<double>(size());
1416  }
1417 
1418  // The allocator used by the btree.
1420 
1421  private:
1422  // Internal accessor routines.
1423  node_type *root() { return root_.template get<2>(); }
1424  const node_type *root() const { return root_.template get<2>(); }
1425  node_type *&mutable_root() noexcept { return root_.template get<2>(); }
1426  key_compare *mutable_key_comp() noexcept { return &root_.template get<0>(); }
1427 
1428  // The leftmost node is stored as the parent of the root node.
1429  node_type *leftmost() { return root()->parent(); }
1430  const node_type *leftmost() const { return root()->parent(); }
1431 
1432  // Allocator routines.
1434  return &root_.template get<1>();
1435  }
1436  const allocator_type &allocator() const noexcept {
1437  return root_.template get<1>();
1438  }
1439 
1440  // Allocates a correctly aligned node of at least size bytes using the
1441  // allocator.
1443  return reinterpret_cast<node_type *>(
1444  absl::container_internal::Allocate<node_type::Alignment()>(
1445  mutable_allocator(), size));
1446  }
1447 
1448  // Node creation/deletion routines.
1451  n->init_internal(parent);
1452  return n;
1453  }
1456  n->init_leaf(parent, kNodeSlots);
1457  return n;
1458  }
1459  node_type *new_leaf_root_node(const int max_count) {
1460  node_type *n = allocate(node_type::LeafSize(max_count));
1461  n->init_leaf(/*parent=*/n, max_count);
1462  return n;
1463  }
1464 
1465  // Deletion helper routines.
1467 
1468  // Rebalances or splits the node iter points to.
1470 
1471  // Merges the values of left, right and the delimiting key on their parent
1472  // onto left, removing the delimiting key and deleting right.
1473  void merge_nodes(node_type *left, node_type *right);
1474 
1475  // Tries to merge node with its left or right sibling, and failing that,
1476  // rebalance with its left or right sibling. Returns true if a merge
1477  // occurred, at which point it is no longer valid to access node. Returns
1478  // false if no merging took place.
1480 
1481  // Tries to shrink the height of the tree by 1.
1482  void try_shrink();
1483 
1485  return iter.node != nullptr ? iter : end();
1486  }
1488  return iter.node != nullptr ? iter : end();
1489  }
1490 
1491  // Emplaces a value into the btree immediately before iter. Requires that
1492  // key(v) <= iter.key() and (--iter).key() <= key(v).
1493  template <typename... Args>
1495 
1496  // Returns an iterator pointing to the first value >= the value "iter" is
1497  // pointing at. Note that "iter" might be pointing to an invalid location such
1498  // as iter.position == iter.node->finish(). This routine simply moves iter up
1499  // in the tree to a valid location.
1500  // Requires: iter.node is non-null.
1501  template <typename IterType>
1502  static IterType internal_last(IterType iter);
1503 
1504  // Returns an iterator pointing to the leaf position at which key would
1505  // reside in the tree, unless there is an exact match - in which case, the
1506  // result may not be on a leaf. When there's a three-way comparator, we can
1507  // return whether there was an exact match. This allows the caller to avoid a
1508  // subsequent comparison to determine if an exact match was made, which is
1509  // important for keys with expensive comparison, such as strings.
1510  template <typename K>
1512  const K &key) const;
1513 
1514  // Internal routine which implements lower_bound().
1515  template <typename K>
1517  const K &key) const;
1518 
1519  // Internal routine which implements upper_bound().
1520  template <typename K>
1521  iterator internal_upper_bound(const K &key) const;
1522 
1523  // Internal routine which implements find().
1524  template <typename K>
1525  iterator internal_find(const K &key) const;
1526 
1527  // Verifies the tree structure of node.
1528  int internal_verify(const node_type *node, const key_type *lo,
1529  const key_type *hi) const;
1530 
1531  node_stats internal_stats(const node_type *node) const {
1532  // The root can be a static empty node.
1533  if (node == nullptr || (node == root() && empty())) {
1534  return node_stats(0, 0);
1535  }
1536  if (node->leaf()) {
1537  return node_stats(1, 0);
1538  }
1539  node_stats res(0, 1);
1540  for (int i = node->start(); i <= node->finish(); ++i) {
1541  res += internal_stats(node->child(i));
1542  }
1543  return res;
1544  }
1545 
1546  // We use compressed tuple in order to save space because key_compare and
1547  // allocator_type are usually empty.
1549  node_type *>
1551 
1552  // A pointer to the rightmost node. Note that the leftmost node is stored as
1553  // the root's parent.
1555 
1556  // Number of values.
1557  size_type size_;
1558 };
1559 
1561 // btree_node methods
1562 template <typename P>
1563 template <typename... Args>
1564 inline void btree_node<P>::emplace_value(const size_type i,
1565  allocator_type *alloc,
1566  Args &&... args) {
1567  assert(i >= start());
1568  assert(i <= finish());
1569  // Shift old values to create space for new value and then construct it in
1570  // place.
1571  if (i < finish()) {
1572  transfer_n_backward(finish() - i, /*dest_i=*/i + 1, /*src_i=*/i, this,
1573  alloc);
1574  }
1575  value_init(i, alloc, std::forward<Args>(args)...);
1576  set_finish(finish() + 1);
1577 
1578  if (!leaf() && finish() > i + 1) {
1579  for (int j = finish(); j > i + 1; --j) {
1580  set_child(j, child(j - 1));
1581  }
1582  clear_child(i + 1);
1583  }
1584 }
1585 
1586 template <typename P>
1587 inline void btree_node<P>::remove_values(const field_type i,
1588  const field_type to_erase,
1589  allocator_type *alloc) {
1590  // Transfer values after the removed range into their new places.
1591  value_destroy_n(i, to_erase, alloc);
1592  const field_type orig_finish = finish();
1593  const field_type src_i = i + to_erase;
1594  transfer_n(orig_finish - src_i, i, src_i, this, alloc);
1595 
1596  if (!leaf()) {
1597  // Delete all children between begin and end.
1598  for (int j = 0; j < to_erase; ++j) {
1599  clear_and_delete(child(i + j + 1), alloc);
1600  }
1601  // Rotate children after end into new positions.
1602  for (int j = i + to_erase + 1; j <= orig_finish; ++j) {
1603  set_child(j - to_erase, child(j));
1604  clear_child(j);
1605  }
1606  }
1607  set_finish(orig_finish - to_erase);
1608 }
1609 
1610 template <typename P>
1611 void btree_node<P>::rebalance_right_to_left(const int to_move,
1612  btree_node *right,
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());
1619 
1620  // 1) Move the delimiting value in the parent to the left node.
1621  transfer(finish(), position(), parent(), alloc);
1622 
1623  // 2) Move the (to_move - 1) values from the right node to the left node.
1624  transfer_n(to_move - 1, finish() + 1, right->start(), right, alloc);
1625 
1626  // 3) Move the new delimiting value to the parent from the right node.
1627  parent()->transfer(position(), right->start() + to_move - 1, right, alloc);
1628 
1629  // 4) Shift the values in the right node to their correct positions.
1630  right->transfer_n(right->count() - to_move, right->start(),
1631  right->start() + to_move, right, alloc);
1632 
1633  if (!leaf()) {
1634  // Move the child pointers from the right to the left node.
1635  for (int i = 0; i < to_move; ++i) {
1636  init_child(finish() + i + 1, right->child(i));
1637  }
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);
1642  }
1643  }
1644 
1645  // Fixup `finish` on the left and right nodes.
1646  set_finish(finish() + to_move);
1647  right->set_finish(right->finish() - to_move);
1648 }
1649 
1650 template <typename P>
1651 void btree_node<P>::rebalance_left_to_right(const int to_move,
1652  btree_node *right,
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());
1659 
1660  // Values in the right node are shifted to the right to make room for the
1661  // new to_move values. Then, the delimiting value in the parent and the
1662  // other (to_move - 1) values in the left node are moved into the right node.
1663  // Lastly, a new delimiting value is moved from the left node into the
1664  // parent, and the remaining empty left node entries are destroyed.
1665 
1666  // 1) Shift existing values in the right node to their correct positions.
1667  right->transfer_n_backward(right->count(), right->start() + to_move,
1668  right->start(), right, alloc);
1669 
1670  // 2) Move the delimiting value in the parent to the right node.
1671  right->transfer(right->start() + to_move - 1, position(), parent(), alloc);
1672 
1673  // 3) Move the (to_move - 1) values from the left node to the right node.
1674  right->transfer_n(to_move - 1, right->start(), finish() - (to_move - 1), this,
1675  alloc);
1676 
1677  // 4) Move the new delimiting value to the parent from the left node.
1678  parent()->transfer(position(), finish() - to_move, this, alloc);
1679 
1680  if (!leaf()) {
1681  // Move the child pointers from the left to the right node.
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);
1685  }
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);
1689  }
1690  }
1691 
1692  // Fixup the counts on the left and right nodes.
1693  set_finish(finish() - to_move);
1694  right->set_finish(right->finish() + to_move);
1695 }
1696 
1697 template <typename P>
1698 void btree_node<P>::split(const int insert_position, btree_node *dest,
1699  allocator_type *alloc) {
1700  assert(dest->count() == 0);
1701  assert(max_count() == kNodeSlots);
1702 
1703  // We bias the split based on the position being inserted. If we're
1704  // inserting at the beginning of the left node then bias the split to put
1705  // more values on the right node. If we're inserting at the end of the
1706  // right node then bias the split to put more values on the left node.
1707  if (insert_position == start()) {
1708  dest->set_finish(dest->start() + finish() - 1);
1709  } else if (insert_position == kNodeSlots) {
1710  dest->set_finish(dest->start());
1711  } else {
1712  dest->set_finish(dest->start() + count() / 2);
1713  }
1714  set_finish(finish() - dest->count());
1715  assert(count() >= 1);
1716 
1717  // Move values from the left sibling to the right sibling.
1718  dest->transfer_n(dest->count(), dest->start(), finish(), this, alloc);
1719 
1720  // The split key is the largest value in the left sibling.
1721  --mutable_finish();
1722  parent()->emplace_value(position(), alloc, finish_slot());
1723  value_destroy(finish(), alloc);
1724  parent()->init_child(position() + 1, dest);
1725 
1726  if (!leaf()) {
1727  for (int i = dest->start(), j = finish() + 1; i <= dest->finish();
1728  ++i, ++j) {
1729  assert(child(j) != nullptr);
1730  dest->init_child(i, child(j));
1731  clear_child(j);
1732  }
1733  }
1734 }
1735 
1736 template <typename P>
1737 void btree_node<P>::merge(btree_node *src, allocator_type *alloc) {
1738  assert(parent() == src->parent());
1739  assert(position() + 1 == src->position());
1740 
1741  // Move the delimiting value to the left node.
1742  value_init(finish(), alloc, parent()->slot(position()));
1743 
1744  // Move the values from the right to the left node.
1745  transfer_n(src->count(), finish() + 1, src->start(), src, alloc);
1746 
1747  if (!leaf()) {
1748  // Move the child pointers from the right to the left node.
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);
1752  }
1753  }
1754 
1755  // Fixup `finish` on the src and dest nodes.
1756  set_finish(start() + 1 + count() + src->count());
1757  src->set_finish(src->start());
1758 
1759  // Remove the value on the parent node and delete the src node.
1760  parent()->remove_values(position(), /*to_erase=*/1, alloc);
1761 }
1762 
1763 template <typename P>
1764 void btree_node<P>::clear_and_delete(btree_node *node, allocator_type *alloc) {
1765  if (node->leaf()) {
1766  node->value_destroy_n(node->start(), node->count(), alloc);
1767  deallocate(LeafSize(node->max_count()), node, alloc);
1768  return;
1769  }
1770  if (node->count() == 0) {
1771  deallocate(InternalSize(), node, alloc);
1772  return;
1773  }
1774 
1775  // The parent of the root of the subtree we are deleting.
1776  btree_node *delete_root_parent = node->parent();
1777 
1778  // Navigate to the leftmost leaf under node, and then delete upwards.
1779  while (!node->leaf()) node = node->start_child();
1780  // Use `int` because `pos` needs to be able to hold `kNodeSlots+1`, which
1781  // isn't guaranteed to be a valid `field_type`.
1782  int pos = node->position();
1783  btree_node *parent = node->parent();
1784  for (;;) {
1785  // In each iteration of the next loop, we delete one leaf node and go right.
1786  assert(pos <= parent->finish());
1787  do {
1788  node = parent->child(pos);
1789  if (!node->leaf()) {
1790  // Navigate to the leftmost leaf under node.
1791  while (!node->leaf()) node = node->start_child();
1792  pos = node->position();
1793  parent = node->parent();
1794  }
1795  node->value_destroy_n(node->start(), node->count(), alloc);
1796  deallocate(LeafSize(node->max_count()), node, alloc);
1797  ++pos;
1798  } while (pos <= parent->finish());
1799 
1800  // Once we've deleted all children of parent, delete parent and go up/right.
1801  assert(pos > parent->finish());
1802  do {
1803  node = parent;
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;
1809  ++pos;
1810  } while (pos > parent->finish());
1811  }
1812 }
1813 
1815 // btree_iterator methods
1816 template <typename N, typename R, typename P>
1818  if (node->leaf()) {
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);
1823  position = node->position();
1824  node = node->parent();
1825  }
1826  // TODO(ezb): assert we aren't incrementing end() instead of handling.
1827  if (position == node->finish()) {
1828  *this = save;
1829  }
1830  } else {
1831  assert(position < node->finish());
1832  node = node->child(position + 1);
1833  while (!node->leaf()) {
1834  node = node->start_child();
1835  }
1836  position = node->start();
1837  }
1838 }
1839 
1840 template <typename N, typename R, typename P>
1842  if (node->leaf()) {
1843  assert(position <= -1);
1844  btree_iterator save(*this);
1845  while (position < node->start() && !node->is_root()) {
1846  assert(node->parent()->child(node->position()) == node);
1847  position = node->position() - 1;
1848  node = node->parent();
1849  }
1850  // TODO(ezb): assert we aren't decrementing begin() instead of handling.
1851  if (position < node->start()) {
1852  *this = save;
1853  }
1854  } else {
1855  assert(position >= node->start());
1856  node = node->child(position);
1857  while (!node->leaf()) {
1858  node = node->child(node->finish());
1859  }
1860  position = node->finish() - 1;
1861  }
1862 }
1863 
1865 // btree methods
1866 template <typename P>
1867 template <typename Btree>
1868 void btree<P>::copy_or_move_values_in_order(Btree &other) {
1869  static_assert(std::is_same<btree, Btree>::value ||
1871  "Btree type must be same or const.");
1872  assert(empty());
1873 
1874  // We can avoid key comparisons because we know the order of the
1875  // values is the same order we'll store them in.
1876  auto iter = other.begin();
1877  if (iter == other.end()) return;
1878  insert_multi(maybe_move_from_iterator(iter));
1879  ++iter;
1880  for (; iter != other.end(); ++iter) {
1881  // If the btree is not empty, we can just insert the new value at the end
1882  // of the tree.
1883  internal_emplace(end(), maybe_move_from_iterator(iter));
1884  }
1885 }
1886 
1887 template <typename P>
1888 constexpr bool btree<P>::static_assert_validation() {
1890  "Key comparison must be nothrow copy constructible");
1892  "Allocator must be nothrow copy constructible");
1894  "iterator not trivially copyable.");
1895 
1896  // Note: We assert that kTargetValues, which is computed from
1897  // Params::kTargetNodeSize, must fit the node_type::field_type.
1898  static_assert(
1899  kNodeSlots < (1 << (8 * sizeof(typename node_type::field_type))),
1900  "target node size too large");
1901 
1902  // Verify that key_compare returns an absl::{weak,strong}_ordering or bool.
1903  using compare_result_type =
1904  absl::result_of_t<key_compare(key_type, key_type)>;
1905  static_assert(
1908  "key comparison function must return absl::{weak,strong}_ordering or "
1909  "bool.");
1910 
1911  // Test the assumption made in setting kNodeValueSpace.
1912  static_assert(node_type::MinimumOverhead() >= sizeof(void *) + 4,
1913  "node space assumption incorrect");
1914 
1915  return true;
1916 }
1917 
1918 template <typename P>
1919 template <typename K>
1920 auto btree<P>::lower_bound_equal(const K &key) const
1921  -> std::pair<iterator, bool> {
1922  const SearchResult<iterator, is_key_compare_to::value> res =
1923  internal_lower_bound(key);
1924  const iterator lower = iterator(internal_end(res.value));
1925  const bool equal = res.HasMatch()
1926  ? res.IsEq()
1927  : lower != end() && !compare_keys(key, lower.key());
1928  return {lower, equal};
1929 }
1930 
1931 template <typename P>
1932 template <typename K>
1933 auto btree<P>::equal_range(const K &key) -> std::pair<iterator, iterator> {
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};
1938  }
1939 
1940  const iterator next = std::next(lower);
1941  if (!params_type::template can_have_multiple_equivalent_keys<K>()) {
1942  // The next iterator after lower must point to a key greater than `key`.
1943  // Note: if this assert fails, then it may indicate that the comparator does
1944  // not meet the equivalence requirements for Compare
1945  // (see https://en.cppreference.com/w/cpp/named_req/Compare).
1946  assert(next == end() || compare_keys(key, next.key()));
1947  return {lower, next};
1948  }
1949  // Try once more to avoid the call to upper_bound() if there's only one
1950  // equivalent key. This should prevent all calls to upper_bound() in cases of
1951  // unique-containers with heterogeneous comparators in which all comparison
1952  // operators have the same equivalence classes.
1953  if (next == end() || compare_keys(key, next.key())) return {lower, next};
1954 
1955  // In this case, we need to call upper_bound() to avoid worst case O(N)
1956  // behavior if we were to iterate over equal keys.
1957  return {lower, upper_bound(key)};
1958 }
1959 
1960 template <typename P>
1961 template <typename K, typename... Args>
1962 auto btree<P>::insert_unique(const K &key, Args &&... args)
1963  -> std::pair<iterator, bool> {
1964  if (empty()) {
1965  mutable_root() = rightmost_ = new_leaf_root_node(1);
1966  }
1967 
1968  SearchResult<iterator, is_key_compare_to::value> res = internal_locate(key);
1969  iterator iter = res.value;
1970 
1971  if (res.HasMatch()) {
1972  if (res.IsEq()) {
1973  // The key already exists in the tree, do nothing.
1974  return {iter, false};
1975  }
1976  } else {
1977  iterator last = internal_last(iter);
1978  if (last.node && !compare_keys(key, last.key())) {
1979  // The key already exists in the tree, do nothing.
1980  return {last, false};
1981  }
1982  }
1983  return {internal_emplace(iter, std::forward<Args>(args)...), true};
1984 }
1985 
1986 template <typename P>
1987 template <typename K, typename... Args>
1988 inline auto btree<P>::insert_hint_unique(iterator position, const K &key,
1989  Args &&... args)
1990  -> std::pair<iterator, bool> {
1991  if (!empty()) {
1992  if (position == end() || compare_keys(key, position.key())) {
1993  if (position == begin() || compare_keys(std::prev(position).key(), key)) {
1994  // prev.key() < key < position.key()
1995  return {internal_emplace(position, std::forward<Args>(args)...), true};
1996  }
1997  } else if (compare_keys(position.key(), key)) {
1998  ++position;
1999  if (position == end() || compare_keys(key, position.key())) {
2000  // {original `position`}.key() < key < {current `position`}.key()
2001  return {internal_emplace(position, std::forward<Args>(args)...), true};
2002  }
2003  } else {
2004  // position.key() == key
2005  return {position, false};
2006  }
2007  }
2008  return insert_unique(key, std::forward<Args>(args)...);
2009 }
2010 
2011 template <typename P>
2012 template <typename InputIterator, typename>
2013 void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, int) {
2014  for (; b != e; ++b) {
2015  insert_hint_unique(end(), params_type::key(*b), *b);
2016  }
2017 }
2018 
2019 template <typename P>
2020 template <typename InputIterator>
2021 void btree<P>::insert_iterator_unique(InputIterator b, InputIterator e, char) {
2022  for (; b != e; ++b) {
2023  init_type value(*b);
2024  insert_hint_unique(end(), params_type::key(value), std::move(value));
2025  }
2026 }
2027 
2028 template <typename P>
2029 template <typename ValueType>
2031  if (empty()) {
2032  mutable_root() = rightmost_ = new_leaf_root_node(1);
2033  }
2034 
2035  iterator iter = internal_upper_bound(key);
2036  if (iter.node == nullptr) {
2037  iter = end();
2038  }
2039  return internal_emplace(iter, std::forward<ValueType>(v));
2040 }
2041 
2042 template <typename P>
2043 template <typename ValueType>
2045  if (!empty()) {
2046  const key_type &key = params_type::key(v);
2047  if (position == end() || !compare_keys(position.key(), key)) {
2048  if (position == begin() ||
2049  !compare_keys(key, std::prev(position).key())) {
2050  // prev.key() <= key <= position.key()
2051  return internal_emplace(position, std::forward<ValueType>(v));
2052  }
2053  } else {
2054  ++position;
2055  if (position == end() || !compare_keys(position.key(), key)) {
2056  // {original `position`}.key() < key < {current `position`}.key()
2057  return internal_emplace(position, std::forward<ValueType>(v));
2058  }
2059  }
2060  }
2061  return insert_multi(std::forward<ValueType>(v));
2062 }
2063 
2064 template <typename P>
2065 template <typename InputIterator>
2066 void btree<P>::insert_iterator_multi(InputIterator b, InputIterator e) {
2067  for (; b != e; ++b) {
2068  insert_hint_multi(end(), *b);
2069  }
2070 }
2071 
2072 template <typename P>
2073 auto btree<P>::operator=(const btree &other) -> btree & {
2074  if (this != &other) {
2075  clear();
2076 
2077  *mutable_key_comp() = other.key_comp();
2080  *mutable_allocator() = other.allocator();
2081  }
2082 
2083  copy_or_move_values_in_order(other);
2084  }
2085  return *this;
2086 }
2087 
2088 template <typename P>
2089 auto btree<P>::operator=(btree &&other) noexcept -> btree & {
2090  if (this != &other) {
2091  clear();
2092 
2093  using std::swap;
2096  // Note: `root_` also contains the allocator and the key comparator.
2097  swap(root_, other.root_);
2098  swap(rightmost_, other.rightmost_);
2099  swap(size_, other.size_);
2100  } else {
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_);
2105  swap(size_, other.size_);
2106  } else {
2107  // We aren't allowed to propagate the allocator and the allocator is
2108  // different so we can't take over its memory. We must move each element
2109  // individually. We need both `other` and `this` to have `other`s key
2110  // comparator while moving the values so we can't swap the key
2111  // comparators.
2112  *mutable_key_comp() = other.key_comp();
2113  copy_or_move_values_in_order(other);
2114  }
2115  }
2116  }
2117  return *this;
2118 }
2119 
2120 template <typename P>
2122  bool internal_delete = false;
2123  if (!iter.node->leaf()) {
2124  // Deletion of a value on an internal node. First, move the largest value
2125  // from our left child here, then delete that position (in remove_values()
2126  // below). We can get to the largest value from our left child by
2127  // decrementing iter.
2128  iterator internal_iter(iter);
2129  --iter;
2130  assert(iter.node->leaf());
2131  params_type::move(mutable_allocator(), iter.node->slot(iter.position),
2132  internal_iter.node->slot(internal_iter.position));
2133  internal_delete = true;
2134  }
2135 
2136  // Delete the key from the leaf.
2137  iter.node->remove_values(iter.position, /*to_erase=*/1, mutable_allocator());
2138  --size_;
2139 
2140  // We want to return the next value after the one we just erased. If we
2141  // erased from an internal node (internal_delete == true), then the next
2142  // value is ++(++iter). If we erased from a leaf node (internal_delete ==
2143  // false) then the next value is ++iter. Note that ++iter may point to an
2144  // internal node and the value in the internal node may move to a leaf node
2145  // (iter.node) when rebalancing is performed at the leaf level.
2146 
2147  iterator res = rebalance_after_delete(iter);
2148 
2149  // If we erased from an internal node, advance the iterator.
2150  if (internal_delete) {
2151  ++res;
2152  }
2153  return res;
2154 }
2155 
2156 template <typename P>
2158  // Merge/rebalance as we walk back up the tree.
2159  iterator res(iter);
2160  bool first_iteration = true;
2161  for (;;) {
2162  if (iter.node == root()) {
2163  try_shrink();
2164  if (empty()) {
2165  return end();
2166  }
2167  break;
2168  }
2169  if (iter.node->count() >= kMinNodeValues) {
2170  break;
2171  }
2172  bool merged = try_merge_or_rebalance(&iter);
2173  // On the first iteration, we should update `res` with `iter` because `res`
2174  // may have been invalidated.
2175  if (first_iteration) {
2176  res = iter;
2177  first_iteration = false;
2178  }
2179  if (!merged) {
2180  break;
2181  }
2182  iter.position = iter.node->position();
2183  iter.node = iter.node->parent();
2184  }
2185 
2186  // Adjust our return value. If we're pointing at the end of a node, advance
2187  // the iterator.
2188  if (res.position == res.node->finish()) {
2189  res.position = res.node->finish() - 1;
2190  ++res;
2191  }
2192 
2193  return res;
2194 }
2195 
2196 template <typename P>
2198  -> std::pair<size_type, iterator> {
2199  difference_type count = std::distance(begin, end);
2200  assert(count >= 0);
2201 
2202  if (count == 0) {
2203  return {0, begin};
2204  }
2205 
2206  if (count == size_) {
2207  clear();
2208  return {count, this->end()};
2209  }
2210 
2211  if (begin.node == end.node) {
2212  assert(end.position > begin.position);
2213  begin.node->remove_values(begin.position, end.position - begin.position,
2214  mutable_allocator());
2215  size_ -= count;
2216  return {count, rebalance_after_delete(begin)};
2217  }
2218 
2219  const size_type target_size = size_ - count;
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());
2227  size_ -= to_erase;
2228  begin = rebalance_after_delete(begin);
2229  } else {
2230  begin = erase(begin);
2231  }
2232  }
2233  return {count, begin};
2234 }
2235 
2236 template <typename P>
2237 void btree<P>::clear() {
2238  if (!empty()) {
2239  node_type::clear_and_delete(root(), mutable_allocator());
2240  }
2241  mutable_root() = EmptyNode();
2242  rightmost_ = EmptyNode();
2243  size_ = 0;
2244 }
2245 
2246 template <typename P>
2247 void btree<P>::swap(btree &other) {
2248  using std::swap;
2250  allocator_type>::propagate_on_container_swap::value) {
2251  // Note: `root_` also contains the allocator and the key comparator.
2252  swap(root_, other.root_);
2253  } else {
2254  // It's undefined behavior if the allocators are unequal here.
2255  assert(allocator() == other.allocator());
2256  swap(mutable_root(), other.mutable_root());
2257  swap(*mutable_key_comp(), *other.mutable_key_comp());
2258  }
2259  swap(rightmost_, other.rightmost_);
2260  swap(size_, other.size_);
2261 }
2262 
2263 template <typename P>
2264 void btree<P>::verify() const {
2265  assert(root() != nullptr);
2266  assert(leftmost() != nullptr);
2267  assert(rightmost_ != nullptr);
2268  assert(empty() || size() == internal_verify(root(), nullptr, 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());
2273 }
2274 
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());
2281 
2282  // First try to make room on the node by rebalancing.
2283  node_type *parent = node->parent();
2284  if (node != root()) {
2285  if (node->position() > parent->start()) {
2286  // Try rebalancing with our left sibling.
2287  node_type *left = parent->child(node->position() - 1);
2288  assert(left->max_count() == kNodeSlots);
2289  if (left->count() < kNodeSlots) {
2290  // We bias rebalancing based on the position being inserted. If we're
2291  // inserting at the end of the right node then we bias rebalancing to
2292  // fill up the left node.
2293  int to_move = (kNodeSlots - left->count()) /
2294  (1 + (insert_position < static_cast<int>(kNodeSlots)));
2295  to_move = (std::max)(1, to_move);
2296 
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());
2300 
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;
2305  node = left;
2306  }
2307 
2308  assert(node->count() < node->max_count());
2309  return;
2310  }
2311  }
2312  }
2313 
2314  if (node->position() < parent->finish()) {
2315  // Try rebalancing with our right sibling.
2316  node_type *right = parent->child(node->position() + 1);
2317  assert(right->max_count() == kNodeSlots);
2318  if (right->count() < kNodeSlots) {
2319  // We bias rebalancing based on the position being inserted. If we're
2320  // inserting at the beginning of the left node then we bias rebalancing
2321  // to fill up the right node.
2322  int to_move = (static_cast<int>(kNodeSlots) - right->count()) /
2323  (1 + (insert_position > node->start()));
2324  to_move = (std::max)(1, to_move);
2325 
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());
2329 
2330  if (insert_position > node->finish()) {
2331  insert_position = insert_position - node->count() - 1;
2332  node = right;
2333  }
2334 
2335  assert(node->count() < node->max_count());
2336  return;
2337  }
2338  }
2339  }
2340 
2341  // Rebalancing failed, make sure there is room on the parent node for a new
2342  // value.
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);
2347  }
2348  } else {
2349  // Rebalancing not possible because this is the root node.
2350  // Create a new root node and set the current root node as the child of the
2351  // new root.
2352  parent = new_internal_node(parent);
2353  parent->init_child(parent->start(), root());
2354  mutable_root() = parent;
2355  // If the former root was a leaf node, then it's now the rightmost node.
2356  assert(!parent->start_child()->leaf() ||
2357  parent->start_child() == rightmost_);
2358  }
2359 
2360  // Split the node.
2361  node_type *split_node;
2362  if (node->leaf()) {
2363  split_node = new_leaf_node(parent);
2364  node->split(insert_position, split_node, mutable_allocator());
2365  if (rightmost_ == node) rightmost_ = split_node;
2366  } else {
2367  split_node = new_internal_node(parent);
2368  node->split(insert_position, split_node, mutable_allocator());
2369  }
2370 
2371  if (insert_position > node->finish()) {
2372  insert_position = insert_position - node->count() - 1;
2373  node = split_node;
2374  }
2375 }
2376 
2377 template <typename P>
2378 void btree<P>::merge_nodes(node_type *left, node_type *right) {
2379  left->merge(right, mutable_allocator());
2380  if (rightmost_ == right) rightmost_ = left;
2381 }
2382 
2383 template <typename P>
2385  node_type *parent = iter->node->parent();
2386  if (iter->node->position() > parent->start()) {
2387  // Try merging with our left sibling.
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);
2393  iter->node = left;
2394  return true;
2395  }
2396  }
2397  if (iter->node->position() < parent->finish()) {
2398  // Try merging with our right sibling.
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);
2403  return true;
2404  }
2405  // Try rebalancing with our right sibling. We don't perform rebalancing if
2406  // we deleted the first element from iter->node and the node is not
2407  // empty. This is a small optimization for the common pattern of deleting
2408  // from the front of the tree.
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());
2414  return false;
2415  }
2416  }
2417  if (iter->node->position() > parent->start()) {
2418  // Try rebalancing with our left sibling. We don't perform rebalancing if
2419  // we deleted the last element from iter->node and the node is not
2420  // empty. This is a small optimization for the common pattern of deleting
2421  // from the back of the tree.
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;
2429  return false;
2430  }
2431  }
2432  return false;
2433 }
2434 
2435 template <typename P>
2436 void btree<P>::try_shrink() {
2437  node_type *orig_root = root();
2438  if (orig_root->count() > 0) {
2439  return;
2440  }
2441  // Deleted the last item on the root node, shrink the height of the tree.
2442  if (orig_root->leaf()) {
2443  assert(size() == 0);
2444  mutable_root() = rightmost_ = EmptyNode();
2445  } else {
2446  node_type *child = orig_root->start_child();
2447  child->make_root();
2448  mutable_root() = child;
2449  }
2450  node_type::clear_and_delete(orig_root, mutable_allocator());
2451 }
2452 
2453 template <typename P>
2454 template <typename IterType>
2455 inline IterType btree<P>::internal_last(IterType iter) {
2456  assert(iter.node != nullptr);
2457  while (iter.position == iter.node->finish()) {
2458  iter.position = iter.node->position();
2459  iter.node = iter.node->parent();
2460  if (iter.node->leaf()) {
2461  iter.node = nullptr;
2462  break;
2463  }
2464  }
2465  return iter;
2466 }
2467 
2468 template <typename P>
2469 template <typename... Args>
2470 inline auto btree<P>::internal_emplace(iterator iter, Args &&... args)
2471  -> iterator {
2472  if (!iter.node->leaf()) {
2473  // We can't insert on an internal node. Instead, we'll insert after the
2474  // previous value which is guaranteed to be on a leaf node.
2475  --iter;
2476  ++iter.position;
2477  }
2478  const field_type max_count = iter.node->max_count();
2479  allocator_type *alloc = mutable_allocator();
2480  if (iter.node->count() == max_count) {
2481  // Make room in the leaf for the new item.
2482  if (max_count < kNodeSlots) {
2483  // Insertion into the root where the root is smaller than the full node
2484  // size. Simply grow the size of the root node.
2485  assert(iter.node == root());
2486  iter.node =
2487  new_leaf_root_node((std::min<int>)(kNodeSlots, 2 * max_count));
2488  // Transfer the values from the old root to the new root.
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;
2497  } else {
2498  rebalance_or_split(&iter);
2499  }
2500  }
2501  iter.node->emplace_value(iter.position, alloc, std::forward<Args>(args)...);
2502  ++size_;
2503  return iter;
2504 }
2505 
2506 template <typename P>
2507 template <typename K>
2508 inline auto btree<P>::internal_locate(const K &key) const
2509  -> SearchResult<iterator, is_key_compare_to::value> {
2510  iterator iter(const_cast<node_type *>(root()));
2511  for (;;) {
2512  SearchResult<int, is_key_compare_to::value> res =
2513  iter.node->lower_bound(key, key_comp());
2514  iter.position = res.value;
2515  if (res.IsEq()) {
2516  return {iter, MatchKind::kEq};
2517  }
2518  // Note: in the non-key-compare-to case, we don't need to walk all the way
2519  // down the tree if the keys are equal, but determining equality would
2520  // require doing an extra comparison on each node on the way down, and we
2521  // will need to go all the way to the leaf node in the expected case.
2522  if (iter.node->leaf()) {
2523  break;
2524  }
2525  iter.node = iter.node->child(iter.position);
2526  }
2527  // Note: in the non-key-compare-to case, the key may actually be equivalent
2528  // here (and the MatchKind::kNe is ignored).
2529  return {iter, MatchKind::kNe};
2530 }
2531 
2532 template <typename P>
2533 template <typename K>
2534 auto btree<P>::internal_lower_bound(const K &key) const
2535  -> SearchResult<iterator, is_key_compare_to::value> {
2536  if (!params_type::template can_have_multiple_equivalent_keys<K>()) {
2537  SearchResult<iterator, is_key_compare_to::value> ret = internal_locate(key);
2538  ret.value = internal_last(ret.value);
2539  return ret;
2540  }
2541  iterator iter(const_cast<node_type *>(root()));
2542  SearchResult<int, is_key_compare_to::value> res;
2543  bool seen_eq = false;
2544  for (;;) {
2545  res = iter.node->lower_bound(key, key_comp());
2546  iter.position = res.value;
2547  if (iter.node->leaf()) {
2548  break;
2549  }
2550  seen_eq = seen_eq || res.IsEq();
2551  iter.node = iter.node->child(iter.position);
2552  }
2553  if (res.IsEq()) return {iter, MatchKind::kEq};
2554  return {internal_last(iter), seen_eq ? MatchKind::kEq : MatchKind::kNe};
2555 }
2556 
2557 template <typename P>
2558 template <typename K>
2559 auto btree<P>::internal_upper_bound(const K &key) const -> iterator {
2560  iterator iter(const_cast<node_type *>(root()));
2561  for (;;) {
2562  iter.position = iter.node->upper_bound(key, key_comp());
2563  if (iter.node->leaf()) {
2564  break;
2565  }
2566  iter.node = iter.node->child(iter.position);
2567  }
2568  return internal_last(iter);
2569 }
2570 
2571 template <typename P>
2572 template <typename K>
2573 auto btree<P>::internal_find(const K &key) const -> iterator {
2574  SearchResult<iterator, is_key_compare_to::value> res = internal_locate(key);
2575  if (res.HasMatch()) {
2576  if (res.IsEq()) {
2577  return res.value;
2578  }
2579  } else {
2580  const iterator iter = internal_last(res.value);
2581  if (iter.node != nullptr && !compare_keys(key, iter.key())) {
2582  return iter;
2583  }
2584  }
2585  return {nullptr, 0};
2586 }
2587 
2588 template <typename P>
2589 int btree<P>::internal_verify(const node_type *node, const key_type *lo,
2590  const key_type *hi) const {
2591  assert(node->count() > 0);
2592  assert(node->count() <= node->max_count());
2593  if (lo) {
2594  assert(!compare_keys(node->key(node->start()), *lo));
2595  }
2596  if (hi) {
2597  assert(!compare_keys(*hi, node->key(node->finish() - 1)));
2598  }
2599  for (int i = node->start() + 1; i < node->finish(); ++i) {
2600  assert(!compare_keys(node->key(i), node->key(i - 1)));
2601  }
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);
2608  count += internal_verify(node->child(i),
2609  i == node->start() ? lo : &node->key(i - 1),
2610  i == node->finish() ? hi : &node->key(i));
2611  }
2612  }
2613  return count;
2614 }
2615 
2616 } // namespace container_internal
2618 } // namespace absl
2619 
2620 #endif // ABSL_CONTAINER_INTERNAL_BTREE_H_
absl::container_internal::set_slot_policy::element
static const value_type & element(const slot_type *slot)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:357
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::const_pointer
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::const_pointer const_pointer
Definition: abseil-cpp/absl/container/internal/btree.h:1294
absl::container_internal::btree_iterator::operator!=
bool operator!=(const const_iterator &other) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1007
absl::container_internal::btree_node::slot_type
typename Params::slot_type slot_type
Definition: abseil-cpp/absl/container/internal/btree.h:518
absl::container_internal::btree::end
iterator end()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1206
absl::container_internal::MatchKind::kEq
@ kEq
absl::container_internal::btree_node::finish_slot
slot_type * finish_slot()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:619
absl::Cord
Definition: abseil-cpp/absl/strings/cord.h:150
absl::container_internal::btree::allocator
const allocator_type & allocator() const noexcept
Definition: abseil-cpp/absl/container/internal/btree.h:1597
absl::container_internal::StringBtreeDefaultLess::operator()
absl::weak_ordering operator()(absl::string_view lhs, absl::string_view rhs) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:93
absl::container_internal::btree_node::transfer_n
void transfer_n(const size_type n, const size_type dest_i, const size_type src_i, btree_node *src_node, allocator_type *alloc)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:893
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::key_compare
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::key_compare key_compare
Definition: abseil-cpp/absl/container/internal/btree.h:1287
absl::container_internal::StringBtreeDefaultLess::StringBtreeDefaultLess
StringBtreeDefaultLess()=default
absl::container_internal::StringBtreeDefaultLess::operator()
absl::weak_ordering operator()(absl::string_view lhs, const absl::Cord &rhs) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:106
absl::container_internal::StringBtreeDefaultGreater
Definition: abseil-cpp/absl/container/internal/btree.h:130
absl::container_internal::btree::node_stats::internal_nodes
size_type internal_nodes
Definition: abseil-cpp/absl/container/internal/btree.h:1279
regen-readme.it
it
Definition: regen-readme.py:15
absl::container_internal::btree_node::kNodeTargetSlots
@ kNodeTargetSlots
Definition: abseil-cpp/absl/container/internal/btree.h:639
absl::container_internal::btree::new_internal_node
node_type * new_internal_node(node_type *parent)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1449
absl::container_internal::btree::operator=
btree & operator=(const btree &other)
Definition: abseil-cpp/absl/container/internal/btree.h:2248
absl::str_format_internal::LengthMod::j
@ j
element
static std::function< Slot &(Slot *)> element
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:44
absl::container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, false >::is_map_container
std::false_type is_map_container
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:396
pos
int pos
Definition: libuv/docs/code/tty-gravity/main.c:11
absl::container_internal::btree::mutable_allocator
allocator_type * mutable_allocator() noexcept
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1433
absl::container_internal::btree_node::set_position
void set_position(field_type v)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:621
const
#define const
Definition: bloaty/third_party/zlib/zconf.h:230
opencensus.proto.agent.common.v1.common_pb2.Node
Node
Definition: common_pb2.py:308
bool
bool
Definition: setup_once.h:312
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::difference_type
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::difference_type difference_type
Definition: abseil-cpp/absl/container/internal/btree.h:1286
absl::container_internal::btree_node::slot
const slot_type * slot(int i) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:620
internal_verify
static int internal_verify(X509_STORE_CTX *ctx)
Definition: x509_vfy.c:1790
absl::container_internal::btree::rightmost_
absl::container_internal::CompressedTuple< key_compare, allocator_type, node_type * > rightmost_
Definition: abseil-cpp/absl/container/internal/btree.h:1713
absl::container_internal::map_params::value
static mapped_type & value(value_type *value)
Definition: abseil-cpp/absl/container/btree_map.h:843
finish
static int finish(struct hexdump_ctx *ctx)
Definition: hexdump.c:148
absl::container_internal::upper_bound_adapter::comp
Compare comp
Definition: abseil-cpp/absl/container/internal/btree.h:481
absl::container_internal::btree_node::init_child
void init_child(int i, btree_node *c)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:687
absl::container_internal::btree_node::set_finish
void set_finish(field_type v)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:623
absl::container_internal::btree_node::mutable_finish
field_type & mutable_finish()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:616
begin
char * begin
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1007
absl::container_internal::set_slot_policy::destroy
static void destroy(Alloc *alloc, slot_type *slot)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:371
absl::container_internal::btree::verify
void verify() const
Definition: abseil-cpp/absl/container/internal/btree.h:2449
absl::container_internal::btree_node::position
field_type position() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:633
absl::container_internal::set_slot_policy::slot_type
Key slot_type
Definition: abseil-cpp/absl/container/btree_set.h:736
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::reference
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::reference reference
Definition: abseil-cpp/absl/container/internal/btree.h:1291
false
#define false
Definition: setup_once.h:323
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
absl::container_internal::btree_iterator::btree_iterator
btree_iterator(Node *n, int p)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:954
absl::container_internal::map_params::mutable_key
static auto mutable_key(slot_type *s) -> decltype(slot_policy::mutable_key(s))
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:341
absl::container_internal::StringBtreeDefaultGreater::operator()
absl::weak_ordering operator()(absl::string_view lhs, const absl::Cord &rhs) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:133
absl::container_internal::btree::upper_bound
iterator upper_bound(const K &key)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1236
absl::container_internal::btree_node::key_type
typename Params::key_type key_type
Definition: abseil-cpp/absl/container/internal/btree.h:523
absl::container_internal::btree::rend
const_reverse_iterator rend() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1215
absl::container_internal::btree::kNodeSlots
@ kNodeSlots
Definition: abseil-cpp/absl/container/internal/btree.h:1263
absl::container_internal::btree_node::GetField
layout_type::template ElementType< N > * GetField()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:604
absl::container_internal::btree::lower_bound_equal
std::pair< iterator, bool > lower_bound_equal(const K &key) const
absl::container_internal::btree_node::key
const key_type & key(int i) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:671
position
intern position
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/array.c:487
absl::container_internal::btree_node::GetField
const layout_type::template ElementType< N > * GetField() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:610
absl::container_internal::btree_node::init_internal
void init_internal(btree_node *parent)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:844
google::protobuf.internal::true_type
integral_constant< bool, true > true_type
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/template_util.h:89
absl::Cord::Compare
int Compare(absl::string_view rhs) const
Definition: abseil-cpp/absl/strings/cord.cc:974
absl::container_internal::btree::root
node_type * root()
Definition: abseil-cpp/absl/container/internal/btree.h:1577
absl::container_internal::btree::new_leaf_node
node_type * new_leaf_node(node_type *parent)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1454
absl::container_internal::StringBtreeDefaultGreater::StringBtreeDefaultGreater
StringBtreeDefaultGreater(std::greater< std::string >)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:117
absl::container_internal::btree::btree
btree(btree &&other) noexcept
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1177
absl::container_internal::btree::lower_bound
const_iterator lower_bound(const K &key) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1225
absl::conditional_t
typename std::conditional< B, T, F >::type conditional_t
Definition: abseil-cpp/absl/meta/type_traits.h:634
absl::container_internal::btree::maybe_move_from_iterator
const value_type & maybe_move_from_iterator(const_iterator it)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1151
absl::container_internal::btree_node::set_start
void set_start(field_type v)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:622
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
absl::container_internal::common_params::kTargetNodeSize
@ kTargetNodeSize
Definition: abseil-cpp/absl/container/internal/btree.h:428
google::protobuf.internal::false_type
integral_constant< bool, false > false_type
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/template_util.h:90
absl::container_internal::btree_node::pointer
typename Params::pointer pointer
Definition: abseil-cpp/absl/container/internal/btree.h:525
absl::container_internal::StringBtreeDefaultGreater::StringBtreeDefaultGreater
StringBtreeDefaultGreater(std::greater< string_view >)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:118
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: abseil-cpp/absl/container/internal/btree.h:1299
absl::container_internal::btree_iterator::operator*
reference operator*() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1012
absl::container_internal::btree_node::init_leaf
void init_leaf(int max_count, btree_node *parent)
Definition: abseil-cpp/absl/container/internal/btree.h:940
absl::container_internal::btree::EmptyNodeType::parent
node_type * parent
Definition: abseil-cpp/absl/container/internal/btree.h:1230
absl::container_internal::btree_node::value_destroy_n
void value_destroy_n(const field_type i, const field_type n, allocator_type *alloc)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:871
absl::container_internal::btree::insert_multi
iterator insert_multi(ValueType &&v)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1291
absl::container_internal::key_compare_to_adapter
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:151
absl::container_internal::btree_container
Definition: abseil-cpp/absl/container/internal/btree_container.h:37
absl::container_internal::btree_iterator::increment_slow
void increment_slow()
Definition: abseil-cpp/absl/container/internal/btree.h:1992
absl::container_internal::set_slot_policy::construct
static void construct(Alloc *alloc, slot_type *slot, slot_type *other)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:366
absl::container_internal::btree_node::rebalance_right_to_left
void rebalance_right_to_left(int to_move, btree_node *right, allocator_type *alloc)
Definition: abseil-cpp/absl/container/internal/btree.h:1770
absl::container_internal::btree_node::Alignment
constexpr static size_type Alignment()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:528
absl::container_internal::btree::erase_range
std::pair< size_type, iterator > erase_range(iterator begin, iterator end)
Definition: abseil-cpp/absl/container/internal/btree.h:2380
absl::container_internal::btree_iterator::operator++
btree_iterator & operator++()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1020
absl::container_internal::btree_node::MinimumOverhead
constexpr static size_type MinimumOverhead()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:548
absl::container_internal::btree::btree
btree(const btree &other)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1172
absl::container_internal::btree_iterator::slot_type
typename params_type::slot_type slot_type
Definition: abseil-cpp/absl/container/internal/btree.h:1049
absl::container_internal::btree_iterator::key_type
typename Node::key_type key_type
Definition: abseil-cpp/absl/container/internal/btree.h:1037
absl::container_internal::btree_iterator::key
const key_type & key() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1055
absl::container_internal::btree::height
size_type height() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1352
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::key_type
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::key_type key_type
Definition: abseil-cpp/absl/container/internal/btree.h:1283
absl::container_internal::map_params::value_type
typename super_type::value_type value_type
Definition: abseil-cpp/absl/container/btree_map.h:829
absl::enable_if_t
typename std::enable_if< B, T >::type enable_if_t
Definition: abseil-cpp/absl/meta/type_traits.h:631
absl::container_internal::btree::internal_upper_bound
iterator internal_upper_bound(const K &key) const
absl::container_internal::btree_node::size_type
typename Params::size_type size_type
Definition: abseil-cpp/absl/container/internal/btree.h:530
absl::container_internal::btree_node::LeafSize
constexpr static size_type LeafSize(const int slot_count=kNodeSlots)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:594
absl::container_internal::common_params::reference
value_type & reference
Definition: abseil-cpp/absl/container/internal/btree.h:403
absl::FormatConversionChar::s
@ s
absl::container_internal::btree::node_stats::leaf_nodes
size_type leaf_nodes
Definition: abseil-cpp/absl/container/internal/btree.h:1278
absl::container_internal::common_params::const_pointer
const value_type * const_pointer
Definition: abseil-cpp/absl/container/internal/btree.h:402
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
absl::container_internal::btree_node::linear_search_impl
SearchResult< int, false > linear_search_impl(const K &k, int s, const int e, const Compare &comp, std::false_type) const
Definition: abseil-cpp/absl/container/internal/btree.h:829
absl::container_internal::btree_map_container
Definition: abseil-cpp/absl/container/internal/btree_container.h:397
absl::container_internal::SearchResult< V, false >::SearchResult
SearchResult(V value)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:438
absl::container_internal::btree_node::clear_child
void clear_child(int i)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:679
absl::container_internal::btree_iterator::pointer
Pointer pointer
Definition: abseil-cpp/absl/container/internal/btree.h:1060
absl::allocator_traits
Definition: third_party/abseil-cpp/absl/memory/memory.h:427
absl::container_internal::common_params::difference_type
ptrdiff_t difference_type
Definition: abseil-cpp/absl/container/internal/btree.h:395
absl::container_internal::common_params::can_have_multiple_equivalent_keys
constexpr static bool can_have_multiple_equivalent_keys()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:250
absl::container_internal::btree_iterator::const_pointer
typename params_type::const_pointer const_pointer
Definition: abseil-cpp/absl/container/internal/btree.h:1047
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
absl::container_internal::btree_iterator::operator==
bool operator==(const const_iterator &other) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1001
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
absl::container_internal::map_params::super_type
typename map_params::common_params super_type
Definition: abseil-cpp/absl/container/btree_map.h:823
absl::allocator_traits::construct
static void construct(Alloc &a, T *p, Args &&... args)
Definition: third_party/abseil-cpp/absl/memory/memory.h:539
iterator
const typedef MCPhysReg * iterator
Definition: MCRegisterInfo.h:27
setup.k
k
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
absl::container_internal::btree::allocate
node_type * allocate(const size_type size)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1442
absl::container_internal::common_params::const_reference
const value_type & const_reference
Definition: abseil-cpp/absl/container/internal/btree.h:404
absl::container_internal::btree_node::rebalance_left_to_right
void rebalance_left_to_right(int to_move, btree_node *right, allocator_type *alloc)
Definition: abseil-cpp/absl/container/internal/btree.h:1810
absl::container_internal::common_params::kNodeValueSpace
@ kNodeValueSpace
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:264
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::value_type
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::value_type value_type
Definition: abseil-cpp/absl/container/internal/btree.h:1284
absl::container_internal::btree_node::parent
btree_node * parent() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:660
absl::container_internal::StringBtreeDefaultLess::operator()
absl::weak_ordering operator()(const absl::Cord &lhs, absl::string_view rhs) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:102
absl::container_internal::btree_node::upper_bound
int upper_bound(const K &k, const key_compare &comp) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:701
absl::container_internal::btree::insert_hint_multi
iterator insert_hint_multi(iterator position, ValueType &&v)
absl::container_internal::has_linear_node_search_preference
Definition: abseil-cpp/absl/container/internal/btree.h:319
absl::container_internal::btree_node::slot
slot_type * slot(int i)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:617
absl::container_internal::btree_iterator::params_type
typename Node::params_type params_type
Definition: abseil-cpp/absl/container/internal/btree.h:1039
absl::container_internal::btree::EmptyNodeType::position
field_type position
Definition: abseil-cpp/absl/container/internal/btree.h:1234
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::field_type
typename node_type::field_type field_type
Definition: abseil-cpp/absl/container/internal/btree.h:1224
ABSL_HARDENING_ASSERT
#define ABSL_HARDENING_ASSERT(expr)
Definition: abseil-cpp/absl/base/macros.h:134
absl::container_internal::btree_node::finish
field_type finish() const
Definition: abseil-cpp/absl/container/internal/btree.h:725
absl::container_internal::key_compare_to_adapter::type
Compare type
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:152
T
#define T(upbtypeconst, upbtype, ctype, default_value)
absl::container_internal::map_params::value_compare::operator()
auto operator()(const T &left, const U &right) const -> decltype(std::declval< key_compare >()(left.first, right.first))
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:327
absl::container_internal::btree::internal_lower_bound
SearchResult< iterator, is_key_compare_to::value > internal_lower_bound(const K &key) const
absl::container_internal::btree::rbegin
const_reverse_iterator rbegin() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1211
absl::container_internal::btree_node::InternalSize
constexpr static size_type InternalSize()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:597
absl::container_internal::common_params::move
static void move(Alloc *alloc, slot_type *src, slot_type *dest)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:300
absl::container_internal::btree_iterator::const_reference
typename params_type::const_reference const_reference
Definition: abseil-cpp/absl/container/internal/btree.h:1048
absl::container_internal::btree::node_stats::node_stats
node_stats(size_type l, size_type i)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1114
absl::container_internal::btree::leftmost
node_type * leftmost()
Definition: abseil-cpp/absl/container/internal/btree.h:1590
absl::container_internal::set_slot_policy::mutable_value_type
Key mutable_value_type
Definition: abseil-cpp/absl/container/btree_set.h:738
absl::container_internal::btree_node::count
field_type count() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:646
absl::container_internal::btree_iterator::value_type
typename params_type::value_type value_type
Definition: abseil-cpp/absl/container/internal/btree.h:1059
absl::container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, false >::value_compare
typename set_params::common_params::key_compare value_compare
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:395
absl::container_internal::btree::btree
btree(btree &&other, const allocator_type &alloc)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1183
absl::container_internal::btree_iterator::node_type
Node node_type
Definition: abseil-cpp/absl/container/internal/btree.h:1042
absl::container_internal::SearchResult< V, false >::HasMatch
static constexpr bool HasMatch()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:443
absl::container_internal::btree_node
Definition: abseil-cpp/absl/container/internal/btree.h:514
absl::container_internal::btree_node::make_root
void make_root()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:665
absl::container_internal::btree::empty
bool empty() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1349
absl::compare_internal::compare_result_as_less_than
constexpr bool compare_result_as_less_than(const Bool r)
Definition: abseil-cpp/absl/types/compare.h:549
absl::container_internal::SearchResult
Definition: abseil-cpp/absl/container/internal/btree.h:487
absl::container_internal::btree_node::params_type
Params params_type
Definition: abseil-cpp/absl/container/internal/btree.h:522
absl::container_internal::btree_node::max_count
field_type max_count() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:650
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
absl::container_internal::common_params::construct
static void construct(Alloc *alloc, slot_type *slot, Args &&... args)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:284
absl::container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true >
absl::container_internal::btree_node::reference
typename Params::reference reference
Definition: abseil-cpp/absl/container/internal/btree.h:527
absl::compare_internal::compare_result_as_ordering
constexpr absl::weak_ordering compare_result_as_ordering(const Int c)
Definition: abseil-cpp/absl/types/compare.h:565
absl::container_internal::btree_node::init_leaf
void init_leaf(btree_node *parent, int max_count)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:835
absl::container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, false >::slot_type
typename set_params::common_params::slot_type slot_type
Definition: abseil-cpp/absl/container/btree_set.h:778
absl::container_internal::btree_iterator::operator--
btree_iterator operator--(int)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1033
absl::container_internal::btree::fullness
double fullness() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1404
absl::container_internal::map_params::value_compare
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:322
absl::container_internal::btree::EmptyNodeType::max_count
field_type max_count
Definition: abseil-cpp/absl/container/internal/btree.h:1239
absl::container_internal::btree::lower_bound
iterator lower_bound(const K &key)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1221
absl::container_internal::btree::node_stats::size_type
typename Params::size_type size_type
Definition: abseil-cpp/absl/container/internal/btree.h:1268
absl::container_internal::common_params::is_key_compare_to
btree_is_key_compare_to< key_compare, Key > is_key_compare_to
Definition: abseil-cpp/absl/container/internal/btree.h:390
absl::container_internal::btree::begin
const_iterator begin() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1205
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::pointer
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::pointer pointer
Definition: abseil-cpp/absl/container/internal/btree.h:1293
start
static uint64_t start
Definition: benchmark-pound.c:74
absl::container_internal::common_params::init_type
typename slot_policy::mutable_value_type init_type
Definition: abseil-cpp/absl/container/internal/btree.h:400
absl::FormatConversionChar::e
@ e
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::container_internal::btree::node_stats
Definition: abseil-cpp/absl/container/internal/btree.h:1267
absl::container_internal::btree_iterator::const_iterator
btree_iterator< const_node, const_reference, const_pointer > const_iterator
Definition: abseil-cpp/absl/container/internal/btree.h:1054
absl::container_internal::common_params::value_type
typename slot_policy::value_type value_type
Definition: abseil-cpp/absl/container/internal/btree.h:399
absl::container_internal::btree::compare_keys
bool compare_keys(const K1 &a, const K2 &b) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1337
absl::container_internal::common_params::node_count_type
absl::conditional_t<(kNodeSlotSpace/sizeof(slot_type) >(std::numeric_limits< uint8_t >::max)()), uint16_t, uint8_t > node_count_type
Definition: abseil-cpp/absl/container/internal/btree.h:442
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
absl::container_internal::btree_iterator::position
int position
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1063
absl::container_internal::btree_node::leaf
bool leaf() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:630
absl::container_internal::btree_node::value_type
typename Params::value_type value_type
Definition: abseil-cpp/absl/container/internal/btree.h:524
absl::container_internal::btree::insert_hint_unique
std::pair< iterator, bool > insert_hint_unique(iterator position, const K &key, Args &&... args)
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
absl::container_internal::Layout
Definition: abseil-cpp/absl/container/internal/layout.h:684
hpack_encoder_fixtures::Args
Args({0, 16384})
absl::container_internal::set_slot_policy::swap
static void swap(Alloc *, slot_type *a, slot_type *b)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:376
swap
#define swap(a, b)
Definition: qsort.h:111
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::is_key_compare_to
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::is_key_compare_to is_key_compare_to
Definition: abseil-cpp/absl/container/internal/btree.h:1223
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
root
RefCountedPtr< grpc_tls_certificate_provider > root
Definition: xds_server_config_fetcher.cc:223
absl::container_internal::btree_node::set_parent
void set_parent(btree_node *p)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:615
absl::container_internal::IsTransparent
Definition: abseil-cpp/absl/container/internal/common.h:29
absl::container_internal::btree::internal_last
static IterType internal_last(IterType iter)
Definition: abseil-cpp/absl/container/internal/btree.h:2642
absl::container_internal::btree_node::value_init
void value_init(const field_type i, allocator_type *alloc, Args &&... args)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:863
absl::container_internal::btree::kMinNodeValues
@ kMinNodeValues
Definition: abseil-cpp/absl/container/internal/btree.h:1264
absl::container_internal::btree_node::child
btree_node * child(int i) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:676
absl::container_internal::btree_node::const_pointer
typename Params::const_pointer const_pointer
Definition: abseil-cpp/absl/container/internal/btree.h:526
absl::container_internal::map_params::key_compare
typename super_type::key_compare key_compare
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:320
absl::container_internal::btree_iterator::is_map_container
typename params_type::is_map_container is_map_container
Definition: abseil-cpp/absl/container/internal/btree.h:1040
absl::container_internal::upper_bound_adapter
Definition: abseil-cpp/absl/container/internal/btree.h:472
absl::container_internal::btree::leftmost
const node_type * leftmost() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1430
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::const_reference
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::const_reference const_reference
Definition: abseil-cpp/absl/container/internal/btree.h:1292
absl::container_internal::btree_iterator::difference_type
typename Node::difference_type difference_type
Definition: abseil-cpp/absl/container/internal/btree.h:1058
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
absl::container_internal::btree::root_
node_type * root_
Definition: abseil-cpp/absl/container/internal/btree.h:1706
absl::container_internal::btree::rebalance_or_split
void rebalance_or_split(iterator *iter)
Definition: abseil-cpp/absl/container/internal/btree.h:2461
absl::container_internal::btree::static_assert_validation
constexpr static bool static_assert_validation()
Definition: abseil-cpp/absl/container/internal/btree.h:2063
absl::swap
void swap(btree_map< K, V, C, A > &x, btree_map< K, V, C, A > &y)
Definition: abseil-cpp/absl/container/btree_map.h:474
absl::container_internal::set_params::key
static const Key & key(slot_type *slot)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:401
absl::container_internal::btree_node::kTargetNodeSize
@ kTargetNodeSize
Definition: abseil-cpp/absl/container/internal/btree.h:638
absl::container_internal::btree::equal_range
std::pair< iterator, iterator > equal_range(const K &key)
absl::container_internal::btree_iterator::operator++
btree_iterator operator++(int)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1028
gen_stats_data.stats
list stats
Definition: gen_stats_data.py:58
absl::container_internal::btree_node::set_max_count
void set_max_count(field_type v)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:625
absl::container_internal::SearchResult::value
V value
Definition: abseil-cpp/absl/container/internal/btree.h:488
absl::container_internal::btree_node::set_child
void set_child(int i, btree_node *c)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:682
absl::container_internal::btree::rend
reverse_iterator rend()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1214
absl::container_internal::btree::new_leaf_root_node
node_type * new_leaf_root_node(const int max_count)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1459
absl::container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, false >::value_type
Key value_type
Definition: abseil-cpp/absl/container/btree_set.h:777
absl::container_internal::btree::max_size
size_type max_size() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1348
absl::container_internal::BtreeNodePeer
Definition: abseil-cpp/absl/container/btree_test.cc:1192
absl::container_internal::btree_node::start
field_type start() const
Definition: abseil-cpp/absl/container/internal/btree.h:718
absl::container_internal::upper_bound_adapter::operator()
bool operator()(const K1 &a, const K2 &b) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:412
absl::container_internal::StringBtreeDefaultLess::is_transparent
void is_transparent
Definition: abseil-cpp/absl/container/internal/btree.h:98
absl::container_internal::StringBtreeDefaultLess
Definition: abseil-cpp/absl/container/internal/btree.h:97
absl::container_internal::btree::try_merge_or_rebalance
bool try_merge_or_rebalance(iterator *iter)
Definition: abseil-cpp/absl/container/internal/btree.h:2570
absl::container_internal::btree_node::binary_search
SearchResult< int, btree_is_key_compare_to< Compare, key_type >::value > binary_search(const K &k, const Compare &comp) const
Definition: abseil-cpp/absl/container/internal/btree.h:821
absl::container_internal::common_params::destroy
static void destroy(Alloc *alloc, slot_type *slot)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:290
absl::container_internal::btree_node::binary_search_impl
SearchResult< int, false > binary_search_impl(const K &k, int s, int e, const Compare &comp, std::false_type) const
Definition: abseil-cpp/absl/container/internal/btree.h:862
absl::inlined_vector_internal::Pointer
typename AllocatorTraits< A >::pointer Pointer
Definition: abseil-cpp/absl/container/internal/inlined_vector.h:52
absl::container_internal::btree_iterator::increment
void increment()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:981
absl::container_internal::btree_iterator::operator==
bool operator==(const iterator &other) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:998
absl::equal
bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, InputIter2 last2, Pred &&pred)
Definition: abseil-cpp/absl/algorithm/algorithm.h:104
absl::compare_internal::value_type
int8_t value_type
Definition: abseil-cpp/absl/types/compare.h:45
absl::container_internal::btree::average_bytes_per_value
static double average_bytes_per_value()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1391
std::swap
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:1226
absl::container_internal::btree::internal_find
iterator internal_find(const K &key) const
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::value_compare
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::value_compare value_compare
Definition: abseil-cpp/absl/container/internal/btree.h:1289
absl::container_internal::btree::swap
void swap(btree &other)
Definition: abseil-cpp/absl/container/internal/btree.h:2432
googletest-filter-unittest.child
child
Definition: bloaty/third_party/googletest/googletest/test/googletest-filter-unittest.py:62
absl::container_internal::btree_node::layout_type
absl::container_internal::Layout< btree_node *, uint32_t, field_type, slot_type, btree_node * > layout_type
Definition: abseil-cpp/absl/container/internal/btree.h:611
absl::container_internal::btree::get_allocator
allocator_type get_allocator() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1419
absl::flags_internal::Alloc
void * Alloc(FlagOpFn op)
Definition: abseil-cpp/absl/flags/internal/flag.h:102
absl::container_internal::map_params::key
static auto key(const V &value) -> decltype(value.first)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:335
absl::container_internal::btree::~btree
~btree()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1193
absl::container_internal::SearchResult::HasMatch
static constexpr bool HasMatch()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:428
absl::container_internal::map_params::is_map_container
std::true_type is_map_container
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:332
absl::container_internal::btree_node::value
reference value(int i)
Definition: abseil-cpp/absl/container/internal/btree.h:777
absl::container_internal::btree_node::const_reference
typename Params::const_reference const_reference
Definition: abseil-cpp/absl/container/internal/btree.h:528
absl::container_internal::btree_node::binary_search_impl
SearchResult< int, true > binary_search_impl(const K &k, int s, int e, const CompareTo &comp, std::true_type) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:774
absl::container_internal::btree_node::value
const_reference value(int i) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:673
absl::container_internal::btree_node::start_child
btree_node * start_child() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:677
absl::container_internal::btree_node::is_key_compare_to
typename Params::is_key_compare_to is_key_compare_to
Definition: abseil-cpp/absl/container/internal/btree.h:515
absl::container_internal::common_params::slot_policy
SlotPolicy slot_policy
Definition: abseil-cpp/absl/container/internal/btree.h:397
absl::container_internal::btree_node::mutable_child
btree_node *& mutable_child(int i)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:678
tests.google.protobuf.internal.message_test.cmp
cmp
Definition: bloaty/third_party/protobuf/python/compatibility_tests/v2.5.0/tests/google/protobuf/internal/message_test.py:61
absl::container_internal::common_params::slot_type
typename slot_policy::slot_type slot_type
Definition: abseil-cpp/absl/container/internal/btree.h:398
absl::container_internal::btree::insert_multi
iterator insert_multi(const key_type &key, ValueType &&v)
absl::container_internal::btree::node_stats::operator+=
node_stats & operator+=(const node_stats &other)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1116
absl::container_internal::btree_node::btree_node
btree_node()=default
min
#define min(a, b)
Definition: qsort.h:83
absl::container_internal::CompressedTuple
Definition: abseil-cpp/absl/container/internal/compressed_tuple.h:55
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
transfer
static std::function< void(void *, Slot *, Slot *)> transfer
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:58
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::init_type
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::init_type init_type
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1070
absl::container_internal::btree::EmptyNode
static node_type * EmptyNode()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1093
absl::container_internal::btree_node::linear_search
SearchResult< int, btree_is_key_compare_to< Compare, key_type >::value > linear_search(const K &k, const Compare &comp) const
Definition: abseil-cpp/absl/container/internal/btree.h:814
absl::container_internal::StringBtreeDefaultGreater::operator()
absl::weak_ordering operator()(const absl::Cord &lhs, absl::string_view rhs) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:129
absl::container_internal::common_params::element
static value_type & element(slot_type *slot)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:277
absl::container_internal::btree::begin
iterator begin()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1204
absl::container_internal::set_slot_policy::move
static void move(Alloc *, slot_type *src, slot_type *dest)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:382
absl::container_internal::btree_node::SizeWithNSlots
constexpr static size_type SizeWithNSlots(size_type n)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:540
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
tests.qps.qps_worker.dest
dest
Definition: qps_worker.py:45
Json::ValueType
ValueType
Type of the value held by a Value object.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:463
absl::container_internal::btree::size_type
typename Params::size_type size_type
Definition: abseil-cpp/absl/container/internal/btree.h:1285
absl::container_internal::btree::erase
iterator erase(iterator iter)
Definition: abseil-cpp/absl/container/internal/btree.h:2296
absl::container_internal::btree::internal_end
const_iterator internal_end(const_iterator iter) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1487
absl::container_internal::btree_iterator::reference
Reference reference
Definition: abseil-cpp/absl/container/internal/btree.h:1061
absl::container_internal::btree_node::start_slot
slot_type * start_slot()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:618
absl::container_internal::btree::internal_emplace
iterator internal_emplace(iterator iter, Args &&... args)
absl::container_internal::StringBtreeDefaultGreater::StringBtreeDefaultGreater
StringBtreeDefaultGreater(std::greater< absl::Cord >)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:124
absl::container_internal::common_params::key_compare
absl::conditional_t<!compare_has_valid_result_type< Compare, Key >(), Compare, typename key_compare_adapter< Compare, Key >::type > key_compare
Definition: abseil-cpp/absl/container/internal/btree.h:373
absl::container_internal::btree_node::NodeTargetSlots
constexpr static size_type NodeTargetSlots(const int begin, const int end)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:554
absl::container_internal::btree_iterator
Definition: abseil-cpp/absl/container/internal/btree.h:1036
google_benchmark.example.empty
def empty(state)
Definition: example.py:31
absl::container_internal::node_handle
Definition: abseil-cpp/absl/container/internal/common.h:120
absl::container_internal::btree_node::remove_values
void remove_values(field_type i, field_type to_erase, allocator_type *alloc)
Definition: abseil-cpp/absl/container/internal/btree.h:1746
absl::container_internal::btree_node::linear_search_impl
SearchResult< int, true > linear_search_impl(const K &k, int s, const int e, const Compare &comp, std::true_type) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:739
absl::container_internal::SanitizerPoisonMemoryRegion
void SanitizerPoisonMemoryRegion(const void *m, size_t s)
Definition: abseil-cpp/absl/container/internal/container_memory.h:219
absl::container_internal::StringBtreeDefaultGreater::StringBtreeDefaultGreater
StringBtreeDefaultGreater()=default
absl::container_internal::btree::size
size_type size() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1347
absl::container_internal::set_slot_policy::element
static value_type & element(slot_type *slot)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:356
absl::container_internal::common_params::key_type
Key key_type
Definition: abseil-cpp/absl/container/internal/btree.h:393
absl::container_internal::btree_iterator::btree_iterator
btree_iterator(Node *n)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:953
absl::container_internal::btree_iterator::normal_pointer
typename params_type::pointer normal_pointer
Definition: abseil-cpp/absl/container/internal/btree.h:1045
absl::container_internal::map_params::key
static const Key & key(slot_type *s)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:339
absl::container_internal::btree::bytes_used
size_type bytes_used() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1379
absl::container_internal::btree::EmptyNodeType::EmptyNodeType
constexpr EmptyNodeType(node_type *p)
Definition: abseil-cpp/absl/container/internal/btree.h:1245
absl::container_internal::set_params::key
static const Key & key(const slot_type *slot)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:400
value
const char * value
Definition: hpack_parser_table.cc:165
absl::container_internal::btree::rightmost_
node_type * rightmost_
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1554
absl::container_internal::SearchResult< V, false >::SearchResult
SearchResult(V value, MatchKind)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:439
absl::container_internal::btree::root_
absl::container_internal::CompressedTuple< key_compare, allocator_type, node_type * > root_
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1550
absl::container_internal::btree::leaf_nodes
size_type leaf_nodes() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1369
absl::container_internal::btree::internal_end
iterator internal_end(iterator iter)
Definition: abseil-cpp/absl/container/internal/btree.h:1645
absl::void_t
typename type_traits_internal::VoidTImpl< Ts... >::type void_t
Definition: abseil-cpp/absl/meta/type_traits.h:218
absl::container_internal::btree_iterator::btree_iterator
btree_iterator(const btree_iterator< N, R, P > other)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:964
absl::container_internal::btree_node::NodeTargetSlots
constexpr static size_type NodeTargetSlots(const size_type begin, const size_type end)
Definition: abseil-cpp/absl/container/internal/btree.h:628
absl::container_internal::btree::try_shrink
void try_shrink()
Definition: abseil-cpp/absl/container/internal/btree.h:2623
absl::container_internal::btree_iterator::node
Node * node
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1059
absl::container_internal::btree_node::key_compare
typename Params::key_compare key_compare
Definition: abseil-cpp/absl/container/internal/btree.h:529
construct
static std::function< void(void *, Slot *, Slot)> construct
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:41
absl::container_internal::btree_iterator::iterator
btree_iterator< normal_node, normal_reference, normal_pointer > iterator
Definition: abseil-cpp/absl/container/internal/btree.h:1052
absl::container_internal::StringBtreeDefaultLess::StringBtreeDefaultLess
StringBtreeDefaultLess(std::less< absl::Cord >)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:97
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::const_iterator
typename iterator::const_iterator const_iterator
Definition: abseil-cpp/absl/container/internal/btree.h:1297
key
const char * key
Definition: hpack_parser_table.cc:164
absl::container_internal::map_params::mapped_type
Data mapped_type
Definition: abseil-cpp/absl/container/btree_map.h:824
absl::container_internal::btree::overhead
double overhead() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1412
N
#define N
Definition: sync_test.cc:37
absl::container_internal::btree::EmptyNodeType::start
field_type start
Definition: abseil-cpp/absl/container/internal/btree.h:1235
size_
size_t size_
Definition: memory_allocator.cc:56
absl::container_internal::btree_iterator::normal_reference
typename params_type::reference normal_reference
Definition: abseil-cpp/absl/container/internal/btree.h:1046
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
absl::container_internal::SearchResult::match
MatchKind match
Definition: abseil-cpp/absl/container/internal/btree.h:489
absl::container_internal::btree_iterator::slot
slot_type * slot()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1056
absl::container_internal::upper_bound_adapter::upper_bound_adapter
upper_bound_adapter(const Compare &c)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:410
absl::container_internal::btree::nodes
size_type nodes() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1373
absl::container_internal::btree_node::clear_and_delete
static void clear_and_delete(btree_node *node, allocator_type *alloc)
Definition: abseil-cpp/absl/container/internal/btree.h:1923
absl::container_internal::StringBtreeDefaultLess::operator()
absl::weak_ordering operator()(const absl::Cord &lhs, const absl::Cord &rhs) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:98
absl::container_internal::btree::rbegin
reverse_iterator rbegin()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1210
absl::container_internal::btree::root
const node_type * root() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1424
absl::container_internal::btree::EmptyNodeType::finish
field_type finish
Definition: abseil-cpp/absl/container/internal/btree.h:1236
absl::container_internal::btree_iterator::iterator_category
std::bidirectional_iterator_tag iterator_category
Definition: abseil-cpp/absl/container/internal/btree.h:1062
absl::inlined_vector_internal::Reference
ValueType< A > & Reference
Definition: abseil-cpp/absl/container/internal/inlined_vector.h:60
absl::container_internal::btree_iterator::btree_iterator
btree_iterator()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:952
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
testing::Key
internal::KeyMatcher< M > Key(M inner_matcher)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:9141
absl::container_internal::btree_node::difference_type
typename Params::difference_type difference_type
Definition: abseil-cpp/absl/container/internal/btree.h:531
absl::string_view::compare
constexpr int compare(string_view x) const noexcept
Definition: abseil-cpp/absl/strings/string_view.h:413
absl::container_internal::btree_multiset_container
Definition: abseil-cpp/absl/container/internal/btree_container.h:542
absl::container_internal::btree::insert_iterator_unique
void insert_iterator_unique(InputIterator b, InputIterator e, int)
Definition: abseil-cpp/absl/container/internal/btree.h:2185
next
AllocList * next[kMaxLevel]
Definition: abseil-cpp/absl/base/internal/low_level_alloc.cc:100
absl::container_internal::btree_node::value_destroy
void value_destroy(const field_type i, allocator_type *alloc)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:867
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
absl::container_internal::btree::mutable_key_comp
key_compare * mutable_key_comp() noexcept
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1426
absl::container_internal::common_params::transfer
static void transfer(Alloc *alloc, slot_type *new_slot, slot_type *old_slot)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:293
absl::container_internal::btree_node::transfer
static void transfer(slot_type *dest, slot_type *src, allocator_type *alloc)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:879
absl::container_internal::btree_node::transfer_n_backward
void transfer_n_backward(const size_type n, const size_type dest_i, const size_type src_i, btree_node *src_node, allocator_type *alloc)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:905
absl::container_internal::btree_node::allocator_type
typename Params::allocator_type allocator_type
Definition: abseil-cpp/absl/container/internal/btree.h:517
absl::container_internal::btree::upper_bound
const_iterator upper_bound(const K &key) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1240
field_type
zend_class_entry * field_type
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/message.c:2030
absl::container_internal::MatchKind
MatchKind
Definition: abseil-cpp/absl/container/internal/btree.h:484
absl::container_internal::map_params::key
static const Key & key(const slot_type *s)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:338
absl::container_internal::btree_node::deallocate
static void deallocate(const size_type size, btree_node *node, allocator_type *alloc)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:853
absl::container_internal::btree_iterator::const_node
const Node const_node
Definition: abseil-cpp/absl/container/internal/btree.h:1044
absl::container_internal::SearchResult< V, false >::SearchResult
SearchResult()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:437
absl::container_internal::btree_node::InternalLayout
constexpr static layout_type InternalLayout()
Definition: abseil-cpp/absl/container/internal/btree.h:665
absl::container_internal::btree::find
iterator find(const K &key)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1319
absl::container_internal::btree::maybe_move_from_iterator
value_type && maybe_move_from_iterator(iterator it)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1152
absl::container_internal::StringBtreeDefaultGreater::is_transparent
void is_transparent
Definition: abseil-cpp/absl/container/internal/btree.h:131
absl::container_internal::btree_set_container
Definition: abseil-cpp/absl/container/internal/btree_container.h:238
absl::container_internal::set_slot_policy::value_type
Key value_type
Definition: abseil-cpp/absl/container/btree_set.h:737
absl::container_internal::common_params::construct
static void construct(Alloc *alloc, slot_type *slot, slot_type *other)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:287
absl::container_internal::map_params::slot_policy
typename super_type::slot_policy slot_policy
Definition: abseil-cpp/absl/container/btree_map.h:827
absl::container_internal::btree::clear
void clear()
Definition: abseil-cpp/absl/container/internal/btree.h:2423
absl::weak_ordering
Definition: abseil-cpp/absl/types/compare.h:347
absl::container_internal::btree::copy_or_move_values_in_order
void copy_or_move_values_in_order(Btree &other)
Definition: abseil-cpp/absl/container/internal/btree.h:2043
absl::container_internal::btree_node::split
void split(int insert_position, btree_node *dest, allocator_type *alloc)
Definition: abseil-cpp/absl/container/internal/btree.h:1857
absl::container_internal::btree_iterator::decrement
void decrement()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:989
absl::container_internal::StringBtreeDefaultLess::StringBtreeDefaultLess
StringBtreeDefaultLess(std::less< string_view >)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:91
absl::container_internal::btree_iterator::decrement_slow
void decrement_slow()
Definition: abseil-cpp/absl/container/internal/btree.h:2016
absl::container_internal::btree
Definition: abseil-cpp/absl/container/internal/btree.h:1221
absl::container_internal::SearchResult::IsEq
bool IsEq() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:429
absl::container_internal::btree_node::operator=
btree_node & operator=(btree_node const &)=delete
absl::container_internal::btree::mutable_root
node_type *& mutable_root() noexcept
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1425
absl::container_internal::btree_iterator::operator--
btree_iterator & operator--()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1024
absl::container_internal::Alloc
Definition: abseil-cpp/absl/container/internal/hash_policy_testing.h:118
absl::strings_internal::Compare
int Compare(const BigUnsigned< N > &lhs, const BigUnsigned< M > &rhs)
Definition: abseil-cpp/absl/strings/internal/charconv_bigint.h:353
absl::container_internal::SanitizerPoisonObject
void SanitizerPoisonObject(const T *object)
Definition: abseil-cpp/absl/container/internal/container_memory.h:242
absl::container_internal::set_slot_policy::construct
static void construct(Alloc *alloc, slot_type *slot, Args &&... args)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:360
absl::container_internal::map_params::init_type
typename super_type::init_type init_type
Definition: abseil-cpp/absl/container/btree_map.h:830
absl::container_internal::btree::merge_nodes
void merge_nodes(node_type *left, node_type *right)
Definition: abseil-cpp/absl/container/internal/btree.h:2564
absl::container_internal::map_params::slot_type
typename super_type::slot_type slot_type
Definition: abseil-cpp/absl/container/btree_map.h:828
absl::container_internal::btree::btree
btree(const key_compare &comp, const allocator_type &alloc)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1169
absl::container_internal::btree::internal_locate
SearchResult< iterator, is_key_compare_to::value > internal_locate(const K &key) const
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::slot_type
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::slot_type slot_type
Definition: abseil-cpp/absl/container/internal/btree.h:1304
absl::container_internal::common_params::element
static const value_type & element(const slot_type *slot)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:280
absl::container_internal::common_params::size_type
size_t size_type
Definition: abseil-cpp/absl/container/internal/btree.h:394
absl::container_internal::btree_node::transfer
void transfer(const size_type dest_i, const size_type src_i, btree_node *src_node, allocator_type *alloc)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:886
absl::container_internal::btree::internal_verify
int internal_verify(const node_type *node, const key_type *lo, const key_type *hi) const
Definition: abseil-cpp/absl/container/internal/btree.h:2779
absl::container_internal::StringBtreeDefaultGreater::operator()
absl::weak_ordering operator()(absl::string_view lhs, absl::string_view rhs) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:120
absl::container_internal::btree::btree
btree(const btree &other, const allocator_type &alloc)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1173
iter
Definition: test_winkernel.cpp:47
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
absl::container_internal::btree::equal_range
std::pair< const_iterator, const_iterator > equal_range(const K &key) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1250
absl::container_internal::btree_node::use_linear_search
std::integral_constant< bool, has_linear_node_search_preference< original_key_compare >::value ? prefers_linear_node_search< original_key_compare >::value :has_linear_node_search_preference< key_type >::value ? prefers_linear_node_search< key_type >::value :std::is_arithmetic< key_type >::value &&(std::is_same< std::less< key_type >, original_key_compare >::value||std::is_same< std::greater< key_type >, original_key_compare >::value)> use_linear_search
Definition: abseil-cpp/absl/container/internal/btree.h:549
absl::container_internal::btree_is_key_compare_to
std::is_convertible< compare_result_t< Compare, T, T >, absl::weak_ordering > btree_is_key_compare_to
Definition: abseil-cpp/absl/container/internal/btree.h:95
absl::container_internal::btree::end
const_iterator end() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1207
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
absl::container_internal::base_checker
Definition: abseil-cpp/absl/container/btree_test.cc:81
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
absl::container_internal::StringBtreeDefaultGreater::operator()
absl::weak_ordering operator()(const absl::Cord &lhs, const absl::Cord &rhs) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:125
value_init
void value_init(TSRMLS_D)
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: abseil-cpp/absl/container/internal/btree.h:1298
setup.template
template
Definition: setup.py:47
absl::container_internal::btree::insert_iterator_multi
void insert_iterator_multi(InputIterator b, InputIterator e)
Definition: abseil-cpp/absl/container/internal/btree.h:2241
absl::container_internal::btree_iterator::operator->
pointer operator->() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1018
absl::container_internal::set_params::key
static const V & key(const V &value)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:399
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
key_type
upb_fieldtype_t key_type
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1071
absl::allocator_traits::destroy
static void destroy(Alloc &a, T *p)
Definition: third_party/abseil-cpp/absl/memory/memory.h:547
absl::container_internal::SearchResult< V, false >::IsEq
static constexpr bool IsEq()
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:444
absl::container_internal::btree::internal_stats
node_stats internal_stats(const node_type *node) const
Definition: abseil-cpp/absl/container/internal/btree.h:1691
absl::container_internal::btree::size_
size_type size_
Definition: abseil-cpp/absl/container/internal/btree.h:1716
absl::result_of_t
typename type_traits_internal::result_of< F >::type result_of_t
Definition: abseil-cpp/absl/meta/type_traits.h:658
absl::container_internal::map_params::value_compare::value_compare
value_compare(const key_compare &cmp)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:324
absl::container_internal::btree_node::~btree_node
~btree_node()=default
grpc_core::P
std::function< Poll< absl::StatusOr< T > >()> P
Definition: try_join_test.cc:27
absl::container_internal::btree_iterator::size_type
typename Node::size_type size_type
Definition: abseil-cpp/absl/container/internal/btree.h:1038
const_reference
const typedef T & const_reference
Definition: cxa_demangle.cpp:4831
absl::container_internal::map_params::value_compare::value_compare
value_compare()=default
absl::container_internal::btree::internal_nodes
size_type internal_nodes() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1370
absl::container_internal::SanitizerUnpoisonObject
void SanitizerUnpoisonObject(const T *object)
Definition: abseil-cpp/absl/container/internal/container_memory.h:247
absl::container_internal::StringBtreeDefaultLess::StringBtreeDefaultLess
StringBtreeDefaultLess(std::less< std::string >)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:90
absl::container_internal::btree::node_type
btree_node< Params > node_type
Definition: abseil-cpp/absl/container/internal/btree.h:1222
alloc
std::allocator< int > alloc
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:87
absl::container_internal::btree_node::LeafLayout
constexpr static layout_type LeafLayout(const int slot_count=kNodeSlots)
Definition: abseil-cpp/absl/container/internal/btree.h:657
destroy
static std::function< void(void *, Slot *)> destroy
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:42
absl::container_internal::MatchKind::kNe
@ kNe
absl::container_internal::btree_node::kMinNodeSlots
@ kMinNodeSlots
Definition: abseil-cpp/absl/container/internal/btree.h:646
absl::container_internal::btree_node::merge
void merge(btree_node *src, allocator_type *alloc)
Definition: abseil-cpp/absl/container/internal/btree.h:1896
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
absl::container_internal::common_params::pointer
value_type * pointer
Definition: abseil-cpp/absl/container/internal/btree.h:401
absl::exchange
T exchange(T &obj, U &&new_value)
Definition: abseil-cpp/absl/utility/utility.h:314
absl::container_internal::btree_node::field_type
typename Params::node_count_type field_type
Definition: abseil-cpp/absl/container/internal/btree.h:516
absl::container_internal::btree_node::emplace_value
void emplace_value(size_type i, allocator_type *alloc, Args &&... args)
Definition: abseil-cpp/absl/container/internal/btree.h:1723
absl::container_internal::common_params::swap
static void swap(Alloc *alloc, slot_type *a, slot_type *b)
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:297
absl::container_internal::btree_iterator::operator!=
bool operator!=(const iterator &other) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1004
absl::container_internal::btree::key_comp
const key_compare & key_comp() const noexcept
Definition: abseil-cpp/absl/container/internal/btree.h:1482
absl::container_internal::btree_iterator::normal_node
typename std::remove_const< Node >::type normal_node
Definition: abseil-cpp/absl/container/internal/btree.h:1043
absl::container_internal::btree_node::lower_bound
SearchResult< int, is_key_compare_to::value > lower_bound(const K &k, const key_compare &comp) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:694
root_
Node root_
Definition: bloaty/third_party/protobuf/src/google/protobuf/util/field_mask_util.cc:287
absl::container_internal::btree::rebalance_after_delete
iterator rebalance_after_delete(iterator iter)
Definition: abseil-cpp/absl/container/internal/btree.h:2339
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::allocator_type
typename container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > ::allocator_type allocator_type
Definition: abseil-cpp/absl/container/internal/btree.h:1290
absl::container_internal::btree::value_comp
value_compare value_comp() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1341
const_pointer
const typedef T * const_pointer
Definition: cxa_demangle.cpp:4833
absl::container_internal::prefers_linear_node_search
Definition: abseil-cpp/absl/container/internal/btree.h:321
absl::container_internal::btree_node::is_root
bool is_root() const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:664
absl::container_internal::btree< container_internal::set_params< Key, std::less< Key >, std::allocator< Key >, 256, true > >::iterator
typename btree_iterator< node_type, reference, pointer >::iterator iterator
Definition: abseil-cpp/absl/container/internal/btree.h:1296
absl::container_internal::btree::insert_unique
std::pair< iterator, bool > insert_unique(const K &key, Args &&... args)
absl::container_internal::btree::find
const_iterator find(const K &key) const
Definition: bloaty/third_party/abseil-cpp/absl/container/internal/btree.h:1323


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:49