]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/Readahead.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / common / Readahead.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #ifndef CEPH_READAHEAD_H
5 #define CEPH_READAHEAD_H
6
7 #include <list>
8 #include <vector>
9
10 #include "include/Context.h"
11 #include "common/ceph_mutex.h"
12
13 /**
14 This class provides common state and logic for code that needs to perform readahead
15 on linear things such as RBD images or files.
16 Unless otherwise specified, all methods are thread-safe.
17
18 Minimum and maximum readahead sizes may be violated by up to 50\% if alignment is enabled.
19 Minimum readahead size may be violated if the end of the readahead target is reached.
20 */
21 class Readahead {
22 public:
23 typedef std::pair<uint64_t, uint64_t> extent_t;
24
25 // equal to UINT64_MAX
26 static const uint64_t NO_LIMIT = 18446744073709551615ULL;
27
28 Readahead();
29
30 ~Readahead();
31
32 /**
33 Update state with new reads and return readahead to be performed.
34 If the length of the returned extent is 0, no readahead should be performed.
35 The readahead extent is guaranteed not to pass \c limit.
36
37 Note that passing in NO_LIMIT as the limit and truncating the returned extent
38 is not the same as passing in the correct limit, because the internal state
39 will differ in the two cases.
40
41 @param extents read operations since last call to update
42 @param limit size of the thing readahead is being applied to
43 */
44 extent_t update(const std::vector<extent_t>& extents, uint64_t limit);
45
46 /**
47 Update state with a new read and return readahead to be performed.
48 If the length of the returned extent is 0, no readahead should be performed.
49 The readahead extent is guaranteed not to pass \c limit.
50
51 Note that passing in NO_LIMIT as the limit and truncating the returned extent
52 is not the same as passing in the correct limit, because the internal state
53 will differ in the two cases.
54
55 @param offset offset of the read operation
56 @param length length of the read operation
57 @param limit size of the thing readahead is being applied to
58 */
59 extent_t update(uint64_t offset, uint64_t length, uint64_t limit);
60
61 /**
62 Increment the pending counter.
63 */
64 void inc_pending(int count = 1);
65
66 /**
67 Decrement the pending counter.
68 The counter must not be decremented below 0.
69 */
70 void dec_pending(int count = 1);
71
72 /**
73 Waits until the pending count reaches 0.
74 */
75 void wait_for_pending();
76 void wait_for_pending(Context *ctx);
77
78 /**
79 Sets the number of sequential requests necessary to trigger readahead.
80 */
81 void set_trigger_requests(int trigger_requests);
82
83 /**
84 Gets the minimum size of a readahead request, in bytes.
85 */
86 uint64_t get_min_readahead_size(void);
87
88 /**
89 Gets the maximum size of a readahead request, in bytes.
90 */
91 uint64_t get_max_readahead_size(void);
92
93 /**
94 Sets the minimum size of a readahead request, in bytes.
95 */
96 void set_min_readahead_size(uint64_t min_readahead_size);
97
98 /**
99 Sets the maximum size of a readahead request, in bytes.
100 */
101 void set_max_readahead_size(uint64_t max_readahead_size);
102
103 /**
104 Sets the alignment units.
105 If the end point of a readahead request can be aligned to an alignment unit
106 by increasing or decreasing the size of the request by 50\% or less, it will.
107 Alignments are tested in order, so larger numbers should almost always come first.
108 */
109 void set_alignments(const std::vector<uint64_t> &alignments);
110
111 private:
112 /**
113 Records that a read request has been received.
114 m_lock must be held while calling.
115 */
116 void _observe_read(uint64_t offset, uint64_t length);
117
118 /**
119 Computes the next readahead request.
120 m_lock must be held while calling.
121 */
122 extent_t _compute_readahead(uint64_t limit);
123
124 /// Number of sequential requests necessary to trigger readahead
125 int m_trigger_requests;
126
127 /// Minimum size of a readahead request, in bytes
128 uint64_t m_readahead_min_bytes;
129
130 /// Maximum size of a readahead request, in bytes
131 uint64_t m_readahead_max_bytes;
132
133 /// Alignment units, in bytes
134 std::vector<uint64_t> m_alignments;
135
136 /// Held while reading/modifying any state except m_pending
137 ceph::mutex m_lock = ceph::make_mutex("Readahead::m_lock");
138
139 /// Number of consecutive read requests in the current sequential stream
140 int m_nr_consec_read;
141
142 /// Number of bytes read in the current sequenial stream
143 uint64_t m_consec_read_bytes;
144
145 /// Position of the read stream
146 uint64_t m_last_pos;
147
148 /// Position of the readahead stream
149 uint64_t m_readahead_pos;
150
151 /// When readahead is already triggered and the read stream crosses this point, readahead is continued
152 uint64_t m_readahead_trigger_pos;
153
154 /// Size of the next readahead request (barring changes due to alignment, etc.)
155 uint64_t m_readahead_size;
156
157 /// Number of pending readahead requests, as determined by inc_pending() and dec_pending()
158 int m_pending;
159
160 /// Lock for m_pending
161 ceph::mutex m_pending_lock = ceph::make_mutex("Readahead::m_pending_lock");
162
163 /// Waiters for pending readahead
164 std::list<Context *> m_pending_waiting;
165 };
166
167 #endif