00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #if ! defined ( RINGBUFFER_HH )
00025 #define RINGBUFFER_HH
00026
00027 namespace PIAVE {
00028
00029
00030
00031
00032
00033 template< class V >
00034 class PtrRingBuffer
00035 {
00036 public:
00037 PtrRingBuffer( size_t s = 128 );
00038 ~PtrRingBuffer();
00039
00040 void push( const V * v );
00041 const V * pop();
00042 int remove( const V * v );
00043 bool isEmpty() const { return _head==_tail; }
00044 bool isFull() const { int h=_head; inc(h); return h==_tail; }
00045
00046 private:
00047 void inc( int & i ) const { if ( ++i == _size ) i = 0; }
00048
00049 private:
00050 const V ** _buffer;
00051 int _head;
00052 int _tail;
00053 int _size;
00054 };
00055
00056 template< class V >
00057 PtrRingBuffer<V>::PtrRingBuffer( size_t s ) :
00058 _buffer( new const V*[s] ),
00059 _head( 0 ),
00060 _tail( 0 ),
00061 _size( s )
00062 {
00063 }
00064
00065 template< class V >
00066 PtrRingBuffer<V>::~PtrRingBuffer()
00067 {
00068 if ( _buffer ) delete [] _buffer;
00069 }
00070
00071 template< class V >
00072 void
00073 PtrRingBuffer<V>::push( const V * v )
00074 {
00075 if ( isFull() ) {
00076
00077 } else {
00078 _buffer[ _head ] = v;
00079 inc( _head );
00080 }
00081
00082 return;
00083 }
00084
00085 template< class V >
00086 const V *
00087 PtrRingBuffer<V>::pop()
00088 {
00089
00090 while ( _buffer[ _tail ] == 0 &&
00091 _tail != _head )
00092 {
00093 inc( _tail );
00094 }
00095
00096
00097 if ( isEmpty() ) return 0;
00098
00099 const V * ret = _buffer[ _tail ];
00100 _buffer[ _tail ] = 0;
00101
00102 inc( _tail );
00103
00104 return ret;
00105 }
00106
00107 template< class V >
00108 int
00109 PtrRingBuffer<V>::remove( const V * v )
00110 {
00111 if ( isEmpty() ) return 0;
00112 int n = 0;
00113 for ( int i=_tail; i!=_head; inc(i) )
00114 {
00115 if ( _buffer[ i ] != 0 ) {
00116 if ( *_buffer[ i ] == *v ) {
00117 delete _buffer[ i ];
00118 _buffer[ i ] = 0;
00119 n++;
00120 }
00121 }
00122 }
00123 return n;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 template< class V >
00139 class ValRingBuffer
00140 {
00141 public:
00142 ValRingBuffer( size_t s = 128 );
00143 ~ValRingBuffer();
00144
00145 void push( const V v );
00146 const V pop();
00147 bool isEmpty() const { return _head==_tail; }
00148 bool isFull() const { int h=_head; inc(h); return h==_tail; }
00149
00150 int getCurSize() const;
00151 int getN( int n, V * dest );
00152 int putN( int n, V * src );
00153 void clean() { _tail = _head; }
00154
00155 private:
00156 void inc( int & i ) const { if ( ++i == _size ) i = 0; }
00157
00158 private:
00159 V * _buffer;
00160 int _head;
00161 int _tail;
00162 int _size;
00163 };
00164
00165 template< class V >
00166 ValRingBuffer<V>::ValRingBuffer( size_t s ) :
00167 _buffer( new V[s] ),
00168 _head( 0 ),
00169 _tail( 0 ),
00170 _size( s )
00171 {
00172 }
00173
00174 template< class V >
00175 ValRingBuffer<V>::~ValRingBuffer()
00176 {
00177 if ( _buffer ) delete [] _buffer;
00178 }
00179
00180 template< class V >
00181 void
00182 ValRingBuffer<V>::push( const V v )
00183 {
00184 if ( isFull() ) {
00185
00186 } else {
00187 _buffer[ _head ] = v;
00188 inc( _head );
00189 }
00190
00191 return;
00192 }
00193
00194 template< class V >
00195 const V
00196 ValRingBuffer<V>::pop()
00197 {
00198
00199 if ( isEmpty() ) return 0;
00200
00201 const V ret = _buffer[ _tail ];
00202 _buffer[ _tail ] = 0;
00203
00204 inc( _tail );
00205
00206 return ret;
00207 }
00208
00209 template< class V >
00210 int
00211 ValRingBuffer<V>::getCurSize() const
00212 {
00213
00214 if (_tail>_head) return _size-_tail+_head;
00215
00216
00217 return _head-_tail;
00218 }
00219
00220 template< class V >
00221 int
00222 ValRingBuffer<V>::getN( int n, V * dest )
00223 {
00224 int nCopied = 0;
00225
00226
00227
00228 if (_tail==_head) return 0;
00229
00230
00231 if (_tail>_head)
00232 {
00233 int tail_chunk = _size-_tail;
00234 if ( n>tail_chunk )
00235 {
00236 memcpy( dest, _buffer+_tail, tail_chunk*sizeof(V) );
00237 nCopied = tail_chunk;
00238 int rest = 0;
00239 if ( n-tail_chunk<=_head)
00240 {
00241 rest = n-tail_chunk;
00242 _tail = rest;
00243 } else {
00244 rest = _head;
00245 _tail = _head;
00246 }
00247 memcpy( dest+tail_chunk, _buffer, rest*sizeof(V) );
00248 nCopied += rest;
00249 } else {
00250 memcpy( dest, _buffer+_tail, n*sizeof(V) );
00251 nCopied = n;
00252 _tail+=n;
00253 if ( _tail==_size ) _tail = 0;
00254 }
00255
00256 return nCopied;
00257 }
00258
00259
00260 int size = _head-_tail;
00261 int old_tail = _tail;
00262 if ( n>size )
00263 {
00264 nCopied = size;
00265 _tail = _head;
00266 } else {
00267 nCopied = n;
00268 _tail+=n;
00269 }
00270 memcpy( dest, _buffer+old_tail, nCopied*sizeof(V) );
00271
00272 if ( _tail==_size ) _tail = 0;
00273 return nCopied;
00274 }
00275
00276 template< class V >
00277 int
00278 ValRingBuffer<V>::putN( int n, V * src )
00279 {
00280 int curSize = getCurSize();
00281 int free = _size-curSize-1;
00282
00283
00284 if ( n>free ) return 0;
00285
00286
00287
00288
00289 int head_chunk = _size-_head;
00290 if ( n>head_chunk )
00291 {
00292 memcpy( _buffer+_head, src, head_chunk*sizeof(V) );
00293 memcpy( _buffer, src+head_chunk, (n-head_chunk)*sizeof(V) );
00294 _head = n-head_chunk;
00295 if ( _head==_size ) _head=0;
00296
00297 return n;
00298 }
00299
00300
00301 memcpy( _buffer+_head, src, n*sizeof(V) );
00302 _head += n;
00303 if ( _head==_size ) _head=0;
00304
00305
00306 return n;
00307 }
00308
00309 }
00310
00311 #endif