CircularBuffer.h

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/common/CircularBuffer.h#5 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2005-2009 SQLstream, Inc.
00006 // Copyright (C) 2005-2009 LucidEra, Inc.
00007 // Portions Copyright (C) 1999-2009 John V. Sichi
00008 //
00009 // This program is free software; you can redistribute it and/or modify it
00010 // under the terms of the GNU General Public License as published by the Free
00011 // Software Foundation; either version 2 of the License, or (at your option)
00012 // any later version approved by The Eigenbase Project.
00013 //
00014 // This program is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with this program; if not, write to the Free Software
00021 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 */
00023 
00024 #ifndef Fennel_CircularBuffer_Included
00025 #define Fennel_CircularBuffer_Included
00026 
00027 FENNEL_BEGIN_NAMESPACE
00028 
00033 template <class T>
00034 class CircularBuffer
00035 {
00039     std::vector<T> buffer;
00040 
00044     uint nEntries;
00045 
00049     uint nFreeEntries;
00050 
00056     uint firstPos;
00057 
00061     bool readOnly;
00062 
00068     void init(uint nEntriesInit)
00069     {
00070         nEntries = nEntriesInit;
00071         buffer.resize(nEntries);
00072         clear();
00073     }
00074 
00075 public:
00076     explicit CircularBuffer()
00077     {
00078         init(0);
00079     }
00080 
00081     explicit CircularBuffer(uint nEntriesInit)
00082     {
00083         init(nEntriesInit);
00084     }
00085 
00089     void clear()
00090     {
00091         firstPos = 0;
00092         nFreeEntries = nEntries;
00093         readOnly = false;
00094     }
00095 
00103     void resize(uint nEntriesInit)
00104     {
00105         init(nEntriesInit);
00106     }
00107 
00111     uint size()
00112     {
00113         return nEntries;
00114     }
00115 
00119     bool empty()
00120     {
00121         return (nFreeEntries == nEntries);
00122     }
00123 
00127     bool spaceAvailable()
00128     {
00129         return (nFreeEntries != 0);
00130     }
00131 
00135     uint nFreeSpace()
00136     {
00137         return nFreeEntries;
00138     }
00139 
00143     uint getFirstPos()
00144     {
00145         assert(!empty());
00146         return firstPos;
00147     }
00148 
00152     uint getLastPos()
00153     {
00154         return nEntries - nFreeEntries + firstPos - 1;
00155     }
00156 
00160     T &reference_back()
00161     {
00162         assert(!empty());
00163         uint lastEntry = getLastPos() % nEntries;
00164         return buffer[lastEntry];
00165     }
00166 
00170     void push_back(T &newEntry)
00171     {
00172         assert(!readOnly);
00173         assert(nFreeEntries > 0);
00174         uint freeEntry = (nEntries - nFreeEntries + firstPos) % nEntries;
00175         buffer[freeEntry] = newEntry;
00176         nFreeEntries--;
00177     }
00178 
00182     T &reference_front()
00183     {
00184         assert(!empty());
00185         return buffer[firstPos % nEntries];
00186     }
00187 
00191     void pop_front()
00192     {
00193         assert(!empty());
00194         firstPos++;
00195         nFreeEntries++;
00196     }
00197 
00205     T & operator [] (uint pos)
00206     {
00207         return buffer[pos % nEntries];
00208     }
00209 
00213     bool isReadOnly()
00214     {
00215         return readOnly;
00216     }
00217 
00221     void setReadOnly()
00222     {
00223         readOnly = true;
00224     }
00225 };
00226 
00236 template <class T>
00237 class CircularBufferIter
00238 {
00242     CircularBuffer<T> *pCircularBuffer;
00243 
00248     uint currPos;
00249 
00250 public:
00251 
00252     explicit CircularBufferIter(CircularBuffer<T> *pCircularBufferInit)
00253     {
00254         pCircularBuffer = pCircularBufferInit;
00255         reset();
00256     }
00257 
00261     void reset()
00262     {
00263         currPos = 0;
00264     }
00265 
00269     void operator ++ ()
00270     {
00271         assert(!pCircularBuffer->empty());
00272         currPos++;
00273     }
00274 
00278     T & operator * ()
00279     {
00280         assert(!pCircularBuffer->empty());
00281         assert(
00282             currPos >= pCircularBuffer->getFirstPos() &&
00283             currPos <= pCircularBuffer->getLastPos());
00284         return (*pCircularBuffer)[currPos];
00285     }
00286 
00291     bool end()
00292     {
00293         return
00294             (pCircularBuffer->empty() ||
00295                 currPos > pCircularBuffer->getLastPos());
00296     }
00297 
00302     bool done()
00303     {
00304         return end() && pCircularBuffer->isReadOnly();
00305     }
00306 
00310     uint getCurrPos()
00311     {
00312         return currPos;
00313     }
00314 
00320     void setCurrPos(uint pos)
00321     {
00322         currPos = pos;
00323     }
00324 
00328     void removeFront()
00329     {
00330         pCircularBuffer->pop_front();
00331     }
00332 };
00333 
00334 FENNEL_END_NAMESPACE
00335 
00336 #endif
00337 
00338 // End CircularBuffer.h

Generated on Mon Jun 22 04:00:18 2009 for Fennel by  doxygen 1.5.1