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