/
backfill.hh
139 lines (107 loc) · 4.05 KB
/
backfill.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#ifndef BACKFILL_HH
#define BACKFILL_HH 1
#include <assert.h>
#include <set>
#include "common.hh"
#include "stats.hh"
#include "dispatcher.hh"
#include "ep_engine.h"
#define DEFAULT_BACKFILL_RESIDENT_THRESHOLD 0.9
#define MINIMUM_BACKFILL_RESIDENT_THRESHOLD 0.7
#define BACKFILL_MEM_THRESHOLD 0.9
/**
* Dispatcher callback responsible for bulk backfilling tap queues
* from a KVStore.
*
* Note that this is only used if the KVStore reports that it has
* efficient vbucket ops.
*/
class BackfillDiskLoad : public DispatcherCallback, public Callback<GetValue> {
public:
BackfillDiskLoad(const std::string &n, EventuallyPersistentEngine* e,
TapConnMap &tcm, KVStore *s, uint16_t vbid, const void *token)
: name(n), engine(e), connMap(tcm), store(s), vbucket(vbid), validityToken(token) {
vbucket_version = engine->getEpStore()->getVBucketVersion(vbucket);
}
void callback(GetValue &gv);
bool callback(Dispatcher &, TaskId);
std::string description();
private:
const std::string name;
EventuallyPersistentEngine *engine;
TapConnMap &connMap;
KVStore *store;
uint16_t vbucket;
uint16_t vbucket_version;
const void *validityToken;
};
/**
* VBucketVisitor to backfill a TapProducer. This visitor basically performs backfill from memory
* for only resident items if it needs to schedule a separate disk backfill task because of
* low resident ratio.
*/
class BackFillVisitor : public VBucketVisitor {
public:
BackFillVisitor(EventuallyPersistentEngine *e, TapProducer *tc,
const void *token, const VBucketFilter &backfillVBfilter):
VBucketVisitor(backfillVBfilter), engine(e), name(tc->getName()),
queue(new std::list<queued_item>),
found(), validityToken(token),
maxBackfillSize(e->tapBacklogLimit), valid(true),
efficientVBDump(e->epstore->getStorageProperties().hasEfficientVBDump()),
residentRatioBelowThreshold(false) {
found.reserve(e->tapBacklogLimit);
}
virtual ~BackFillVisitor() {
delete queue;
}
void releaseEngineResources() {
engine->tapConnMap.releaseValidityToken(validityToken);
}
bool visitBucket(RCPtr<VBucket> vb);
void visit(StoredValue *v);
bool shouldContinue() {
return checkValidity();
}
void apply(void);
void complete(void);
static void setResidentItemThreshold(double residentThreshold);
private:
void setEvents();
bool pauseVisitor();
bool checkValidity();
EventuallyPersistentEngine *engine;
const std::string name;
std::list<queued_item> *queue;
std::vector<std::pair<uint16_t, queued_item> > found;
std::vector<uint16_t> vbuckets;
const void *validityToken;
ssize_t maxBackfillSize;
bool valid;
bool efficientVBDump;
bool residentRatioBelowThreshold;
static double backfillResidentThreshold;
};
/**
* Backfill task scheduled by non-IO dispatcher. Each backfill task performs backfill from
* memory or disk depending on the resident ratio. Each backfill task can backfill more than one
* vbucket, but will snooze for 1 sec if the current backfill backlog for the corresponding TAP
* producer is greater than the threshold (5000 by default).
*/
class BackfillTask : public DispatcherCallback {
public:
BackfillTask(EventuallyPersistentEngine *e, TapProducer *tc,
EventuallyPersistentStore *s, const void *tok,
const VBucketFilter &backfillVBFilter):
bfv(new BackFillVisitor(e, tc, tok, backfillVBFilter)), engine(e), epstore(s) {}
virtual ~BackfillTask() {}
bool callback(Dispatcher &d, TaskId t);
std::string description() {
return std::string("Backfilling items from memory and disk.");
}
shared_ptr<BackFillVisitor> bfv;
EventuallyPersistentEngine *engine;
EventuallyPersistentStore *epstore;
};
#endif /* BACKFILL_HH */