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 //****************************************************************************
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 //***************************************************************************/
33 #include "TransporterDefinitions.hpp"
34 #include <TransporterCallback.hpp>
36 #ifdef DEBUG_TRANSPORTER
37 #include <ndb_global.h>
41 friend class TCP_Transporter
;
43 // Set member variables
44 SendBuffer(Uint32 bufSize
);
46 // Deallocate the buffer memory
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
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)
69 * Returns 0 if buffer empty
72 Uint32
bytesSent(Uint32 len
);
74 #ifdef DEBUG_TRANSPORTER
75 // Prints the buffer status on the screen. Can be used for testing purposes.
79 Uint32
* getInsertPtr(Uint32 bytes
);
80 void updateInsertPtr(Uint32 bytes
);
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
;
100 SendBuffer::bytesSent(Uint32 bytes
) {
102 if(bytes
> dataSize
){
103 #ifdef DEBUG_TRANSPORTER
104 printf("bytes(%d) > dataSize(%d)\n", bytes
, dataSize
);
107 // reportError(0 ,theRemoteNodeId, TE_INVALID_MESSAGE_LENGTH);
111 if(bytes
> sendDataSize
){
112 #ifdef DEBUG_TRANSPORTER
113 printf("bytes(%d) > sendDataSize(%d)\n", bytes
, sendDataSize
);
116 //reportError(0,theRemoteNodeId, TE_INVALID_MESSAGE_LENGTH);
122 sendDataSize
-= bytes
;
124 if(sendDataSize
== 0){
125 if(sendPtr
> (char*)insertPtr
){
126 sendPtr
= (char *)startOfBuffer
;
127 sendDataSize
= dataSize
;
129 sendPtr
= ((char*)insertPtr
) - dataSize
;
130 sendDataSize
= dataSize
;
141 SendBuffer::getInsertPtr(Uint32 len
){
142 if (bufferSizeRemaining() < len
){
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
){
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
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){
167 sendPtr
= (char *)startOfBuffer
;
173 // sendPtr > insertPtr
174 // Is there enought room
175 if((tmpInsertPtr
+ len
) < sendPtr
){
184 SendBuffer::updateInsertPtr(Uint32 lenBytes
){
185 dataSize
+= lenBytes
;
186 insertPtr
+= (lenBytes
/ 4);
189 #endif // Define of SendBuffer_H