DCP Backfill: Use size_t instead of uint32_t to record mem usage
[ep-engine.git] / src / dcp / backfill-manager.h
1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2013 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 /**
19  * The BackfillManager is responsible for multiple DCP backfill
20  * operations owned by a single DCP connection.
21  * It consists of two main classes:
22  *
23  * - BackfillManager, which acts as the main interface for adding new
24  *    streams.
25  * - BackfillManagerTask, which runs on a background AUXIO thread and
26  *    performs most of the actual backfilling operations.
27  *
28  * One main purpose of the BackfillManager is to impose a limit on the
29  * in-memory buffer space a streams' backfills consume - often
30  * ep-engine can read data from disk faster than the client connection
31  * can consume it, and so without any limits we could exhaust the
32  * bucket quota and cause Items to be evicted from the HashTable,
33  * which is Bad. At a high level, these limits are based on giving
34  * each DCP connection a maximum amount of buffer space, and pausing
35  * backfills if the buffer limit is reached. When the buffers are
36  * sufficiently drained (by sending to the client), backfilling can be
37  * resumed.
38  *
39  * Significant configuration parameters affecting backfill:
40  * - dcp_scan_byte_limit
41  * - dcp_scan_item_limit
42  * - dcp_backfill_byte_limit
43  */
44
45 #ifndef SRC_DCP_BACKFILL_MANAGER_H_
46 #define SRC_DCP_BACKFILL_MANAGER_H_ 1
47
48 #include "config.h"
49 #include "connmap.h"
50 #include "dcp/backfill.h"
51 #include "dcp/producer.h"
52 #include "dcp/stream.h"
53
54 #include <list>
55
56 class EventuallyPersistentEngine;
57
58 class BackfillManager : public std::enable_shared_from_this<BackfillManager> {
59 public:
60     BackfillManager(EventuallyPersistentEngine& e);
61
62     ~BackfillManager();
63
64     void addStats(connection_t conn, ADD_STAT add_stat, const void *c);
65
66     void schedule(VBucket& vb,
67                   const active_stream_t& stream,
68                   uint64_t start,
69                   uint64_t end);
70
71     bool bytesRead(size_t bytes);
72
73     void bytesSent(size_t bytes);
74
75     // Called by the managerTask to acutally perform backfilling & manage
76     // backfills between the different queues.
77     backfill_status_t backfill();
78
79     void wakeUpTask();
80
81 private:
82
83     void moveToActiveQueue();
84
85     std::mutex lock;
86     std::list<UniqueDCPBackfillPtr> activeBackfills;
87     std::list<std::pair<rel_time_t, UniqueDCPBackfillPtr> > snoozingBackfills;
88     //! When the number of (activeBackfills + snoozingBackfills) crosses a
89     //!   threshold we use waitingBackfills
90     std::list<UniqueDCPBackfillPtr> pendingBackfills;
91     EventuallyPersistentEngine& engine;
92     ExTask managerTask;
93
94     //! The scan buffer is for the current stream being backfilled
95     struct {
96         size_t bytesRead;
97         size_t itemsRead;
98         size_t maxBytes;
99         size_t maxItems;
100     } scanBuffer;
101
102     //! The buffer is the total bytes used by all backfills for this connection
103     struct {
104         size_t bytesRead;
105         size_t maxBytes;
106         size_t nextReadSize;
107         bool full;
108     } buffer;
109 };
110
111 #endif  // SRC_DCP_BACKFILL_MANAGER_H_