00001 /** @file 00002 00003 I/O classes 00004 00005 @section license License 00006 00007 Licensed to the Apache Software Foundation (ASF) under one 00008 or more contributor license agreements. See the NOTICE file 00009 distributed with this work for additional information 00010 regarding copyright ownership. The ASF licenses this file 00011 to you under the Apache License, Version 2.0 (the 00012 "License"); you may not use this file except in compliance 00013 with the License. You may obtain a copy of the License at 00014 00015 http://www.apache.org/licenses/LICENSE-2.0 00016 00017 Unless required by applicable law or agreed to in writing, software 00018 distributed under the License is distributed on an "AS IS" BASIS, 00019 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00020 See the License for the specific language governing permissions and 00021 limitations under the License. 00022 00023 @section watermark Watermark 00024 00025 Watermarks can be used as an interface between the data transferring 00026 layer (VConnection) and the user layer (a state machine). Watermarks 00027 should be used when you need to have at least a certain amount of data 00028 to make some determination. For example, when parsing a string, one 00029 might wish to ensure that an entire line will come in before consuming 00030 the data. In such a case, the water_mark should be set to the largest 00031 possible size of the string. (appropriate error handling should take 00032 care of exessively long strings). 00033 00034 In all other cases, especially when all data will be consumed, the 00035 water_mark should be set to 0 (the default). 00036 00037 */ 00038 00039 #if !defined (I_IOBuffer_h) 00040 #define I_IOBuffer_h 00041 00042 #include "libts.h" 00043 #include "ink_resource.h" 00044 00045 struct MIOBufferAccessor; 00046 00047 class MIOBuffer; 00048 class IOBufferReader; 00049 class VIO; 00050 00051 // Removing this optimization since this is breaking WMT over HTTP 00052 //#define WRITE_AND_TRANSFER 00053 00054 inkcoreapi extern int64_t max_iobuffer_size; 00055 extern int64_t default_small_iobuffer_size; 00056 extern int64_t default_large_iobuffer_size; // matched to size of OS buffers 00057 00058 #if !defined(TRACK_BUFFER_USER) 00059 #define TRACK_BUFFER_USER 1 00060 #endif 00061 00062 enum AllocType 00063 { 00064 NO_ALLOC, 00065 FAST_ALLOCATED, 00066 XMALLOCED, 00067 MEMALIGNED, 00068 DEFAULT_ALLOC, 00069 CONSTANT 00070 }; 00071 00072 #if TS_USE_RECLAIMABLE_FREELIST 00073 #define DEFAULT_BUFFER_NUMBER 64 00074 #else 00075 #define DEFAULT_BUFFER_NUMBER 128 00076 #endif 00077 #define DEFAULT_HUGE_BUFFER_NUMBER 32 00078 #define MAX_MIOBUFFER_READERS 5 00079 #define DEFAULT_BUFFER_ALIGNMENT 8192 // should be disk/page size 00080 #define DEFAULT_BUFFER_BASE_SIZE 128 00081 00082 //////////////////////////////////////////////// 00083 // These are defines so that code that used 2 // 00084 // for buffer size index when 2 was 2K will // 00085 // still work if it uses BUFFER_SIZE_INDEX_2K // 00086 // instead. // 00087 //////////////////////////////////////////////// 00088 #define BUFFER_SIZE_INDEX_128 0 00089 #define BUFFER_SIZE_INDEX_256 1 00090 #define BUFFER_SIZE_INDEX_512 2 00091 #define BUFFER_SIZE_INDEX_1K 3 00092 #define BUFFER_SIZE_INDEX_2K 4 00093 #define BUFFER_SIZE_INDEX_4K 5 00094 #define BUFFER_SIZE_INDEX_8K 6 00095 #define BUFFER_SIZE_INDEX_16K 7 00096 #define BUFFER_SIZE_INDEX_32K 8 00097 #define BUFFER_SIZE_INDEX_64K 9 00098 #define BUFFER_SIZE_INDEX_128K 10 00099 #define BUFFER_SIZE_INDEX_256K 11 00100 #define BUFFER_SIZE_INDEX_512K 12 00101 #define BUFFER_SIZE_INDEX_1M 13 00102 #define BUFFER_SIZE_INDEX_2M 14 00103 #define MAX_BUFFER_SIZE_INDEX 14 00104 #define DEFAULT_BUFFER_SIZES (MAX_BUFFER_SIZE_INDEX+1) 00105 00106 #define BUFFER_SIZE_FOR_INDEX(_i) (DEFAULT_BUFFER_BASE_SIZE * (1 << (_i))) 00107 #define DEFAULT_SMALL_BUFFER_SIZE BUFFER_SIZE_INDEX_512 00108 #define DEFAULT_LARGE_BUFFER_SIZE BUFFER_SIZE_INDEX_4K 00109 #define DEFAULT_TS_BUFFER_SIZE BUFFER_SIZE_INDEX_8K 00110 #define DEFAULT_MAX_BUFFER_SIZE BUFFER_SIZE_FOR_INDEX(MAX_BUFFER_SIZE_INDEX) 00111 #define MIN_IOBUFFER_SIZE BUFFER_SIZE_INDEX_128 00112 #define MAX_IOBUFFER_SIZE (DEFAULT_BUFFER_SIZES-1) 00113 00114 00115 #define BUFFER_SIZE_ALLOCATED(_i) \ 00116 (BUFFER_SIZE_INDEX_IS_FAST_ALLOCATED(_i) || \ 00117 BUFFER_SIZE_INDEX_IS_XMALLOCED(_i) ) 00118 00119 #define BUFFER_SIZE_NOT_ALLOCATED DEFAULT_BUFFER_SIZES 00120 #define BUFFER_SIZE_INDEX_IS_XMALLOCED(_size_index) (_size_index < 0) 00121 #define BUFFER_SIZE_INDEX_IS_FAST_ALLOCATED(_size_index) \ 00122 (((uint64_t)_size_index) < DEFAULT_BUFFER_SIZES) 00123 #define BUFFER_SIZE_INDEX_IS_CONSTANT(_size_index) \ 00124 (_size_index >= DEFAULT_BUFFER_SIZES) 00125 00126 #define BUFFER_SIZE_FOR_XMALLOC(_size) (-(_size)) 00127 #define BUFFER_SIZE_INDEX_FOR_XMALLOC_SIZE(_size) (-(_size)) 00128 00129 #define BUFFER_SIZE_FOR_CONSTANT(_size) (_size - DEFAULT_BUFFER_SIZES) 00130 #define BUFFER_SIZE_INDEX_FOR_CONSTANT_SIZE(_size) (_size+DEFAULT_BUFFER_SIZES) 00131 00132 inkcoreapi extern Allocator ioBufAllocator[DEFAULT_BUFFER_SIZES]; 00133 00134 void init_buffer_allocators(); 00135 00136 /** 00137 A reference counted wrapper around fast allocated or malloced memory. 00138 The IOBufferData class provides two basic services around a portion 00139 of allocated memory. 00140 00141 First, it is a reference counted object and ... 00142 00143 @remarks The AllocType enum, is used to define the type of allocation 00144 for the memory this IOBufferData object manages. 00145 00146 <table> 00147 <tr> 00148 <td align="center">AllocType</td> 00149 <td align="center">Meaning</td> 00150 </tr> 00151 <tr> 00152 <td>NO_ALLOC</td> 00153 <td></td> 00154 </tr> 00155 <tr> 00156 <td>FAST_ALLOCATED</td> 00157 <td></td> 00158 </tr> 00159 <tr> 00160 <td>XMALLOCED</td> 00161 <td></td> 00162 </tr> 00163 <tr> 00164 <td>MEMALIGNED</td> 00165 <td></td> 00166 </tr> 00167 <tr> 00168 <td>DEFAULT_ALLOC</td> 00169 <td></td> 00170 </tr> 00171 <tr> 00172 <td>CONSTANT</td> 00173 <td></td> 00174 </tr> 00175 </table> 00176 00177 */ 00178 class IOBufferData:public RefCountObj 00179 { 00180 public: 00181 00182 /** 00183 The size of the memory allocated by this IOBufferData. Calculates 00184 the amount of memory allocated by this IOBufferData. 00185 00186 @return number of bytes allocated for the '_data' member. 00187 00188 */ 00189 int64_t block_size(); 00190 00191 /** 00192 Frees the memory managed by this IOBufferData. Deallocates the 00193 memory previously allocated by this IOBufferData object. It frees 00194 the memory pointed to by '_data' according to the '_mem_type' and 00195 '_size_index' members. 00196 00197 */ 00198 void dealloc(); 00199 00200 /** 00201 Allocates memory and sets this IOBufferData to point to it. 00202 Allocates memory according to the size_index and type 00203 parameters. Any previously allocated memory pointed to by 00204 this IOBufferData is deallocated. 00205 00206 @param size_index 00207 @param type of allocation to use; see remarks section. 00208 */ 00209 void alloc(int64_t size_index, AllocType type = DEFAULT_ALLOC); 00210 00211 /** 00212 Provides access to the allocated memory. Returns the address of the 00213 allocated memory handled by this IOBufferData. 00214 00215 @return address of the memory handled by this IOBufferData. 00216 00217 */ 00218 char *data() 00219 { 00220 return _data; 00221 } 00222 00223 /** 00224 Cast operator. Provided as a convenience, the cast to a char* applied 00225 to the IOBufferData returns the address of the memory handled by the 00226 IOBuffer data. In this manner, objects of this class can be used as 00227 parameter to functions requiring a char*. 00228 00229 */ 00230 operator char *() 00231 { 00232 return _data; 00233 } 00234 00235 /** 00236 Frees the IOBufferData object and its underlying memory. Deallocates 00237 the memory managed by this IOBufferData and then frees itself. You 00238 should not use this object or reference after this call. 00239 00240 */ 00241 virtual void free(); 00242 00243 int64_t _size_index; 00244 00245 /** 00246 Type of allocation used for the managed memory. Stores the type of 00247 allocation used for the memory currently managed by the IOBufferData 00248 object. Do not set or modify this value directly. Instead use the 00249 alloc or dealloc methods. 00250 00251 */ 00252 AllocType _mem_type; 00253 00254 /** 00255 Points to the allocated memory. This member stores the address of 00256 the allocated memory. You should not modify its value directly, 00257 instead use the alloc or dealloc methods. 00258 00259 */ 00260 char *_data; 00261 00262 #ifdef TRACK_BUFFER_USER 00263 const char *_location; 00264 #endif 00265 00266 /** 00267 Constructor. Initializes state for a IOBufferData object. Do not use 00268 this method. Use one of the functions with the 'new_' prefix instead. 00269 00270 */ 00271 IOBufferData() 00272 : _size_index(BUFFER_SIZE_NOT_ALLOCATED), _mem_type(NO_ALLOC), _data(NULL) 00273 #ifdef TRACK_BUFFER_USER 00274 , _location(NULL) 00275 #endif 00276 { 00277 } 00278 00279 private: 00280 // declaration only 00281 IOBufferData(const IOBufferData &); 00282 IOBufferData & operator =(const IOBufferData &); 00283 }; 00284 00285 inkcoreapi extern ClassAllocator<IOBufferData> ioDataAllocator; 00286 00287 /** 00288 A linkable portion of IOBufferData. IOBufferBlock is a chainable 00289 buffer block descriptor. The IOBufferBlock represents both the used 00290 and available space in the underlying block. The IOBufferBlock is not 00291 sharable between buffers but rather represents what part of the data 00292 block is both in use and usable by the MIOBuffer it is attached to. 00293 00294 */ 00295 class IOBufferBlock:public RefCountObj 00296 { 00297 public: 00298 /** 00299 Access the actual data. Provides access to rhe underlying data 00300 managed by the IOBufferData. 00301 00302 @return pointer to the underlying data. 00303 00304 */ 00305 char *buf() 00306 { 00307 return data->_data; 00308 } 00309 00310 /** 00311 Beginning of the inuse section. Returns the position in the buffer 00312 where the inuse area begins. 00313 00314 @return pointer to the start of the inuse section. 00315 00316 */ 00317 char *start() 00318 { 00319 return _start; 00320 } 00321 00322 /** 00323 End of the used space. Returns a pointer to end of the used space 00324 in the data buffer represented by this block. 00325 00326 @return pointer to the end of the inuse portion of the block. 00327 00328 */ 00329 char *end() 00330 { 00331 return _end; 00332 } 00333 00334 /** 00335 End of the data buffer. Returns a pointer to end of the data buffer 00336 represented by this block. 00337 00338 */ 00339 char *buf_end() 00340 { 00341 return _buf_end; 00342 } 00343 00344 /** 00345 Size of the inuse area. Returns the size of the current inuse area. 00346 00347 @return bytes occupied by the inuse area. 00348 00349 */ 00350 int64_t size() 00351 { 00352 return (int64_t) (_end - _start); 00353 } 00354 00355 /** 00356 Size of the data available for reading. Returns the size of the data 00357 available for reading in the inuse area. 00358 00359 @return bytes available for reading from the inuse area. 00360 00361 */ 00362 int64_t read_avail() 00363 { 00364 return (int64_t) (_end - _start); 00365 } 00366 00367 /** 00368 Space available in the buffer. Returns the number of bytes that can 00369 be written to the data buffer. 00370 00371 @return space available for writing in this IOBufferBlock. 00372 */ 00373 int64_t write_avail() 00374 { 00375 return (int64_t) (_buf_end - _end); 00376 } 00377 00378 /** 00379 Size of the memory allocated by the underlying IOBufferData. 00380 Computes the size of the entire block, which includes the used and 00381 available areas. It is the memory allocated by the IOBufferData 00382 referenced by this IOBufferBlock. 00383 00384 @return bytes allocated to the IOBufferData referenced by this 00385 IOBufferBlock. 00386 00387 */ 00388 int64_t block_size() 00389 { 00390 return data->block_size(); 00391 } 00392 00393 /** 00394 Decrease the size of the inuse area. Moves forward the start of 00395 the inuse area. This also decreases the number of available bytes 00396 for reading. 00397 00398 @param len bytes to consume or positions to skip for the start of 00399 the inuse area. 00400 00401 */ 00402 void consume(int64_t len); 00403 00404 /** 00405 Increase the inuse area of the block. Adds 'len' bytes to the inuse 00406 area of the block. Data should be copied into the data buffer by 00407 using end() to find the start of the free space in the data buffer 00408 before calling fill() 00409 00410 @param len bytes to increase the inuse area. It must be less than 00411 or equal to the value of write_avail(). 00412 00413 */ 00414 void fill(int64_t len); 00415 00416 /** 00417 Reset the inuse area. The start and end of the inuse area are reset 00418 but the actual IOBufferData referenced by this IOBufferBlock is not 00419 modified. This effectively reduces the number of bytes available 00420 for reading to zero, and the number of bytes available for writing 00421 to the size of the entire buffer. 00422 00423 */ 00424 void reset(); 00425 00426 /** 00427 Create a copy of the IOBufferBlock. Creates and returns a copy of this 00428 IOBufferBlock that references the same data that this IOBufferBlock 00429 (it does not allocate an another buffer). The cloned block will not 00430 have a writable space since the original IOBufferBlock mantains the 00431 ownership for writing data to the block. 00432 00433 @return copy of this IOBufferBlock. 00434 00435 */ 00436 IOBufferBlock *clone(); 00437 00438 /** 00439 Clear the IOBufferData this IOBufferBlock handles. Clears this 00440 IOBufferBlock's reference to the data buffer (IOBufferData). You can 00441 use alloc after this call to allocate an IOBufferData associated to 00442 this IOBufferBlock. 00443 00444 */ 00445 void clear(); 00446 00447 /** 00448 Allocate a data buffer. Allocates a data buffer for this IOBufferBlock 00449 based on index 'i'. Index values are described in the remarks 00450 section in MIOBuffer. 00451 00452 */ 00453 void alloc(int64_t i = default_large_iobuffer_size); 00454 00455 /** 00456 Clear the IOBufferData this IOBufferBlock handles. Clears this 00457 IOBufferBlock's reference to the data buffer (IOBufferData). 00458 00459 */ 00460 void dealloc(); 00461 00462 /** 00463 Set or replace this IOBufferBlock's IOBufferData member. Sets this 00464 IOBufferBlock's IOBufferData member to point to the IOBufferData 00465 passed in. You can optionally specify the inuse area with the 'len' 00466 argument and an offset for the start. 00467 00468 @param d new IOBufferData this IOBufferBlock references. 00469 @param len in use area to set. It must be less than or equal to the 00470 length of the block size *IOBufferData). 00471 @param offset bytes to skip from the beginning of the IOBufferData 00472 and to mark its start. 00473 00474 */ 00475 void set(IOBufferData * d, int64_t len = 0, int64_t offset = 0); 00476 void set_internal(void *b, int64_t len, int64_t asize_index); 00477 void realloc_set_internal(void *b, int64_t buf_size, int64_t asize_index); 00478 void realloc(void *b, int64_t buf_size); 00479 void realloc(int64_t i); 00480 void realloc_xmalloc(void *b, int64_t buf_size); 00481 void realloc_xmalloc(int64_t buf_size); 00482 00483 /** 00484 Frees the IOBufferBlock object and its underlying memory. 00485 Removes the reference to the IOBufferData object and then frees 00486 itself. You should not use this object or reference after this 00487 call. 00488 00489 */ 00490 virtual void free(); 00491 00492 char *_start; 00493 char *_end; 00494 char *_buf_end; 00495 00496 #ifdef TRACK_BUFFER_USER 00497 const char *_location; 00498 #endif 00499 00500 /** 00501 The underlying reference to the allocated memory. A reference to a 00502 IOBufferData representing the memory allocated to this buffer. Do 00503 not set or modify its value directly. 00504 00505 */ 00506 Ptr<IOBufferData> data; 00507 00508 /** 00509 Reference to another IOBufferBlock. A reference to another 00510 IOBufferBlock that allows this object to link to other. 00511 00512 */ 00513 Ptr<IOBufferBlock> next; 00514 00515 /** 00516 Constructor of a IOBufferBlock. Do not use it to create a new object, 00517 instead call new_IOBufferBlock 00518 00519 */ 00520 IOBufferBlock(); 00521 00522 private: 00523 IOBufferBlock(const IOBufferBlock &); 00524 IOBufferBlock & operator =(const IOBufferBlock &); 00525 }; 00526 00527 extern inkcoreapi ClassAllocator<IOBufferBlock> ioBlockAllocator; 00528 00529 /** 00530 An independent reader from an MIOBuffer. A reader for a set of 00531 IOBufferBlocks. The IOBufferReader represents the place where a given 00532 consumer of buffer data is reading from. It provides a uniform interface 00533 for easily accessing the data contained in a list of IOBufferBlocks 00534 associated with the IOBufferReader. 00535 00536 IOBufferReaders are the abstraction that determine when data blocks 00537 can be removed from the buffer. 00538 00539 */ 00540 class IOBufferReader 00541 { 00542 public: 00543 00544 /** 00545 Start of unconsumed data. Returns a pointer to first unconsumed data 00546 on the buffer for this reader. A null pointer indicates no data is 00547 available. It uses the current start_offset value. 00548 00549 @return pointer to the start of the unconsumed data. 00550 00551 */ 00552 char *start(); 00553 00554 /** 00555 End of inuse area of the first block with unconsumed data. Returns a 00556 pointer to the end of the first block with unconsumed data for this 00557 reader. A NULL pointer indicates there are no blocks with unconsumed 00558 data for this reader. 00559 00560 @return pointer to the end of the first block with unconsumed data. 00561 00562 */ 00563 char *end(); 00564 00565 /** 00566 Amount of data available across all of the IOBufferBlocks. Returns the 00567 number of unconsumed bytes of data available to this reader across 00568 all remaining IOBufferBlocks. It subtracts the current start_offset 00569 value from the total. 00570 00571 @return bytes of data available across all the buffers. 00572 00573 */ 00574 int64_t read_avail(); 00575 00576 /** Check if there is more than @a size bytes available to read. 00577 @return @c true if more than @a size byte are available. 00578 */ 00579 bool is_read_avail_more_than(int64_t size); 00580 00581 00582 /** 00583 Number of IOBufferBlocks with data in the block list. Returns the 00584 number of IOBufferBlocks on the block list with data remaining for 00585 this reader. 00586 00587 @return number of blocks with data for this reader. 00588 00589 */ 00590 int block_count(); 00591 00592 /** 00593 Amount of data available in the first buffer with data for this 00594 reader. Returns the number of unconsumed bytes of data available 00595 on the first IOBufferBlock with data for this reader. 00596 00597 @return number of unconsumed bytes of data available in the first 00598 buffer. 00599 00600 */ 00601 int64_t block_read_avail(); 00602 00603 void skip_empty_blocks(); 00604 00605 /** 00606 Clears all fields in this IOBuffeReader, rendering it unusable. Drops 00607 the reference to the IOBufferBlock list, the accesor, MIOBuffer and 00608 resets this reader's state. You have to set those fields in order 00609 to use this object again. 00610 00611 */ 00612 void clear(); 00613 00614 /** 00615 Instruct the reader to reset the IOBufferBlock list. Resets the 00616 reader to the point to the start of the block where new data will 00617 be written. After this call, the start_offset field is set to zero 00618 and the list of IOBufferBlocks is set using the associated MIOBuffer. 00619 00620 */ 00621 void reset(); 00622 00623 /** 00624 Consume a number of bytes from this reader's IOBufferBlock 00625 list. Advances the current position in the IOBufferBlock list of 00626 this reader by n bytes. 00627 00628 @param n number of bytes to consume. It must be less than or equal 00629 to read_avail(). 00630 00631 */ 00632 void consume(int64_t n); 00633 00634 /** 00635 Create another reader with access to the same data as this 00636 IOBufferReader. Allocates a new reader with the same state as this 00637 IOBufferReader. This means that the new reader will point to the same 00638 list of IOBufferBlocks and to the same buffer position as this reader. 00639 00640 @return new reader with the same state as this. 00641 00642 */ 00643 IOBufferReader *clone(); 00644 00645 /** 00646 Deallocate this reader. Removes and deallocates this reader from 00647 the underlying MIOBuffer. This IOBufferReader object must not be 00648 used after this call. 00649 00650 */ 00651 void dealloc(); 00652 00653 /** 00654 Get a pointer to the first block with data. Returns a pointer to 00655 the first IOBufferBlock in the block chain with data available for 00656 this reader 00657 00658 @return pointer to the first IOBufferBlock in the list with data 00659 available for this reader. 00660 00661 */ 00662 IOBufferBlock *get_current_block(); 00663 00664 /** 00665 Consult this reader's MIOBuffer writable space. Queries the MIOBuffer 00666 associated with this reader about the amount of writable space 00667 available without adding any blocks on the buffer and returns true 00668 if it is less than the water mark. 00669 00670 @return true if the MIOBuffer associated with this IOBufferReader 00671 returns true in MIOBuffer::current_low_water(). 00672 00673 */ 00674 bool current_low_water(); 00675 00676 /** 00677 Queries the underlying MIOBuffer about. Returns true if the amount 00678 of writable space after adding a block on the underlying MIOBuffer 00679 is less than its water mark. This function call may add blocks to 00680 the MIOBuffer (see MIOBuffer::low_water()). 00681 00682 @return result of MIOBuffer::low_water() on the MIOBuffer for 00683 this reader. 00684 00685 */ 00686 bool low_water(); 00687 00688 /** 00689 To see if the amount of data available to the reader is greater than 00690 the MIOBuffer's water mark. Indicates whether the amount of data 00691 available to this reader exceeds the water mark for this reader's 00692 MIOBuffer. 00693 00694 @return true if the amount of data exceeds the MIOBuffer's water mark. 00695 00696 */ 00697 bool high_water(); 00698 00699 /** 00700 Perform a memchr() across the list of IOBufferBlocks. Returns the 00701 offset from the current start point of the reader to the first 00702 occurence of character 'c' in the buffer. 00703 00704 @param c character to look for. 00705 @param len number of characters to check. If len exceeds the number 00706 of bytes available on the buffer or INT64_MAX is passed in, the 00707 number of bytes available to the reader is used. It is independent 00708 of the offset value. 00709 @param offset number of the bytes to skip over before beginning 00710 the operation. 00711 @return -1 if c is not found, otherwise position of the first 00712 ocurrence. 00713 00714 */ 00715 inkcoreapi int64_t memchr(char c, int64_t len = INT64_MAX, int64_t offset = 0); 00716 00717 /** 00718 Copies and consumes data. Copies len bytes of data from the buffer 00719 into the supplied buffer, which must be allocated prior to the call 00720 and it must be at large enough for the requested bytes. Once the 00721 data is copied, it consumed from the reader. 00722 00723 @param buf in which to place the data. 00724 @param len bytes to copy and consume. If 'len' exceeds the bytes 00725 available to the reader, the number of bytes available is used 00726 instead. 00727 00728 @return number of bytes copied and consumed. 00729 00730 */ 00731 inkcoreapi int64_t read(void *buf, int64_t len); 00732 00733 /** 00734 Copy data but do not consume it. Copies 'len' bytes of data from 00735 the current buffer into the supplied buffer. The copy skips the 00736 number of bytes specified by 'offset' beyond the current point of 00737 the reader. It also takes into account the current start_offset value. 00738 00739 @param buf in which to place the data. The pointer is modified after 00740 the call and points one position after the end of the data copied. 00741 @param len bytes to copy. If len exceeds the bytes available to the 00742 reader or INT64_MAX is passed in, the number of bytes available is 00743 used instead. No data is consumed from the reader in this operation. 00744 @param offset bytes to skip from the current position. The parameter 00745 is modified after the call. 00746 @return pointer to one position after the end of the data copied. The 00747 parameter buf is set to this value also. 00748 00749 */ 00750 inkcoreapi char *memcpy(const void *buf, int64_t len = INT64_MAX, int64_t offset = 0); 00751 00752 /** 00753 Subscript operator. Returns a reference to the character at the 00754 specified position. You must ensure that it is within an appropriate 00755 range. 00756 00757 @param i positions beyond the current point of the reader. It must 00758 be less than the number of the bytes available to the reader. 00759 00760 @return reference to the character in that position. 00761 00762 */ 00763 char &operator[] (int64_t i); 00764 00765 MIOBuffer *writer() const { return mbuf; } 00766 MIOBuffer *allocated() const { return mbuf; } 00767 00768 MIOBufferAccessor *accessor; // pointer back to the accessor 00769 00770 /** 00771 Back pointer to this object's MIOBuffer. A pointer back to the 00772 MIOBuffer this reader is allocated from. 00773 00774 */ 00775 MIOBuffer *mbuf; 00776 Ptr<IOBufferBlock> block; 00777 00778 /** 00779 Offset beyond the shared start(). The start_offset is used in the 00780 calls that copy or consume data and is an offset at the beginning 00781 of the available data. 00782 00783 */ 00784 int64_t start_offset; 00785 int64_t size_limit; 00786 00787 IOBufferReader() 00788 : accessor(NULL), mbuf(NULL), start_offset(0), size_limit(INT64_MAX) 00789 { } 00790 }; 00791 00792 /** 00793 A multiple reader, single writer memory buffer. MIOBuffers are at 00794 the center of all IOCore data transfer. MIOBuffers are the data 00795 buffers used to transfer data to and from VConnections. A MIOBuffer 00796 points to a list of IOBufferBlocks which in turn point to IOBufferData 00797 structures that in turn point to the actual data. MIOBuffer allows one 00798 producer and multiple consumers. The buffer fills up according the 00799 amount of data outstanding for the slowest consumer. Thus, MIOBuffer 00800 implements automatic flow control between readers of different speeds. 00801 Data on IOBuffer is immutable. Once written it cannot be modified, only 00802 deallocated once all consumers have finished with it. Immutability is 00803 necessary since data can be shared between buffers, which means that 00804 multiple IOBufferBlock objects may reference the same data but only 00805 one will have ownership for writing. 00806 00807 */ 00808 class MIOBuffer 00809 { 00810 public: 00811 00812 /** 00813 Increase writer's inuse area. Instructs the writer associated with 00814 this MIOBuffer to increase the inuse area of the block by as much as 00815 'len' bytes. 00816 00817 @param len number of bytes to add to the inuse area of the block. 00818 00819 */ 00820 void fill(int64_t len); 00821 00822 /** 00823 Adds a block to the end of the block list. The block added to list 00824 must be writable by this buffer and must not be writable by any 00825 other buffer. 00826 00827 */ 00828 void append_block(IOBufferBlock * b); 00829 00830 /** 00831 Adds a new block to the end of the block list. The size is determined 00832 by asize_index. See the remarks section for a mapping of indexes to 00833 buffer block sizes. 00834 00835 */ 00836 void append_block(int64_t asize_index); 00837 00838 /** 00839 Adds new block to the end of block list using the block size for 00840 the buffer specified when the buffer was allocated. 00841 00842 */ 00843 void add_block(); 00844 00845 /** 00846 Adds by reference len bytes of data pointed to by b to the end 00847 of the buffer. b MUST be a pointer to the beginning of block 00848 allocated from the ats_xmalloc() routine. The data will be deallocated 00849 by the buffer once all readers on the buffer have consumed it. 00850 00851 */ 00852 void append_xmalloced(void *b, int64_t len); 00853 00854 /** 00855 Adds by reference len bytes of data pointed to by b to the end of the 00856 buffer. b MUST be a pointer to the beginning of block allocated from 00857 ioBufAllocator of the corresponding index for fast_size_index. The 00858 data will be deallocated by the buffer once all readers on the buffer 00859 have consumed it. 00860 00861 */ 00862 void append_fast_allocated(void *b, int64_t len, int64_t fast_size_index); 00863 00864 /** 00865 Adds the nbytes worth of data pointed by rbuf to the buffer. The 00866 data is copied into the buffer. write() does not respect watermarks 00867 or buffer size limits. Users of write must implement their own flow 00868 control. Returns the number of bytes added. 00869 00870 */ 00871 inkcoreapi int64_t write(const void *rbuf, int64_t nbytes); 00872 00873 #ifdef WRITE_AND_TRANSFER 00874 /** 00875 Same functionality as write but for the one small difference. The 00876 space available in the last block is taken from the original and 00877 this space becomes available to the copy. 00878 00879 */ 00880 inkcoreapi int64_t write_and_transfer_left_over_space(IOBufferReader * r, int64_t len = INT64_MAX, int64_t offset = 0); 00881 #endif 00882 00883 /** 00884 Add by data from IOBufferReader r to the this buffer by reference. If 00885 len is INT64_MAX, all available data on the reader is added. If len is 00886 less than INT64_MAX, the smaller of len or the amount of data on the 00887 buffer is added. If offset is greater than zero, than the offset 00888 bytes of data at the front of the reader are skipped. Bytes skipped 00889 by offset reduce the number of bytes available on the reader used 00890 in the amount of data to add computation. write() does not respect 00891 watermarks or buffer size limits. Users of write must implement 00892 their own flow control. Returns the number of bytes added. Each 00893 write() call creates a new IOBufferBlock, even if it is for one 00894 byte. As such, it's necessary to exercise caution in any code that 00895 repeatedly transfers data from one buffer to another, especially if 00896 the data is being read over the network as it may be coming in very 00897 small chunks. Because deallocation of outstanding buffer blocks is 00898 recursive, it's possible to overrun the stack if too many blocks 00899 have been added to the buffer chain. It's imperative that users 00900 both implement their own flow control to prevent too many bytes 00901 from becoming outstanding on a buffer that the write() call is 00902 being used and that care be taken to ensure the transfers are of a 00903 minimum size. Should it be necessary to make a large number of small 00904 transfers, it's preferable to use a interface that copies the data 00905 rather than sharing blocks to prevent a build of blocks on the buffer. 00906 00907 */ 00908 inkcoreapi int64_t write(IOBufferReader * r, int64_t len = INT64_MAX, int64_t offset = 0); 00909 00910 int64_t remove_append(IOBufferReader *); 00911 00912 /** 00913 Returns a pointer to the first writable block on the block chain. 00914 Returns NULL if there are not currently any writable blocks on the 00915 block list. 00916 00917 */ 00918 IOBufferBlock *first_write_block() 00919 { 00920 if (_writer) { 00921 if (_writer->next && !_writer->write_avail()) 00922 return _writer->next; 00923 ink_assert(!_writer->next || !_writer->next->read_avail()); 00924 return _writer; 00925 } else 00926 return NULL; 00927 } 00928 00929 00930 char *buf() 00931 { 00932 IOBufferBlock *b = first_write_block(); 00933 return b ? b->buf() : 0; 00934 } 00935 char *buf_end() 00936 { 00937 return first_write_block()->buf_end(); 00938 } 00939 char *start() 00940 { 00941 return first_write_block()->start(); 00942 } 00943 char *end() 00944 { 00945 return first_write_block()->end(); 00946 } 00947 00948 /** 00949 Returns the amount of space of available for writing on the first 00950 writable block on the block chain (the one that would be reutrned 00951 by first_write_block()). 00952 00953 */ 00954 int64_t block_write_avail(); 00955 00956 /** 00957 Returns the amount of space of available for writing on all writable 00958 blocks currently on the block chain. Will NOT add blocks to the 00959 block chain. 00960 00961 */ 00962 int64_t current_write_avail(); 00963 00964 /** 00965 Adds blocks for writing if the watermark criteria are met. Returns 00966 the amount of space of available for writing on all writable blocks 00967 on the block chain after a block due to the watermark criteria. 00968 00969 */ 00970 int64_t write_avail(); 00971 00972 /** 00973 Returns the default data block size for this buffer. 00974 00975 */ 00976 int64_t block_size(); 00977 00978 /** 00979 Returns the default data block size for this buffer. 00980 00981 */ 00982 int64_t total_size() 00983 { 00984 return block_size(); 00985 } 00986 00987 /** 00988 Returns true if amount of the data outstanding on the buffer exceeds 00989 the watermark. 00990 00991 */ 00992 bool high_water() 00993 { 00994 return max_read_avail() > water_mark; 00995 } 00996 00997 /** 00998 Returns true if the amount of writable space after adding a block on 00999 the buffer is less than the water mark. Since this function relies 01000 on write_avail() it may add blocks. 01001 01002 */ 01003 bool low_water() 01004 { 01005 return write_avail() <= water_mark; 01006 } 01007 01008 /** 01009 Returns true if amount the amount writable space without adding and 01010 blocks on the buffer is less than the water mark. 01011 01012 */ 01013 bool current_low_water() 01014 { 01015 return current_write_avail() <= water_mark; 01016 } 01017 void set_size_index(int64_t size); 01018 01019 /** 01020 Allocates a new IOBuffer reader and sets it's its 'accessor' field 01021 to point to 'anAccessor'. 01022 01023 */ 01024 IOBufferReader *alloc_accessor(MIOBufferAccessor * anAccessor); 01025 01026 /** 01027 Allocates an IOBufferReader for this buffer. IOBufferReaders hold 01028 data on the buffer for different consumers. IOBufferReaders are 01029 REQUIRED when using buffer. alloc_reader() MUST ONLY be a called 01030 on newly allocated buffers. Calling on a buffer with data already 01031 placed on it will result in the reader starting at an indeterminate 01032 place on the buffer. 01033 01034 */ 01035 IOBufferReader *alloc_reader(); 01036 01037 /** 01038 Allocates a new reader on this buffer and places it's starting 01039 point at the same place as reader r. r MUST be a pointer to a reader 01040 previous allocated from this buffer. 01041 01042 */ 01043 IOBufferReader *clone_reader(IOBufferReader * r); 01044 01045 /** 01046 Deallocates reader e from this buffer. e MUST be a pointer to a reader 01047 previous allocated from this buffer. Reader need to allocated when a 01048 particularly consumer is being removed from the buffer but the buffer 01049 is still in use. Deallocation is not necessary when the buffer is 01050 being freed as all outstanding readers are automatically deallocated. 01051 01052 */ 01053 void dealloc_reader(IOBufferReader * e); 01054 01055 /** 01056 Deallocates all outstanding readers on the buffer. 01057 01058 */ 01059 void dealloc_all_readers(); 01060 01061 void set(void *b, int64_t len); 01062 void set_xmalloced(void *b, int64_t len); 01063 void alloc(int64_t i = default_large_iobuffer_size); 01064 void alloc_xmalloc(int64_t buf_size); 01065 void append_block_internal(IOBufferBlock * b); 01066 int64_t puts(char *buf, int64_t len); 01067 01068 // internal interface 01069 01070 bool empty() 01071 { 01072 return !_writer; 01073 } 01074 int64_t max_read_avail(); 01075 01076 int max_block_count(); 01077 void check_add_block(); 01078 01079 IOBufferBlock *get_current_block(); 01080 01081 void reset() 01082 { 01083 if (_writer) { 01084 _writer->reset(); 01085 } 01086 for (int j = 0; j < MAX_MIOBUFFER_READERS; j++) 01087 if (readers[j].allocated()) { 01088 readers[j].reset(); 01089 } 01090 } 01091 01092 void init_readers() 01093 { 01094 for (int j = 0; j < MAX_MIOBUFFER_READERS; j++) 01095 if (readers[j].allocated() && !readers[j].block) 01096 readers[j].block = _writer; 01097 } 01098 01099 void dealloc() 01100 { 01101 _writer = NULL; 01102 dealloc_all_readers(); 01103 } 01104 01105 void clear() 01106 { 01107 dealloc(); 01108 size_index = BUFFER_SIZE_NOT_ALLOCATED; 01109 water_mark = 0; 01110 } 01111 01112 void realloc(int64_t i) 01113 { 01114 _writer->realloc(i); 01115 } 01116 void realloc(void *b, int64_t buf_size) 01117 { 01118 _writer->realloc(b, buf_size); 01119 } 01120 void realloc_xmalloc(void *b, int64_t buf_size) 01121 { 01122 _writer->realloc_xmalloc(b, buf_size); 01123 } 01124 void realloc_xmalloc(int64_t buf_size) 01125 { 01126 _writer->realloc_xmalloc(buf_size); 01127 } 01128 01129 int64_t size_index; 01130 01131 /** 01132 Determines when to stop writing or reading. The watermark is the 01133 level to which the producer (filler) is required to fill the buffer 01134 before it can expect the reader to consume any data. A watermark 01135 of zero means that the reader will consume any amount of data, 01136 no matter how small. 01137 01138 */ 01139 int64_t water_mark; 01140 01141 Ptr<IOBufferBlock> _writer; 01142 IOBufferReader readers[MAX_MIOBUFFER_READERS]; 01143 01144 #ifdef TRACK_BUFFER_USER 01145 const char *_location; 01146 #endif 01147 01148 MIOBuffer(void *b, int64_t bufsize, int64_t aWater_mark); 01149 MIOBuffer(int64_t default_size_index); 01150 MIOBuffer(); 01151 ~MIOBuffer(); 01152 }; 01153 01154 /** 01155 A wrapper for either a reader or a writer of an MIOBuffer. 01156 01157 */ 01158 struct MIOBufferAccessor 01159 { 01160 IOBufferReader * reader() { 01161 return entry; 01162 } 01163 01164 MIOBuffer * writer() { 01165 return mbuf; 01166 } 01167 01168 int64_t block_size() const { 01169 return mbuf->block_size(); 01170 } 01171 01172 int64_t total_size() const { 01173 return block_size(); 01174 } 01175 01176 void reader_for(IOBufferReader * abuf); 01177 void reader_for(MIOBuffer * abuf); 01178 void writer_for(MIOBuffer * abuf); 01179 01180 void clear() { 01181 mbuf = NULL; 01182 entry = NULL; 01183 } 01184 01185 MIOBufferAccessor(): 01186 #ifdef DEBUG 01187 name(NULL), 01188 #endif 01189 mbuf(NULL), entry(NULL) 01190 { 01191 } 01192 01193 ~MIOBufferAccessor(); 01194 01195 #ifdef DEBUG 01196 const char * name; 01197 #endif 01198 01199 private: 01200 MIOBufferAccessor(const MIOBufferAccessor &); 01201 MIOBufferAccessor & operator =(const MIOBufferAccessor &); 01202 01203 MIOBuffer *mbuf; 01204 IOBufferReader *entry; 01205 01206 }; 01207 01208 extern MIOBuffer * new_MIOBuffer_internal( 01209 #ifdef TRACK_BUFFER_USER 01210 const char *loc, 01211 #endif 01212 int64_t size_index = default_large_iobuffer_size); 01213 01214 #ifdef TRACK_BUFFER_USER 01215 class MIOBuffer_tracker 01216 { 01217 const char *loc; 01218 01219 public: 01220 MIOBuffer_tracker(const char *_loc):loc(_loc) 01221 { 01222 } 01223 MIOBuffer *operator() (int64_t size_index = default_large_iobuffer_size) { 01224 return new_MIOBuffer_internal(loc, size_index); 01225 } 01226 01227 }; 01228 #endif 01229 01230 extern MIOBuffer * new_empty_MIOBuffer_internal( 01231 #ifdef TRACK_BUFFER_USER 01232 const char *loc, 01233 #endif 01234 int64_t size_index = default_large_iobuffer_size); 01235 01236 #ifdef TRACK_BUFFER_USER 01237 class Empty_MIOBuffer_tracker 01238 { 01239 const char *loc; 01240 01241 public: 01242 Empty_MIOBuffer_tracker(const char *_loc):loc(_loc) 01243 { 01244 } 01245 MIOBuffer *operator() (int64_t size_index = default_large_iobuffer_size) { 01246 return new_empty_MIOBuffer_internal(loc, size_index); 01247 } 01248 }; 01249 #endif 01250 01251 /// MIOBuffer allocator/deallocator 01252 #ifdef TRACK_BUFFER_USER 01253 #define new_MIOBuffer MIOBuffer_tracker(RES_PATH("memory/IOBuffer/")) 01254 #define new_empty_MIOBuffer Empty_MIOBuffer_tracker(RES_PATH("memory/IOBuffer/")) 01255 #else 01256 #define new_MIOBuffer new_MIOBuffer_internal 01257 #define new_empty_MIOBuffer new_empty_MIOBuffer_internal 01258 #endif 01259 extern void free_MIOBuffer(MIOBuffer * mio); 01260 ////////////////////////////////////////////////////////////////////// 01261 01262 extern IOBufferBlock * new_IOBufferBlock_internal( 01263 #ifdef TRACK_BUFFER_USER 01264 const char *loc 01265 #endif 01266 ); 01267 01268 extern IOBufferBlock * new_IOBufferBlock_internal( 01269 #ifdef TRACK_BUFFER_USER 01270 const char *loc, 01271 #endif 01272 IOBufferData * d, int64_t len = 0, int64_t offset = 0); 01273 01274 #ifdef TRACK_BUFFER_USER 01275 class IOBufferBlock_tracker 01276 { 01277 const char *loc; 01278 01279 public: 01280 IOBufferBlock_tracker(const char *_loc):loc(_loc) 01281 { 01282 } 01283 IOBufferBlock *operator() () 01284 { 01285 return new_IOBufferBlock_internal(loc); 01286 } 01287 IOBufferBlock *operator() (IOBufferData * d, int64_t len = 0, int64_t offset = 0) { 01288 return new_IOBufferBlock_internal(loc, d, len, offset); 01289 } 01290 01291 }; 01292 #endif 01293 01294 /// IOBufferBlock allocator 01295 #ifdef TRACK_BUFFER_USER 01296 #define new_IOBufferBlock IOBufferBlock_tracker(RES_PATH("memory/IOBuffer/")) 01297 #else 01298 #define new_IOBufferBlock new_IOBufferBlock_internal 01299 #endif 01300 //////////////////////////////////////////////////////////// 01301 01302 extern IOBufferData *new_IOBufferData_internal( 01303 #ifdef TRACK_BUFFER_USER 01304 const char *location, 01305 #endif 01306 int64_t size_index = default_large_iobuffer_size, 01307 AllocType type = DEFAULT_ALLOC); 01308 01309 extern IOBufferData *new_xmalloc_IOBufferData_internal( 01310 #ifdef TRACK_BUFFER_USER 01311 const char *location, 01312 #endif 01313 void *b, int64_t size); 01314 01315 extern IOBufferData *new_constant_IOBufferData_internal( 01316 #ifdef TRACK_BUFFER_USER 01317 const char *locaction, 01318 #endif 01319 void *b, int64_t size); 01320 01321 #ifdef TRACK_BUFFER_USER 01322 class IOBufferData_tracker 01323 { 01324 const char *loc; 01325 01326 public: 01327 IOBufferData_tracker(const char *_loc):loc(_loc) 01328 { 01329 } 01330 IOBufferData *operator() (int64_t size_index = default_large_iobuffer_size, AllocType type = DEFAULT_ALLOC) { 01331 return new_IOBufferData_internal(loc, size_index, type); 01332 } 01333 01334 }; 01335 #endif 01336 01337 #ifdef TRACK_BUFFER_USER 01338 #define new_IOBufferData IOBufferData_tracker(RES_PATH("memory/IOBuffer/")) 01339 #define new_xmalloc_IOBufferData(b, size) \ 01340 new_xmalloc_IOBufferData_internal(RES_PATH("memory/IOBuffer/"), \ 01341 (b), (size)) 01342 #define new_constant_IOBufferData(b, size) \ 01343 new_constant_IOBufferData_internal(RES_PATH("memory/IOBuffer/"), \ 01344 (b), (size)) 01345 #else 01346 #define new_IOBufferData new_IOBufferData_internal 01347 #define new_xmalloc_IOBufferData new_xmalloc_IOBufferData_internal 01348 #define new_constant_IOBufferData new_constant_IOBufferData_internal 01349 #endif 01350 01351 extern int64_t iobuffer_size_to_index(int64_t size, int64_t max = max_iobuffer_size); 01352 extern int64_t index_to_buffer_size(int64_t idx); 01353 /** 01354 Clone a IOBufferBlock chain. Used to snarf a IOBufferBlock chain 01355 w/o copy. 01356 01357 @param b head of source IOBufferBlock chain. 01358 @param offset # bytes in the beginning to skip. 01359 @param len bytes to copy from source. 01360 @return ptr to head of new IOBufferBlock chain. 01361 01362 */ 01363 extern IOBufferBlock *iobufferblock_clone(IOBufferBlock * b, int64_t offset, int64_t len); 01364 /** 01365 Skip over specified bytes in chain. Used for dropping references. 01366 01367 @param b head of source IOBufferBlock chain. 01368 @param poffset originally offset in b, finally offset in returned 01369 IOBufferBlock. 01370 @param plen value of write is subtracted from plen in the function. 01371 @param write bytes to skip. 01372 @return ptr to head of new IOBufferBlock chain. 01373 01374 */ 01375 extern IOBufferBlock *iobufferblock_skip(IOBufferBlock * b, int64_t *poffset, int64_t *plen, int64_t write); 01376 #endif