FsBuffer.hpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:8k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #ifndef FS_BUFFER_HPP
  14. #define FS_BUFFER_HPP
  15. #include <ndb_global.h>
  16. #define DEBUG(x)
  17. /**
  18.  * A circular data buffer to be used together with the FS
  19.  * 
  20.  * One writer - Typically your block
  21.  *   getWritePtr()
  22.  *   updateWritePtr()
  23.  *
  24.  * One reader - Typically "thread" in your block sending stuff to NDBFS
  25.  *   getReadPtr()
  26.  *   updateReadPtr()
  27.  */
  28. class FsBuffer {
  29. public:  
  30.   /**
  31.    * Default constructor
  32.    */
  33.   FsBuffer();
  34.   /**
  35.    * setup FsBuffer
  36.    *
  37.    * @param Buffer    - Ptr to continuous memory
  38.    * @param Size      - Buffer size in 32-bit words
  39.    * @param BlockSize - Size of block in 32-bit words
  40.    * @param MinRead   - Min read size in 32-bit words
  41.    *                    Get rounded(down) to nearest multiple of block size.
  42.    * @param MaxRead   - Max read size in 32-bit words
  43.    *                    Get rounded(down) to nearest multiple of block size.
  44.    * @param MaxWrite  - Maximum write (into buffer) in 32-bit words
  45.    *
  46.    * @return NULL if everything is OK
  47.    *    else A string describing problem
  48.    */
  49.   const char * setup(Uint32 * Buffer,
  50.      Uint32 Size, 
  51.      Uint32 BlockSize = 128,   // 512 bytes
  52.      Uint32 MinRead   = 1024,  // 4k
  53.      Uint32 MaxRead   = 1024,  // 4k
  54.      Uint32 MaxWrite  = 1024); // 4k
  55.   /*  
  56.    * @return NULL if everything is OK
  57.    *    else A string describing problem
  58.    */
  59.   const char * valid() const;
  60.   
  61.   Uint32 getBufferSize() const;
  62.   Uint32 getUsableSize() const; 
  63.   Uint32 * getStart() const;
  64.   
  65.   /**
  66.    * getReadPtr - Get pointer and size of data to send to FS
  67.    *
  68.    * @param ptr - Where to fetch data
  69.    * @param sz  - How much data in 32-bit words
  70.    * @param eof - Is this the last fetch (only if return false)
  71.    *                                             
  72.    * @return true  - If there is data of size >= minread
  73.    *         false - If there is can be data be if it is is < minread
  74.    *               - else eof = true
  75.    */
  76.   bool getReadPtr(Uint32 ** ptr, Uint32 * sz, bool * eof);
  77.   
  78.   /**
  79.    * @note: sz must be equal to sz returned by getReadPtr
  80.    */
  81.   void updateReadPtr(Uint32 sz);
  82.   /**
  83.    * 
  84.    * @note Must be followed by a updateWritePtr(no of words used)
  85.    */
  86.   bool getWritePtr(Uint32 ** ptr, Uint32 sz);
  87.   
  88.   void updateWritePtr(Uint32 sz);
  89.   /**
  90.    * There will be no more writing to this buffer
  91.    */
  92.   void eof();
  93.   /**
  94.    * Getters for varibles
  95.    */
  96.   Uint32 getMaxWrite() const { return m_maxWrite;}
  97.   Uint32 getMinRead() const { return m_minRead;}
  98.   
  99.   Uint32 getFreeSize() const { return m_free; }
  100.   
  101. private:
  102.   
  103.   Uint32 m_free;
  104.   Uint32 m_readIndex;
  105.   Uint32 m_writeIndex;
  106.   Uint32 m_eof;
  107.   Uint32 * m_start; 
  108.   Uint32 m_minRead;
  109.   Uint32 m_maxRead;
  110.   Uint32 m_maxWrite;
  111.   Uint32 m_size;
  112.   Uint32 * m_buffer;
  113.   Uint32 m_bufSize;
  114.   Uint32 m_blockSize;
  115.   void clear();
  116. };
  117. inline
  118. FsBuffer::FsBuffer() 
  119. {
  120.   clear();
  121. }
  122. inline
  123. void
  124. FsBuffer::clear(){
  125.   m_minRead = m_maxRead = m_maxWrite = m_size = m_bufSize = m_free = 0;
  126.   m_buffer = m_start = 0;
  127. }
  128. static 
  129. Uint32 * 
  130. align(Uint32 * ptr, Uint32 alignment, bool downwards){
  131.   
  132.   const UintPtr a = (UintPtr)ptr;
  133.   const UintPtr b = a % alignment;
  134.   
  135.   if(downwards){
  136.     return (Uint32 *)(a - b);
  137.   } else {
  138.     return (Uint32 *)(a + (b == 0 ? 0 : (alignment - b)));
  139.   }
  140. }
  141. inline
  142. const char * 
  143. FsBuffer::setup(Uint32 * Buffer,
  144. Uint32 Size, 
  145. Uint32 Block,
  146. Uint32 MinRead,
  147. Uint32 MaxRead,
  148. Uint32 MaxWrite)
  149. {
  150.   clear();
  151.   m_buffer    = Buffer;
  152.   m_bufSize   = Size;
  153.   m_blockSize = Block;
  154.   if(Block == 0){
  155.     return valid();
  156.   }
  157.   
  158.   m_minRead  = (MinRead / Block) * Block;
  159.   m_maxRead  = (MaxRead / Block) * Block;
  160.   m_maxWrite = MaxWrite;
  161.   m_start = align(Buffer, Block*4, false);
  162.   Uint32 * stop = align(Buffer + Size - MaxWrite, Block*4, true);
  163.   if(stop > m_start){
  164.     m_size = stop - m_start;
  165.   } else {
  166.     m_size = 0;
  167.   }
  168.   
  169.   if(m_minRead == 0)
  170.     m_size = 0;
  171.   else
  172.     m_size = (m_size / m_minRead) * m_minRead;
  173.   
  174. #if 0
  175.   ndbout_c("Block = %d MinRead = %d -> %d", Block*4, MinRead*4, m_minRead*4);
  176.   ndbout_c("Block = %d MaxRead = %d -> %d", Block*4, MaxRead*4, m_maxRead*4);
  177.   
  178.   ndbout_c("Buffer = %d -> %d", Buffer, m_start);
  179.   ndbout_c("Buffer = %d Size = %d MaxWrite = %d -> %d",
  180.    Buffer, Size*4, MaxWrite*4, m_size*4);
  181. #endif
  182.   
  183.   m_readIndex = m_writeIndex = m_eof = 0;
  184.   m_free = m_size;
  185.   return valid();
  186. }
  187. inline
  188. const char *
  189. FsBuffer::valid() const {
  190.   if(m_buffer  == 0) return "Null pointer buffer";
  191.   if(m_bufSize == 0) return "Zero size buffer";
  192.   if(m_blockSize == 0) return "Zero block size";
  193.   if(m_minRead < m_blockSize) return "Min read less than block size";
  194.   if(m_maxRead < m_blockSize) return "Max read less than block size";
  195.   if(m_maxRead < m_minRead) return "Max read less than min read";
  196.   if(m_size == 0) return "Zero usable space";
  197.   return 0;
  198. }
  199. inline
  200. Uint32 
  201. FsBuffer::getBufferSize() const {
  202.   return m_bufSize;
  203. }
  204. inline
  205. Uint32
  206. FsBuffer::getUsableSize() const {
  207.   return m_size;
  208. }
  209. inline
  210. Uint32 *
  211. FsBuffer::getStart() const {
  212.   return m_start;
  213. }
  214. inline
  215. bool 
  216. FsBuffer::getReadPtr(Uint32 ** ptr, Uint32 * sz, bool * _eof){
  217.   Uint32 * Tp = m_start;
  218.   const Uint32 Tr = m_readIndex;
  219.   const Uint32 Tm = m_minRead;
  220.   const Uint32 Ts = m_size;
  221.   const Uint32 Tmw = m_maxRead;
  222.   Uint32 sz1 = m_size - m_free; // Used
  223.   
  224.   if(sz1 >= Tm){
  225.     if(Tr + sz1 > Ts)
  226.       sz1 = (Ts - Tr);
  227.     
  228.     if(sz1 > Tmw)
  229.       * sz = Tmw;
  230.     else
  231.       * sz = sz1 - (sz1 % Tm);
  232.     
  233.     * ptr = &Tp[Tr];
  234.     DEBUG(ndbout_c("getReadPtr() Tr: %d Tw: %d Ts: %d Tm: %d sz1: %d -> %d",
  235.    Tr, Tw, Ts, Tm, sz1, * sz));
  236.     return true;
  237.   }
  238.   
  239.   if(!m_eof){
  240.     * _eof = false;
  241.     
  242.     DEBUG(ndbout_c("getReadPtr() Tr: %d Tw: %d Ts: %d Tm: %d sz1: %d -> false",
  243.    Tr, Tw, Ts, Tm, sz1));
  244.     
  245.     return false;
  246.   }
  247.   
  248.   * sz = sz1;
  249.   * _eof = true;
  250.   * ptr = &Tp[Tr];
  251.   DEBUG(ndbout_c("getReadPtr() Tr: %d Tw: %d Ts: %d Tm: %d sz1: %d -> %d eof",
  252.  Tr, Tw, Ts, Tm, sz1, * sz));
  253.   
  254.   return false;
  255. }
  256. inline
  257. void
  258. FsBuffer::updateReadPtr(Uint32 sz){
  259.   const Uint32 Tr = m_readIndex;
  260.   const Uint32 Ts = m_size;
  261.   
  262.   m_free += sz;
  263.   m_readIndex = (Tr + sz) % Ts;
  264. }
  265. inline
  266. bool
  267. FsBuffer::getWritePtr(Uint32 ** ptr, Uint32 sz){
  268.   assert(sz <= m_maxWrite);
  269.   Uint32 * Tp = m_start;
  270.   const Uint32 Tw = m_writeIndex;
  271.   const Uint32 sz1 = m_free;
  272.   if(sz1 > sz){ // Note at least 1 word of slack
  273.     * ptr = &Tp[Tw];
  274.     DEBUG(ndbout_c("getWritePtr(%d) Tr: %d Tw: %d Ts: %d sz1: %d -> true",
  275.    sz, Tr, Tw, Ts, sz1));
  276.     return true;
  277.   }
  278.   DEBUG(ndbout_c("getWritePtr(%d) Tr: %d Tw: %d Ts: %d sz1: %d -> false",
  279.  sz, Tr, Tw, Ts, sz1));
  280.   return false;
  281. }
  282. inline
  283. void 
  284. FsBuffer::updateWritePtr(Uint32 sz){
  285.   assert(sz <= m_maxWrite);
  286.   Uint32 * Tp = m_start;
  287.   const Uint32 Tw = m_writeIndex;
  288.   const Uint32 Ts = m_size;
  289.   
  290.   const Uint32 Tnew = (Tw + sz);
  291.   m_free -= sz;
  292.   if(Tnew < Ts){
  293.     m_writeIndex = Tnew;
  294.     return;
  295.   }
  296.   memcpy(Tp, &Tp[Ts], (Tnew - Ts) << 2);
  297.   m_writeIndex = Tnew - Ts;
  298. }
  299. inline
  300. void
  301. FsBuffer::eof(){
  302.   m_eof = 1;
  303. }
  304. #endif