Skip to content

Commit c320484

Browse files
jameseh96daverigby
authored andcommitted
MB-40531: [BP] Allow VBucketVisitors to specify vbucket order
Backport of http://review.couchbase.org/c/kv_engine/+/137339/ 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/+/137665 Well-Formed: Build Bot <[email protected]> Tested-by: Build Bot <[email protected]> Reviewed-by: Dave Rigby <[email protected]>
1 parent 829f660 commit c320484

File tree

5 files changed

+106
-6
lines changed

5 files changed

+106
-6
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: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2226,19 +2226,24 @@ VBCBAdaptor::VBCBAdaptor(KVBucket* s,
22262226
sleepTime(sleep),
22272227
maxDuration(std::chrono::microseconds::max()),
22282228
currentvb(0) {
2229+
// populate the list of vbuckets to visit, and order them as needed by
2230+
// the visitor.
22292231
const VBucketFilter& vbFilter = visitor->getVBucketFilter();
22302232
for (auto vbid : store->getVBuckets().getBuckets()) {
22312233
if (vbFilter(vbid)) {
2232-
vbList.push(vbid);
2234+
vbList.push_back(vbid);
22332235
}
22342236
}
2237+
std::sort(vbList.begin(),
2238+
vbList.end(),
2239+
visitor->getVBucketComparator());
22352240
}
22362241

22372242
std::string VBCBAdaptor::getDescription() {
22382243
return std::string(label) + " on vb " + std::to_string(currentvb.load());
22392244
}
22402245

2241-
bool VBCBAdaptor::run(void) {
2246+
bool VBCBAdaptor::run() {
22422247
if (!vbList.empty()) {
22432248
currentvb.store(vbList.front());
22442249
VBucketPtr vb = store->getVBucket(currentvb);
@@ -2249,7 +2254,7 @@ bool VBCBAdaptor::run(void) {
22492254
}
22502255
visitor->visitBucket(vb);
22512256
}
2252-
vbList.pop();
2257+
vbList.pop_front();
22532258
}
22542259

22552260
bool isdone = vbList.empty();

engines/ep/src/kv_bucket.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,26 @@ class VBCBAdaptor : public GlobalTask {
6262
bool run(void);
6363

6464
private:
65-
std::queue<uint16_t> vbList;
66-
KVBucket *store;
65+
/**
66+
* VBuckets the visitor has not yet visited.
67+
* Vbs will be sorted according to visitor->getVBucketComparator().
68+
* Once visited, vbuckets will be removed, so the visitor can resume after
69+
* pausing at the first element.
70+
*/
71+
72+
std::deque<VBucket::id_type> vbList;
73+
KVBucket* store;
6774
std::unique_ptr<VBucketVisitor> visitor;
6875
const char *label;
6976
double sleepTime;
7077
std::chrono::microseconds maxDuration;
71-
std::atomic<uint16_t> currentvb;
78+
79+
/**
80+
* Current VBucket.
81+
* RelaxedAtomic as this is used by getDescription to generate the task
82+
* description, which can be called by threads other than the one executing.
83+
*/
84+
Couchbase::RelaxedAtomic<VBucket::id_type> currentvb;
7285

7386
DISALLOW_COPY_AND_ASSIGN(VBCBAdaptor);
7487
};

engines/ep/src/monotonic.h

Lines changed: 2 additions & 0 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 <functional>
2224
#include <limits>

engines/ep/src/vb_visitors.h

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

2020
#include "config.h"
2121

22+
#include "comparators.h"
2223
#include "hash_table.h"
2324
#include "vb_filter.h"
2425

@@ -50,6 +51,18 @@ class VBucketVisitor {
5051
return vBucketFilter;
5152
}
5253

54+
/**
55+
* Get a comparator used to order the vbucket IDs based on visitor-specific
56+
* criteria, if necessary. This can be used to specify the order the visitor
57+
* wishes to visit vbuckets.
58+
*
59+
* Default behaviour is to visit vbuckets in ascending order.
60+
*/
61+
virtual std::function<bool(const uint16_t&, const uint16_t&)>
62+
getVBucketComparator() const {
63+
return cb::less<uint16_t>();
64+
}
65+
5366
/**
5467
* Called after all vbuckets have been visited.
5568
*/

0 commit comments

Comments
 (0)