diff options
author | Abseil Team <absl-team@google.com> | 2020-10-23 12:31:49 -0700 |
---|---|---|
committer | Gennadiy Rozental <rogeeff@google.com> | 2020-10-23 15:52:35 -0400 |
commit | 1e3d25b2657228bd691ee938cfd37d487f48054b (patch) | |
tree | b85a416a407751b89c94ac67e41b2e9935db0283 /absl/container/internal/btree.h | |
parent | eb317a701b83bf9a4f2a035d75747a3d76a48324 (diff) | |
download | abseil-1e3d25b2657228bd691ee938cfd37d487f48054b.tar.gz abseil-1e3d25b2657228bd691ee938cfd37d487f48054b.tar.bz2 abseil-1e3d25b2657228bd691ee938cfd37d487f48054b.zip |
Export of internal Abseil changes
--
017c3924d21132085bc20c9be0ae469bfbf2c56c by Gennadiy Rozental <rogeeff@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 338723934
--
8b08c23d7b05232e283b1388cee3eb5bebc2d9c4 by Derek Mauro <dmauro@google.com>:
Add script to test GCC floor (the minimum version of GCC we support,
currently the GCC 5 series)
PiperOrigin-RevId: 338708581
--
afa440ac7c843126b4f99b89ebc071dda1d85a4d by Abseil Team <absl-team@google.com>:
Fix typo in documentation of StatusOr::value_or() ('of' -> 'if').
PiperOrigin-RevId: 338690089
--
97d5008865327fc36b942b96de0d0cacfb909df5 by Derek Mauro <dmauro@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 338568224
--
da5e09a7fedb3217329465d9206b7cbc6677176b by Abseil Team <absl-team@google.com>:
Add `absl_btree_prefer_linear_node_search`
Allow keys of `btree_set`, `btree_map`, `btree_multiset`, and `btree_multimap`
to opt-in to linear search (instead of binary search). Linear search was
used previously for arithmetic types with `key_compare` of `std::greater`
or `std::less`.
For example, this would be useful for key types that wrap an integer
and define their own cheap `operator<()`.
```
class K {
public:
using absl_btree_prefer_linear_node_search = std::true_type;
...
private:
friend bool operator<(K a, K b) { return a.k_ < b.k_; }
int k_;
};
absl::btree_map<K, V> m; // Uses linear search
assert((absl::btree_map<K, V>::testonly_uses_linear_node_search()));
```
PiperOrigin-RevId: 338476553
--
c56ead7ce6b0a5ad32e3a42904c686448a69451e by Gennadiy Rozental <rogeeff@google.com>:
Import of CCTZ from GitHub.
PiperOrigin-RevId: 338419417
GitOrigin-RevId: 017c3924d21132085bc20c9be0ae469bfbf2c56c
Change-Id: I1199f3ae917280a3ef20ccc6038abbe34d96ec0b
Diffstat (limited to 'absl/container/internal/btree.h')
-rw-r--r-- | absl/container/internal/btree.h | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h index cadbeab1..a82b5177 100644 --- a/absl/container/internal/btree.h +++ b/absl/container/internal/btree.h @@ -182,6 +182,38 @@ struct key_compare_to_adapter<std::greater<absl::Cord>> { using type = StringBtreeDefaultGreater; }; +// Detects an 'absl_btree_prefer_linear_node_search' member. This is +// a protocol used as an opt-in or opt-out of linear search. +// +// For example, this would be useful for key types that wrap an integer +// and define their own cheap operator<(). For example: +// +// class K { +// public: +// using absl_btree_prefer_linear_node_search = std::true_type; +// ... +// private: +// friend bool operator<(K a, K b) { return a.k_ < b.k_; } +// int k_; +// }; +// +// btree_map<K, V> m; // Uses linear search +// +// If T has the preference tag, then it has a preference. +// Btree will use the tag's truth value. +template <typename T, typename = void> +struct has_linear_node_search_preference : std::false_type {}; +template <typename T, typename = void> +struct prefers_linear_node_search : std::false_type {}; +template <typename T> +struct has_linear_node_search_preference< + T, absl::void_t<typename T::absl_btree_prefer_linear_node_search>> + : std::true_type {}; +template <typename T> +struct prefers_linear_node_search< + T, absl::void_t<typename T::absl_btree_prefer_linear_node_search>> + : T::absl_btree_prefer_linear_node_search {}; + template <typename Key, typename Compare, typename Alloc, int TargetNodeSize, bool Multi, typename SlotPolicy> struct common_params { @@ -424,15 +456,22 @@ class btree_node { using difference_type = typename Params::difference_type; // Btree decides whether to use linear node search as follows: + // - If the comparator expresses a preference, use that. + // - If the key expresses a preference, use that. // - If the key is arithmetic and the comparator is std::less or // std::greater, choose linear. // - Otherwise, choose binary. // TODO(ezb): Might make sense to add condition(s) based on node-size. using use_linear_search = std::integral_constant< bool, - std::is_arithmetic<key_type>::value && - (std::is_same<std::less<key_type>, key_compare>::value || - std::is_same<std::greater<key_type>, key_compare>::value)>; + has_linear_node_search_preference<key_compare>::value + ? prefers_linear_node_search<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>, key_compare>::value || + std::is_same<std::greater<key_type>, + key_compare>::value)>; // This class is organized by gtl::Layout as if it had the following // structure: |