1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_READAHEAD_H
5 #define CEPH_READAHEAD_H
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.
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.
21 typedef std::pair<uint64_t, uint64_t> extent_t;
23 // equal to UINT64_MAX
24 static const uint64_t NO_LIMIT = 18446744073709551615ULL;
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.
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.
39 @param extents read operations since last call to update
40 @param limit size of the thing readahead is being applied to
42 extent_t update(const vector<extent_t>& extents, uint64_t limit);
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.
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.
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
57 extent_t update(uint64_t offset, uint64_t length, uint64_t limit);
60 Increment the pending counter.
62 void inc_pending(int count = 1);
65 Decrement the pending counter.
66 The counter must not be decremented below 0.
68 void dec_pending(int count = 1);
71 Waits until the pending count reaches 0.
73 void wait_for_pending();
74 void wait_for_pending(Context *ctx);
77 Sets the number of sequential requests necessary to trigger readahead.
79 void set_trigger_requests(int trigger_requests);
82 Gets the minimum size of a readahead request, in bytes.
84 uint64_t get_min_readahead_size(void);
87 Gets the maximum size of a readahead request, in bytes.
89 uint64_t get_max_readahead_size(void);
92 Sets the minimum size of a readahead request, in bytes.
94 void set_min_readahead_size(uint64_t min_readahead_size);
97 Sets the maximum size of a readahead request, in bytes.
99 void set_max_readahead_size(uint64_t max_readahead_size);
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.
107 void set_alignments(const std::vector<uint64_t> &alignments);
111 Records that a read request has been received.
112 m_lock must be held while calling.
114 void _observe_read(uint64_t offset, uint64_t length);
117 Computes the next readahead request.
118 m_lock must be held while calling.
120 extent_t _compute_readahead(uint64_t limit);
122 /// Number of sequential requests necessary to trigger readahead
123 int m_trigger_requests;
125 /// Minimum size of a readahead request, in bytes
126 uint64_t m_readahead_min_bytes;
128 /// Maximum size of a readahead request, in bytes
129 uint64_t m_readahead_max_bytes;
131 /// Alignment units, in bytes
132 std::vector<uint64_t> m_alignments;
134 /// Held while reading/modifying any state except m_pending
137 /// Number of consecutive read requests in the current sequential stream
138 int m_nr_consec_read;
140 /// Number of bytes read in the current sequenial stream
141 uint64_t m_consec_read_bytes;
143 /// Position of the read stream
146 /// Position of the readahead stream
147 uint64_t m_readahead_pos;
149 /// When readahead is already triggered and the read stream crosses this point, readahead is continued
150 uint64_t m_readahead_trigger_pos;
152 /// Size of the next readahead request (barring changes due to alignment, etc.)
153 uint64_t m_readahead_size;
155 /// Number of pending readahead requests, as determined by inc_pending() and dec_pending()
158 /// Lock for m_pending
159 Mutex m_pending_lock;
161 /// Waiters for pending readahead
162 std::list<Context *> m_pending_waiting;