From 8c2c728ce5aa1c1941426d0f8e9ab27762ef6754 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 5 Jun 2007 18:46:01 +0000 Subject: Added a basic ringbuffer, it should be nice and quick, but may be bad to use with objects at the moment, still contemplating that one... --- src/list.h | 20 +++++----- src/ringbuffer.cpp | 2 + src/ringbuffer.h | 100 +++++++++++++++++++++++++++++++++++++++++++++++ src/tests/ringbuffer.cpp | 29 ++++++++++++++ 4 files changed, 141 insertions(+), 10 deletions(-) create mode 100644 src/ringbuffer.cpp create mode 100644 src/ringbuffer.h create mode 100644 src/tests/ringbuffer.cpp (limited to 'src') diff --git a/src/list.h b/src/list.h index 6081ea5..ea67f45 100644 --- a/src/list.h +++ b/src/list.h @@ -69,10 +69,10 @@ namespace Bu { if( pCur == NULL ) break; va.destroy( pCur->pValue ); - va.deallocate( pCur->pValue, sizeof( value ) ); + va.deallocate( pCur->pValue, 1 ); Link *pTmp = pCur->pNext; la.destroy( pCur ); - la.deallocate( pCur, sizeof( Link ) ); + la.deallocate( pCur, 1 ); pCur = pTmp; } pFirst = pLast = NULL; @@ -81,8 +81,8 @@ namespace Bu void append( const value &v ) { - Link *pNew = la.allocate( sizeof( Link ) ); - pNew->pValue = va.allocate( sizeof( value ) ); + Link *pNew = la.allocate( 1 ); + pNew->pValue = va.allocate( 1 ); va.construct( pNew->pValue, v ); nSize++; if( pFirst == NULL ) @@ -102,8 +102,8 @@ namespace Bu void prepend( const value &v ) { - Link *pNew = la.allocate( sizeof( Link ) ); - pNew->pValue = va.allocate( sizeof( value ) ); + Link *pNew = la.allocate( 1 ); + pNew->pValue = va.allocate( 1 ); va.construct( pNew->pValue, v ); nSize++; if( pFirst == NULL ) @@ -316,10 +316,10 @@ namespace Bu if( pPrev == NULL ) { va.destroy( pCur->pValue ); - va.deallocate( pCur->pValue, sizeof( value ) ); + va.deallocate( pCur->pValue, 1 ); pFirst = pCur->pNext; la.destroy( pCur ); - la.deallocate( pCur, sizeof( Link ) ); + la.deallocate( pCur, 1 ); if( pFirst == NULL ) pLast = NULL; nSize--; @@ -328,10 +328,10 @@ namespace Bu else { va.destroy( pCur->pValue ); - va.deallocate( pCur->pValue, sizeof( value ) ); + va.deallocate( pCur->pValue, 1 ); Link *pTmp = pCur->pNext; la.destroy( pCur ); - la.deallocate( pCur, sizeof( Link ) ); + la.deallocate( pCur, 1 ); pPrev->pNext = pTmp; if( pTmp != NULL ) pTmp->pPrev = pPrev; diff --git a/src/ringbuffer.cpp b/src/ringbuffer.cpp new file mode 100644 index 0000000..feb9bc7 --- /dev/null +++ b/src/ringbuffer.cpp @@ -0,0 +1,2 @@ +#include "bu/ringbuffer.h" + diff --git a/src/ringbuffer.h b/src/ringbuffer.h new file mode 100644 index 0000000..9480043 --- /dev/null +++ b/src/ringbuffer.h @@ -0,0 +1,100 @@ +#ifndef RING_BUFFER_H +#define RING_BUFFER_H + +#include +#include "bu/exceptionbase.h" + +namespace Bu +{ + template > + class RingBuffer + { + public: + RingBuffer( int nCapacity ) : + nCapacity( nCapacity ), + nStart( -1 ), + nEnd( -2 ) + { + aData = va.allocate( nCapacity ); + for( int j = 0; j < nCapacity; j++ ) + { + va.construct( &aData[j], value() ); + } + } + + virtual ~RingBuffer() + { + for( int j = 0; j < nCapacity; j++ ) + { + va.destroy( &aData[j] ); + } + va.deallocate( aData, nCapacity ); + } + + int getCapacity() + { + return nCapacity; + } + + bool isFilled() + { + return (nStart == nEnd); + } + + bool isEmpty() + { + return (nStart == -1); + } + + void enqueue( const value &v ) + { + if( nStart == -1 ) + { + nStart = 0; + nEnd = 1; + aData[0] = v; + } + else if( nStart == nEnd ) + { + throw ExceptionBase("Hey, it's full!"); + } + else + { + aData[nEnd] = v; + nEnd = (nEnd+1)%nCapacity; + } + } + + value dequeue() + { + if( nStart == -1 ) + { + throw ExceptionBase("No data"); + } + else + { + value &v = aData[nStart]; + nStart = (nStart+1)%nCapacity; + if( nStart == nEnd ) + { + nStart = -1; + nEnd = -2; + } + return v; + } + } + + value &operator[]( int nIndex ) + { + return aData[(nIndex+nStart)%nCapacity]; + } + + private: + int nCapacity; + value *aData; + valuealloc va; + int nStart, nEnd; + }; +} + +#endif diff --git a/src/tests/ringbuffer.cpp b/src/tests/ringbuffer.cpp new file mode 100644 index 0000000..259ec1f --- /dev/null +++ b/src/tests/ringbuffer.cpp @@ -0,0 +1,29 @@ +#include "bu/ringbuffer.h" +#include + +int main() +{ + Bu::RingBuffer ibuf( 10 ); + + for( int k = 0; k < 2; k++ ) + { + int j = 1; + for(; j < 7; j++ ) + { + ibuf.enqueue( j ); + } + + for(; j < 20; j++ ) + { + ibuf.enqueue( j ); + printf("- %d\n", ibuf.dequeue() ); + } + + for(;;) + { + if( ibuf.isEmpty() ) break; + printf(". %d\n", ibuf.dequeue() ); + } + } +} + -- cgit v1.2.3