MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FsBuffer.hpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef FS_BUFFER_HPP
19 #define FS_BUFFER_HPP
20 
21 #include <ndb_global.h>
22 
23 #define DEBUG(x)
24 
36 class FsBuffer {
37 public:
41  FsBuffer();
42 
58  const char * setup(Uint32 * Buffer,
59  Uint32 Size,
60  Uint32 BlockSize = 128, // 512 bytes
61  Uint32 MinRead = 1024, // 4k
62  Uint32 MaxRead = 1024, // 4k
63  Uint32 MaxWrite = 1024); // 4k
64  /*
65  * @return NULL if everything is OK
66  * else A string describing problem
67  */
68  const char * valid() const;
69 
70  Uint32 getBufferSize() const;
71  Uint32 getUsableSize() const;
72  Uint32 * getStart() const;
73 
85  bool getReadPtr(Uint32 ** ptr, Uint32 * sz, bool * eof);
86 
90  void updateReadPtr(Uint32 sz);
91 
96  bool getWritePtr(Uint32 ** ptr, Uint32 sz);
97 
98  void updateWritePtr(Uint32 sz);
99 
103  void eof();
104 
108  Uint32 getMaxWrite() const { return m_maxWrite;}
109  Uint32 getMinRead() const { return m_minRead;}
110 
111  Uint32 getFreeSize() const { return m_free; }
112 
116  void reset();
117 
118 private:
119 
120  Uint32 m_free;
121  Uint32 m_readIndex;
122  Uint32 m_writeIndex;
123  Uint32 m_eof;
124  Uint32 * m_start;
125  Uint32 m_minRead;
126  Uint32 m_maxRead;
127  Uint32 m_maxWrite;
128  Uint32 m_size;
129 
130  Uint32 * m_buffer;
131  Uint32 m_bufSize;
132  Uint32 m_blockSize;
133 
134  void clear();
135 };
136 
137 inline
139 {
140  clear();
141 }
142 
143 inline
144 void
145 FsBuffer::clear(){
146  m_minRead = m_maxRead = m_maxWrite = m_size = m_bufSize = m_free = 0;
147  m_buffer = m_start = 0;
148 }
149 
150 static
151 Uint32 *
152 align(Uint32 * ptr, Uint32 alignment, bool downwards){
153 
154  const UintPtr a = (UintPtr)ptr;
155  const UintPtr b = a % alignment;
156 
157  if(downwards){
158  return (Uint32 *)(a - b);
159  } else {
160  return (Uint32 *)(a + (b == 0 ? 0 : (alignment - b)));
161  }
162 }
163 
164 inline
165 const char *
167  Uint32 Size,
168  Uint32 Block,
169  Uint32 MinRead,
170  Uint32 MaxRead,
171  Uint32 MaxWrite)
172 {
173  clear();
174  m_buffer = Buffer;
175  m_bufSize = Size;
176  m_blockSize = Block;
177  if(Block == 0){
178  return valid();
179  }
180 
181  m_minRead = (MinRead / Block) * Block;
182  m_maxRead = (MaxRead / Block) * Block;
183  m_maxWrite = MaxWrite;
184 
185  m_start = align(Buffer, Block*4, false);
186  Uint32 * stop = align(Buffer + Size - MaxWrite, Block*4, true);
187  if(stop > m_start){
188  assert(((Uint64(stop) - Uint64(m_start)) >> 32) == 0);
189  m_size = Uint32(stop - m_start);
190  } else {
191  m_size = 0;
192  }
193 
194  if(m_minRead == 0)
195  m_size = 0;
196  else
197  m_size = (m_size / m_minRead) * m_minRead;
198 
199 #if 0
200  ndbout_c("Block = %d MinRead = %d -> %d", Block*4, MinRead*4, m_minRead*4);
201  ndbout_c("Block = %d MaxRead = %d -> %d", Block*4, MaxRead*4, m_maxRead*4);
202 
203  ndbout_c("Buffer = %d -> %d", Buffer, m_start);
204  ndbout_c("Buffer = %d Size = %d MaxWrite = %d -> %d",
205  Buffer, Size*4, MaxWrite*4, m_size*4);
206 #endif
207 
208  m_readIndex = m_writeIndex = m_eof = 0;
209  m_free = m_size;
210  return valid();
211 }
212 
213 inline
214 void
216 {
217  m_readIndex = m_writeIndex = 0;
218  m_free = m_size;
219  m_eof = 0;
220 }
221 
222 inline
223 const char *
224 FsBuffer::valid() const {
225  if(m_buffer == 0) return "Null pointer buffer";
226  if(m_bufSize == 0) return "Zero size buffer";
227  if(m_blockSize == 0) return "Zero block size";
228  if(m_minRead < m_blockSize) return "Min read less than block size";
229  if(m_maxRead < m_blockSize) return "Max read less than block size";
230  if(m_maxRead < m_minRead) return "Max read less than min read";
231  if(m_size == 0) return "Zero usable space";
232  return 0;
233 }
234 
235 inline
236 Uint32
237 FsBuffer::getBufferSize() const {
238  return m_bufSize;
239 }
240 
241 inline
242 Uint32
243 FsBuffer::getUsableSize() const {
244  return m_size;
245 }
246 
247 inline
248 Uint32 *
249 FsBuffer::getStart() const {
250  return m_start;
251 }
252 
253 inline
254 bool
255 FsBuffer::getReadPtr(Uint32 ** ptr, Uint32 * sz, bool * _eof){
256 
257  Uint32 * Tp = m_start;
258  const Uint32 Tr = m_readIndex;
259  const Uint32 Tm = m_minRead;
260  const Uint32 Ts = m_size;
261  const Uint32 Tmw = m_maxRead;
262 
263  Uint32 sz1 = m_size - m_free; // Used
264 
265  if(sz1 >= Tm){
266  if(Tr + sz1 > Ts)
267  sz1 = (Ts - Tr);
268 
269  if(sz1 > Tmw)
270  * sz = Tmw;
271  else
272  * sz = sz1 - (sz1 % Tm);
273 
274  * ptr = &Tp[Tr];
275 
276  DEBUG(ndbout_c("getReadPtr() Tr: %d Tmw: %d Ts: %d Tm: %d sz1: %d -> %d",
277  Tr, Tmw, Ts, Tm, sz1, * sz));
278 
279  return true;
280  }
281 
282  if(!m_eof){
283  * _eof = false;
284 
285  DEBUG(ndbout_c("getReadPtr() Tr: %d Tmw: %d Ts: %d Tm: %d sz1: %d -> false",
286  Tr, Tmw, Ts, Tm, sz1));
287 
288  return false;
289  }
290 
291  * sz = sz1;
292  * _eof = true;
293  * ptr = &Tp[Tr];
294 
295  DEBUG(ndbout_c("getReadPtr() Tr: %d Tmw: %d Ts: %d Tm: %d sz1: %d -> %d eof",
296  Tr, Tmw, Ts, Tm, sz1, * sz));
297 
298  return false;
299 }
300 
301 inline
302 void
304  const Uint32 Tr = m_readIndex;
305  const Uint32 Ts = m_size;
306 
307  m_free += sz;
308  m_readIndex = (Tr + sz) % Ts;
309 }
310 
311 inline
312 bool
313 FsBuffer::getWritePtr(Uint32 ** ptr, Uint32 sz){
314  assert(sz <= m_maxWrite);
315  Uint32 * Tp = m_start;
316  const Uint32 Tw = m_writeIndex;
317  const Uint32 sz1 = m_free;
318 
319  if(sz1 > sz){ // Note at least 1 word of slack
320  * ptr = &Tp[Tw];
321 
322  DEBUG(ndbout_c("getWritePtr(%d) Tw: %d sz1: %d -> true",
323  sz, Tw, sz1));
324  return true;
325  }
326 
327  DEBUG(ndbout_c("getWritePtr(%d) Tw: %d sz1: %d -> false",
328  sz, Tw, sz1));
329 
330  return false;
331 }
332 
333 inline
334 void
335 FsBuffer::updateWritePtr(Uint32 sz){
336  assert(sz <= m_maxWrite);
337  Uint32 * Tp = m_start;
338  const Uint32 Tw = m_writeIndex;
339  const Uint32 Ts = m_size;
340 
341  const Uint32 Tnew = (Tw + sz);
342  m_free -= sz;
343  if(Tnew < Ts){
344  m_writeIndex = Tnew;
345  DEBUG(ndbout_c("updateWritePtr(%d) m_writeIndex: %d",
346  sz, m_writeIndex));
347  return;
348  }
349 
350  memcpy(Tp, &Tp[Ts], (Tnew - Ts) << 2);
351  m_writeIndex = Tnew - Ts;
352  DEBUG(ndbout_c("updateWritePtr(%d) m_writeIndex: %d",
353  sz, m_writeIndex));
354 }
355 
356 inline
357 void
359  m_eof = 1;
360 }
361 
362 #endif