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