Skip to content

Commit dd3aaf9

Browse files
committed
MB-40531: Allow VBucketVisitors to specify vbucket order
In a future patch, the item pager will specify a specific order to visit vbuckets, to avoid eviction favouring early vbucket IDs. To support that, vb visitors can now define an order the vbuckets will be visited in. Change-Id: Ib66685844c4609442f5d727f79c77d26cca713b3 Reviewed-on: http://review.couchbase.org/c/kv_engine/+/136627 Well-Formed: Build Bot <[email protected]> Reviewed-by: Paolo Cocchi <[email protected]> Tested-by: James Harrison <[email protected]>
1 parent 3999521 commit dd3aaf9

File tree

5 files changed

+106
-30
lines changed

5 files changed

+106
-30
lines changed

engines/ep/src/comparators.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* Copyright 2020 Couchbase, Inc
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#pragma once
19+
20+
namespace cb {
21+
/**
22+
* Function object which returns true if lhs > rhs.
23+
* Equivalent to std::greater, but without having to pull in all of <functional>
24+
*/
25+
template <typename T>
26+
struct greater {
27+
constexpr bool operator()(const T& lhs, const T& rhs) const {
28+
return lhs > rhs;
29+
}
30+
};
31+
32+
/**
33+
* Function object which returns true if lhs >= rhs.
34+
* Equivalent to std::greater_equal, but without having to pull in all of
35+
* <functional>
36+
*/
37+
template <typename T>
38+
struct greater_equal {
39+
constexpr bool operator()(const T& lhs, const T& rhs) const {
40+
return lhs >= rhs;
41+
}
42+
};
43+
44+
/**
45+
* Function object which returns true if lhs < rhs.
46+
* Equivalent to std::less, but without having to pull in all of
47+
* <functional>
48+
*/
49+
template <typename T>
50+
struct less {
51+
constexpr bool operator()(const T& lhs, const T& rhs) const {
52+
return lhs < rhs;
53+
}
54+
};
55+
56+
/**
57+
* Function object which returns true if lhs <= rhs.
58+
* Equivalent to std::less_equal, but without having to pull in all of
59+
* <functional>
60+
*/
61+
template <typename T>
62+
struct less_equal {
63+
constexpr bool operator()(const T& lhs, const T& rhs) const {
64+
return lhs <= rhs;
65+
}
66+
};
67+
} // namespace cb

engines/ep/src/kv_bucket.cc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2329,6 +2329,17 @@ VBCBAdaptor::VBCBAdaptor(KVBucket* s,
23292329
label(l),
23302330
maxDuration(std::chrono::microseconds::max()),
23312331
currentvb(0) {
2332+
// populate the list of vbuckets to visit, and order them as needed by
2333+
// the visitor.
2334+
for (Vbid::id_type vbid = 0; vbid < store->getVBuckets().getSize();
2335+
++vbid) {
2336+
if (visitor->getVBucketFilter()(Vbid(vbid))) {
2337+
vbucketsToVisit.emplace_front(vbid);
2338+
}
2339+
}
2340+
std::sort(vbucketsToVisit.begin(),
2341+
vbucketsToVisit.end(),
2342+
visitor->getVBucketComparator());
23322343
}
23332344

23342345
std::string VBCBAdaptor::getDescription() {
@@ -2337,19 +2348,19 @@ std::string VBCBAdaptor::getDescription() {
23372348

23382349
bool VBCBAdaptor::run() {
23392350
visitor->begin();
2340-
for (; currentvb < store->getVBuckets().getSize(); currentvb++) {
2341-
const auto vbid = Vbid(currentvb);
2342-
if (!visitor->getVBucketFilter()(vbid)) {
2343-
continue;
2344-
}
2351+
2352+
while (!vbucketsToVisit.empty()) {
2353+
const auto vbid = vbucketsToVisit.front();
23452354
VBucketPtr vb = store->getVBucket(vbid);
23462355
if (vb) {
2356+
currentvb = vbid.get();
23472357
if (visitor->pauseVisitor()) {
23482358
snooze(0);
23492359
return true;
23502360
}
23512361
visitor->visitBucket(vb);
23522362
}
2363+
vbucketsToVisit.pop_front();
23532364
}
23542365
visitor->complete();
23552366

engines/ep/src/kv_bucket.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ class VBCBAdaptor : public GlobalTask {
7979
const char *label;
8080
std::chrono::microseconds maxDuration;
8181

82+
/**
83+
* VBuckets the visitor has not yet visited.
84+
* Vbs will be sorted according to visitor->getVBucketComparator().
85+
* Once visited, vbuckets will be removed, so the visitor can resume after
86+
* pausing at the first element.
87+
*/
88+
std::deque<Vbid> vbucketsToVisit;
89+
8290
/**
8391
* Current VBucket.
8492
* RelaxedAtomic as this is used by getDescription to generate the task

engines/ep/src/monotonic.h

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
#pragma once
1919

20+
#include "comparators.h"
21+
2022
#include <atomic>
2123
#include <limits>
2224
#include <stdexcept>
@@ -75,31 +77,6 @@ using DefaultOrderReversedPolicy = ThrowExceptionPolicy<T>;
7577
using DefaultOrderReversedPolicy = IgnorePolicy<T>;
7678
#endif
7779

78-
namespace cb {
79-
/**
80-
* Function object which returns true if lhs > rhs.
81-
* Equivalent to std::greater, but without having to pull in all of <functional>
82-
*/
83-
template <typename T>
84-
struct greater {
85-
constexpr bool operator()(const T& lhs, const T& rhs) const {
86-
return lhs > rhs;
87-
}
88-
};
89-
90-
/**
91-
* Function object which returns true if lhs >= rhs.
92-
* Equivalent to std::greater_equal, but without having to pull in all of
93-
* <functional>
94-
*/
95-
template <typename T>
96-
struct greater_equal {
97-
constexpr bool operator()(const T& lhs, const T& rhs) const {
98-
return lhs >= rhs;
99-
}
100-
};
101-
} // namespace cb
102-
10380
/**
10481
* Monotonic is a class template for simple types T. It provides guarantee
10582
* of updating the class objects by only values that are greater than what is

engines/ep/src/vb_visitors.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#pragma once
1919

20+
#include "comparators.h"
2021
#include "hash_table.h"
2122
#include "vb_filter.h"
2223
#include "vbucket_fwd.h"
@@ -62,6 +63,18 @@ class VBucketVisitor {
6263
vBucketFilter = std::move(filter);
6364
}
6465

66+
/**
67+
* Get a comparator used to order the vbucket IDs based on visitor-specific
68+
* criteria, if necessary. This can be used to specify the order the visitor
69+
* wishes to visit vbuckets.
70+
*
71+
* Default behaviour is to visit vbuckets in ascending order.
72+
*/
73+
virtual std::function<bool(const Vbid&, const Vbid&)> getVBucketComparator()
74+
const {
75+
return cb::less<Vbid>();
76+
}
77+
6578
protected:
6679
VBucketFilter vBucketFilter;
6780
};

0 commit comments

Comments
 (0)