• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

I_IOBuffer.h

Go to the documentation of this file.
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

Generated by  doxygen 1.7.1