@@ -21,6 +21,9 @@ template <typename T> struct DefaultCompareTo {
21
21
22
22
template <typename T> struct BPTreePolicy {
23
23
using KeyT = T;
24
+
25
+ // The three way comparator that should accept a query ( or key) on the left, and the key
26
+ // on the right.
24
27
using KeyCompareTo = DefaultCompareTo<T>;
25
28
};
26
29
@@ -89,16 +92,15 @@ template <typename T, typename Policy = BPTreePolicy<T>> class BPTree {
89
92
// / Should return false to stop iteration.
90
93
bool IterateReverse (uint32_t rank_start, uint32_t rank_end, std::function<bool (KeyT)> cb) const ;
91
94
92
- // / @brief Returns the path to the first item in the tree that is greater or equal to key .
95
+ // / @brief Returns the path to the first item in the tree for which comp(q, key) >= 0 .
93
96
// / @param item
94
97
// / @return the path if such item exists, empty path otherwise.
95
- // / @todo: to wrap the result into iterator to avoid the leakage of internal data structures.
96
- detail::BPTreePath<T> GEQ (KeyT key) const ;
98
+ template <typename Q> BPTreePath GEQ (Q&& query) const ;
97
99
98
- // / @brief Returns the path to the largest item in the tree that is less or equal to key .
100
+ // / @brief Returns the path to the largest item in the tree such that comp(q, key) <= 0 .
99
101
// / @param key
100
102
// / @return the path if such item exists, empty path otherwise.
101
- detail::BPTreePath<T> LEQ (KeyT key ) const ;
103
+ template < typename Q> BPTreePath LEQ (Q&& query ) const ;
102
104
103
105
// / @brief Deletes the element pointed by path.
104
106
// / @param path
@@ -122,10 +124,10 @@ template <typename T, typename Policy = BPTreePolicy<T>> class BPTree {
122
124
void IncreaseSubtreeCounts (const BPTreePath& path, unsigned depth, int32_t delta);
123
125
124
126
// Charts the path towards key. Returns true if key is found.
125
- // In that case path->Last().first->Key(path->Last().second) == key .
127
+ // In that case comp(q, path->Last().first->Key(path->Last().second)) == 0 .
126
128
// Fills the tree path not including the key itself. In case key was not found,
127
129
// returns the path to the item that is greater than the key.
128
- bool Locate (KeyT key , BPTreePath* path) const ;
130
+ template < typename Q> bool Locate (Q&& q , BPTreePath* path) const ;
129
131
130
132
// Sets the tree path to item at specified rank. Rank is 0-based and must be less than Size().
131
133
// returns the index of the key in the last node of the path.
@@ -243,12 +245,15 @@ std::optional<uint32_t> BPTree<T, Policy>::GetRank(KeyT item, bool reverse) cons
243
245
}
244
246
245
247
template <typename T, typename Policy>
246
- bool BPTree<T, Policy>::Locate(KeyT key, BPTreePath* path) const {
248
+ template <typename Q>
249
+ bool BPTree<T, Policy>::Locate(Q&& q, BPTreePath* path) const {
247
250
assert (root_);
248
251
BPTreeNode* node = root_;
249
252
typename Policy::KeyCompareTo cmp;
253
+ auto cmp_cb = [&](const KeyT& key) { return cmp (q, key); };
254
+
250
255
while (true ) {
251
- typename BPTreeNode::SearchResult res = node->BSearch (key, cmp );
256
+ typename BPTreeNode::SearchResult res = node->BSearch (cmp_cb );
252
257
path->Push (node, res.index );
253
258
if (res.found ) {
254
259
return true ;
@@ -486,10 +491,11 @@ void BPTree<T, Policy>::ToRank(uint32_t rank, BPTreePath* path) const {
486
491
}
487
492
488
493
template <typename T, typename Policy>
489
- detail::BPTreePath<T> BPTree<T, Policy>::GEQ(KeyT item) const {
494
+ template <typename Q>
495
+ auto BPTree<T, Policy>::GEQ(Q&& query) const -> BPTreePath {
490
496
BPTreePath path;
491
497
492
- bool res = Locate (item , &path);
498
+ bool res = Locate (query , &path);
493
499
494
500
// if we did not find the item and the path does not lead to any key in the node,
495
501
// adjust the path to point to the next key in the tree.
@@ -502,9 +508,10 @@ detail::BPTreePath<T> BPTree<T, Policy>::GEQ(KeyT item) const {
502
508
}
503
509
504
510
template <typename T, typename Policy>
505
- detail::BPTreePath<T> BPTree<T, Policy>::LEQ(KeyT item) const {
511
+ template <typename Q>
512
+ auto BPTree<T, Policy>::LEQ(Q&& query) const -> BPTreePath {
506
513
BPTreePath path;
507
- bool res = Locate (item , &path);
514
+ bool res = Locate (query , &path);
508
515
509
516
if (!res) { // fix the result in case the path leads to key greater than item.
510
517
path.Prev ();
0 commit comments