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

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. //****************************************************************************
  14. //
  15. //  NAME
  16. //      SendBuffer
  17. //
  18. //  DESCRIPTION
  19. //      The SendBuffer is a circular buffer storing signals waiting to be sent.
  20. //      The signals can be of variable size and are copied into the buffer 
  21. //      in Protocol 6 format. There will be two SendBuffer instances 
  22. //      (priority level A and B) for each transporter using a buffer for 
  23. //      sending. The buffering will in most cases be done to send as big 
  24. //      packages as possible over TCP/IP.
  25. //
  26. //***************************************************************************/
  27. #ifndef SendBuffer_H
  28. #define SendBuffer_H
  29. #include "TransporterDefinitions.hpp"
  30. #include <TransporterCallback.hpp>
  31. #ifdef DEBUG_TRANSPORTER
  32. #include <ndb_global.h>
  33. #endif
  34. class SendBuffer {
  35.   friend class TCP_Transporter;
  36. public:
  37.   // Set member variables
  38.   SendBuffer(Uint32 bufSize);
  39.   // Deallocate the buffer memory
  40.   ~SendBuffer();
  41.   
  42.   // Allocate memory for the buffer and initialize the buffer pointers
  43.   bool initBuffer(Uint32 aRemoteNodeId);  
  44.   // Number of bytes remaining in the buffer
  45.   Uint32 bufferSizeRemaining() const;
  46.   // Number of bytes of data in the buffer 
  47.   int bufferSize(); 
  48.   // Empty the buffer
  49.   void emptyBuffer();
  50.   
  51.   /**
  52.    * The transporter calls updateBuffer after a retrieve followed by 
  53.    * a successful send, to update the cirkular buffer pointers.
  54.    * updateBuffer is called with the number of bytes really sent,
  55.    * it may be that it is less than what was retrived from the buffer.
  56.    * If that is the case there will be an incomplete message (slack)
  57.    * in the SendBuffer. 
  58.    *
  59.    * Returns  0 if buffer empty
  60.    *    else ~0
  61.    */
  62.   Uint32 bytesSent(Uint32 len);
  63.   
  64. #ifdef DEBUG_TRANSPORTER
  65.   // Prints the buffer status on the screen. Can be used for testing purposes.
  66.   void print();
  67. #endif
  68.   Uint32* getInsertPtr(Uint32 bytes);
  69.   void updateInsertPtr(Uint32 bytes);
  70. private:
  71.   
  72.   Uint32   sizeOfBuffer;  // Length, in number of bytes, of the buffer memory
  73.   Uint32   dataSize;      // Number of bytes in buffer
  74.   
  75.   Uint32 * startOfBuffer; // Pointer to the start of the buffer memory
  76.   Uint32 * endOfBuffer;   // Pointer to end of buffer
  77.   
  78.   Uint32 * insertPtr;     // Where to insert next
  79.   
  80.   char *   sendPtr;           // Where data to send starts
  81.   Uint32   sendDataSize;      // Num bytes to send
  82.   
  83.   Uint32   theRemoteNodeId;
  84. };
  85. inline
  86. Uint32
  87. SendBuffer::bytesSent(Uint32 bytes) {
  88.   if(bytes > dataSize){
  89. #ifdef DEBUG_TRANSPORTER
  90.     printf("bytes(%d) > dataSize(%d)n", bytes, dataSize);
  91. #endif
  92.     abort();
  93.     // reportError(0 ,theRemoteNodeId, TE_INVALID_MESSAGE_LENGTH);
  94.     return 0;
  95.   }//if
  96.   if(bytes > sendDataSize){
  97. #ifdef DEBUG_TRANSPORTER
  98.     printf("bytes(%d) > sendDataSize(%d)n", bytes, sendDataSize);
  99. #endif
  100.     abort();
  101.     //reportError(0,theRemoteNodeId, TE_INVALID_MESSAGE_LENGTH);
  102.     return 0;
  103.   }//if
  104.   dataSize     -= bytes;
  105.   sendPtr      += bytes;
  106.   sendDataSize -= bytes;
  107.   
  108.   if(sendDataSize == 0){
  109.     if(sendPtr > (char*)insertPtr){
  110.       sendPtr = (char *)startOfBuffer;
  111.       sendDataSize = dataSize;
  112.     } else {
  113.       sendPtr = ((char*)insertPtr) - dataSize;
  114.       sendDataSize = dataSize;
  115.     }
  116.   }
  117.   
  118.   if(dataSize == 0)
  119.     return 0;
  120.   return ~0;
  121. }
  122. inline
  123. Uint32*
  124. SendBuffer::getInsertPtr(Uint32 len){
  125.   if (bufferSizeRemaining() < len){
  126.     return 0;
  127.   }
  128.   const char * const tmpInsertPtr = (char *) insertPtr;
  129.   if(tmpInsertPtr >= sendPtr){
  130.     // Is there enough space at the end of the buffer? 
  131.     if ((tmpInsertPtr + len) < (char*)endOfBuffer){
  132.       sendDataSize += len;
  133.       return insertPtr;
  134.     } else {
  135.       // We have passed the end of the cirkular buffer, 
  136.       // must start from the beginning
  137.       // Is there enough space in the beginning of the buffer?
  138.       if ((Uint32)(sendPtr - (char *)startOfBuffer) <= len){
  139. // Not enough space available, insert failed
  140. return 0;
  141.       } else {
  142. // There is space available at the beginning of the buffer
  143. // We start from the beginning, set endOfData and insertPtr
  144. insertPtr = startOfBuffer; 
  145. if(sendDataSize != 0){
  146.   return insertPtr;
  147. }
  148. sendPtr      = (char *)startOfBuffer;
  149. sendDataSize = len;
  150. return insertPtr;
  151.       }
  152.     }
  153.   } else {
  154.     // sendPtr > insertPtr
  155.     // Is there enought room
  156.     if((tmpInsertPtr + len) < sendPtr){
  157.       return insertPtr;
  158.     }
  159.     return 0;
  160.   }
  161. }
  162. inline
  163. void
  164. SendBuffer::updateInsertPtr(Uint32 lenBytes){
  165.   dataSize  += lenBytes;
  166.   insertPtr += (lenBytes / 4);
  167. }
  168. #endif // Define of SendBuffer_H