1
/* Copyright (C) 2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
19
#include <ndb_global.h>
24
* A circular data buffer to be used together with the FS
26
* One writer - Typically your block
30
* One reader - Typically "thread" in your block sending stuff to NDBFS
44
* @param Buffer - Ptr to continuous memory
45
* @param Size - Buffer size in 32-bit words
46
* @param BlockSize - Size of block in 32-bit words
47
* @param MinRead - Min read size in 32-bit words
48
* Get rounded(down) to nearest multiple of block size.
49
* @param MaxRead - Max read size in 32-bit words
50
* Get rounded(down) to nearest multiple of block size.
51
* @param MaxWrite - Maximum write (into buffer) in 32-bit words
53
* @return NULL if everything is OK
54
* else A string describing problem
56
const char * setup(Uint32 * Buffer,
58
Uint32 BlockSize = 128, // 512 bytes
59
Uint32 MinRead = 1024, // 4k
60
Uint32 MaxRead = 1024, // 4k
61
Uint32 MaxWrite = 1024); // 4k
63
* @return NULL if everything is OK
64
* else A string describing problem
66
const char * valid() const;
68
Uint32 getBufferSize() const;
69
Uint32 getUsableSize() const;
70
Uint32 * getStart() const;
73
* getReadPtr - Get pointer and size of data to send to FS
75
* @param ptr - Where to fetch data
76
* @param sz - How much data in 32-bit words
77
* @param eof - Is this the last fetch (only if return false)
79
* @return true - If there is data of size >= minread
80
* false - If there is can be data be if it is is < minread
83
bool getReadPtr(Uint32 ** ptr, Uint32 * sz, bool * eof);
86
* @note: sz must be equal to sz returned by getReadPtr
88
void updateReadPtr(Uint32 sz);
92
* @note Must be followed by a updateWritePtr(no of words used)
94
bool getWritePtr(Uint32 ** ptr, Uint32 sz);
96
void updateWritePtr(Uint32 sz);
99
* There will be no more writing to this buffer
104
* Getters for varibles
106
Uint32 getMaxWrite() const { return m_maxWrite;}
107
Uint32 getMinRead() const { return m_minRead;}
109
Uint32 getFreeSize() const { return m_free; }
144
m_minRead = m_maxRead = m_maxWrite = m_size = m_bufSize = m_free = 0;
145
m_buffer = m_start = 0;
150
align(Uint32 * ptr, Uint32 alignment, bool downwards){
152
const UintPtr a = (UintPtr)ptr;
153
const UintPtr b = a % alignment;
156
return (Uint32 *)(a - b);
158
return (Uint32 *)(a + (b == 0 ? 0 : (alignment - b)));
164
FsBuffer::setup(Uint32 * Buffer,
179
m_minRead = (MinRead / Block) * Block;
180
m_maxRead = (MaxRead / Block) * Block;
181
m_maxWrite = MaxWrite;
183
m_start = align(Buffer, Block*4, false);
184
Uint32 * stop = align(Buffer + Size - MaxWrite, Block*4, true);
186
m_size = stop - m_start;
194
m_size = (m_size / m_minRead) * m_minRead;
197
ndbout_c("Block = %d MinRead = %d -> %d", Block*4, MinRead*4, m_minRead*4);
198
ndbout_c("Block = %d MaxRead = %d -> %d", Block*4, MaxRead*4, m_maxRead*4);
200
ndbout_c("Buffer = %d -> %d", Buffer, m_start);
201
ndbout_c("Buffer = %d Size = %d MaxWrite = %d -> %d",
202
Buffer, Size*4, MaxWrite*4, m_size*4);
205
m_readIndex = m_writeIndex = m_eof = 0;
214
m_readIndex = m_writeIndex = 0;
221
FsBuffer::valid() const {
222
if(m_buffer == 0) return "Null pointer buffer";
223
if(m_bufSize == 0) return "Zero size buffer";
224
if(m_blockSize == 0) return "Zero block size";
225
if(m_minRead < m_blockSize) return "Min read less than block size";
226
if(m_maxRead < m_blockSize) return "Max read less than block size";
227
if(m_maxRead < m_minRead) return "Max read less than min read";
228
if(m_size == 0) return "Zero usable space";
234
FsBuffer::getBufferSize() const {
240
FsBuffer::getUsableSize() const {
246
FsBuffer::getStart() const {
252
FsBuffer::getReadPtr(Uint32 ** ptr, Uint32 * sz, bool * _eof){
254
Uint32 * Tp = m_start;
255
const Uint32 Tr = m_readIndex;
256
const Uint32 Tm = m_minRead;
257
const Uint32 Ts = m_size;
258
const Uint32 Tmw = m_maxRead;
260
Uint32 sz1 = m_size - m_free; // Used
269
* sz = sz1 - (sz1 % Tm);
273
DEBUG(ndbout_c("getReadPtr() Tr: %d Tmw: %d Ts: %d Tm: %d sz1: %d -> %d",
274
Tr, Tmw, Ts, Tm, sz1, * sz));
282
DEBUG(ndbout_c("getReadPtr() Tr: %d Tmw: %d Ts: %d Tm: %d sz1: %d -> false",
283
Tr, Tmw, Ts, Tm, sz1));
292
DEBUG(ndbout_c("getReadPtr() Tr: %d Tmw: %d Ts: %d Tm: %d sz1: %d -> %d eof",
293
Tr, Tmw, Ts, Tm, sz1, * sz));
300
FsBuffer::updateReadPtr(Uint32 sz){
301
const Uint32 Tr = m_readIndex;
302
const Uint32 Ts = m_size;
305
m_readIndex = (Tr + sz) % Ts;
310
FsBuffer::getWritePtr(Uint32 ** ptr, Uint32 sz){
311
assert(sz <= m_maxWrite);
312
Uint32 * Tp = m_start;
313
const Uint32 Tw = m_writeIndex;
314
const Uint32 sz1 = m_free;
316
if(sz1 > sz){ // Note at least 1 word of slack
319
DEBUG(ndbout_c("getWritePtr(%d) Tw: %d sz1: %d -> true",
324
DEBUG(ndbout_c("getWritePtr(%d) Tw: %d sz1: %d -> false",
332
FsBuffer::updateWritePtr(Uint32 sz){
333
assert(sz <= m_maxWrite);
334
Uint32 * Tp = m_start;
335
const Uint32 Tw = m_writeIndex;
336
const Uint32 Ts = m_size;
338
const Uint32 Tnew = (Tw + sz);
342
DEBUG(ndbout_c("updateWritePtr(%d) m_writeIndex: %d",
347
memcpy(Tp, &Tp[Ts], (Tnew - Ts) << 2);
348
m_writeIndex = Tnew - Ts;
349
DEBUG(ndbout_c("updateWritePtr(%d) m_writeIndex: %d",