Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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