From: Patrik Gornicz Date: Tue, 4 Aug 2009 01:32:51 +0000 (-0400) Subject: first run implementation of Queue X-Git-Tag: libbear-premerge~24 X-Git-Url: http://gitweb.pgornicz.com/?a=commitdiff_plain;h=811414ce5aa9a33bdb3ff8fadd89c7d458a506df;p=libbear.git first run implementation of Queue --- diff --git a/lib/include/bear/Queue.h b/lib/include/bear/Queue.h index 21df35b..d224cd8 100644 --- a/lib/include/bear/Queue.h +++ b/lib/include/bear/Queue.h @@ -7,6 +7,9 @@ #pragma once +#include "debug.h" +#include "mathw.h" + // HACK #ifndef NULL #define NULL 0 @@ -23,41 +26,46 @@ namespace bear Queue(); ~Queue() {} - void init(int iStartSize = 2, int iSizeMultiplier = 2); + void init(unsigned int uiStartSize = 2, unsigned int uiSizeMultiplier = 2); void fini(); - void alloc(int iSize); + void alloc(unsigned int uiSize); void trim(); bool isEmpty() const; - Item& getFront(); - Item& getBack(); + const Item& getFront() const; + const Item& getBack() const; void pushFront(const Item& i); - void popBack(const Item& i); + void pushBack(const Item& i); private: - int m_iStartSize; - int m_iSizeMultiplier; + unsigned int getLength() const; + unsigned int getSpaceNeeded(unsigned int uiSize) const; + + unsigned int m_uiStartSize; + unsigned int m_uiSizeMultiplier; - int m_iAllocated; - Item* m_pArrayItems; + unsigned int m_uiAllocated; + Item* m_pArrayItems; + bool m_fIsEmpty; - int m_iHead; - int m_iTail; + unsigned int m_uiHead; + unsigned int m_uiTail; }; } // namespace bear template < class Item > bear::Queue::Queue() - : m_iStartSize(0), - m_iSizeMultiplier(0), - m_iAllocated(0), + : m_uiStartSize(0), + m_uiSizeMultiplier(0), + m_uiAllocated(0), m_pArrayItems(NULL), - m_iHead(0), - m_iTail(0) + m_fIsEmpty(0), + m_uiHead(0), + m_uiTail(0) { } @@ -65,23 +73,77 @@ bear::Queue::Queue() template < class Item > void bear::Queue::init ( - int iStartSize, - int iSizeMultiplier + unsigned int uiStartSize, + unsigned int uiSizeMultiplier ) { - m_iStartSize = iStartSize; - m_iSizeMultiplier = iSizeMultiplier; + m_uiStartSize = uiStartSize; + m_uiSizeMultiplier = uiSizeMultiplier; + + m_uiAllocated = 0; + + bear::DASSERT(NULL == m_pArrayItems); // this better be the case + m_pArrayItems = NULL; + + m_fIsEmpty = true; + + m_uiHead = 0; + m_uiTail = 0; } template < class Item > void bear::Queue::fini() { + m_uiStartSize = 0; + m_uiSizeMultiplier = 0; + m_uiAllocated = 0; + + delete m_pArrayItems; + m_pArrayItems = NULL; + + m_fIsEmpty = true; + + m_uiHead = 0; + m_uiTail = 0; } template < class Item > -void bear::Queue::alloc(int iSize) +void bear::Queue::alloc(unsigned int uiSize) { + if(m_uiAllocated < uiSize) + { + unsigned int uiOldLength = getLength(); + + unsigned int uiOldAllocated = m_uiAllocated; + Item* pOldArrayItems = m_pArrayItems; + unsigned int uiOldHead = m_uiHead; + unsigned int uiOldTail = m_uiTail; + + m_uiAllocated = 0; + m_pArrayItems = NULL; + m_uiHead = -1; + m_uiTail = -1; + + unsigned int uiNewAllocated = uiSize; + Item* pNewArrayItems = new Item[uiNewAllocated]; + unsigned int uiNewHead = 0; + unsigned int uiNewTail = uiOldLength - 1; + + for(unsigned int uiNewIndex = uiNewHead; uiNewIndex <= uiNewTail; uiNewIndex++) + { + unsigned int iOldIndex = mod(uiNewIndex + uiOldHead, uiOldAllocated); + bear::DASSERT(iOldIndex <= uiOldTail); + + pNewArrayItems[uiNewIndex] = pOldArrayItems[iOldIndex]; + } + + m_uiAllocated = uiNewAllocated; + m_pArrayItems = pNewArrayItems; + m_uiHead = uiNewHead; + m_uiTail = uiNewTail; + } + // TODO: return error code } template < class Item > void bear::Queue::trim() @@ -92,30 +154,72 @@ void bear::Queue::trim() template < class Item > bool bear::Queue::isEmpty() const { - return false; + return m_fIsEmpty; } template < class Item > -Item& bear::Queue::getFront() +const Item& bear::Queue::getFront() const { + // This is very bad. Fix your code + DASSERT(!isEmpty()); + return m_pArrayItems[m_uiHead]; } template < class Item > -Item& bear::Queue::getBack() +const Item& bear::Queue::getBack() const { + // This is very bad. Fix your code + DASSERT(!isEmpty()); + return m_pArrayItems[m_uiTail]; } template < class Item > void bear::Queue::pushFront(const Item& i) { + // Make sure we have the space to add an item + alloc( getSpaceNeeded( getLength() + 1 ) ); + m_uiHead = mod( m_uiHead + 1, m_uiAllocated ); + + m_pArrayItems[m_uiHead] = i; } template < class Item > -void bear::Queue::popBack(const Item& i) +void bear::Queue::pushBack(const Item& i) { + // Make sure we have the space to add an item + alloc( getSpaceNeeded( getLength() + 1 ) ); + + m_uiTail = mod( m_uiTail + 1, m_uiAllocated ); + + m_pArrayItems[m_uiTail] = i; +} + +template < class Item > +unsigned int bear::Queue::getLength() const +{ + if ( isEmpty() ) + { + return 0; + } + else + { + return mod( m_uiTail - m_uiHead, m_uiAllocated ) + 1; + } } +template < class Item > +unsigned int bear::Queue::getSpaceNeeded(unsigned int uiSize) const +{ + unsigned int uiNewSize = m_uiAllocated; + + while ( uiNewSize < uiSize ) + { + uiNewSize *= m_uiSizeMultiplier; + } + + return uiNewSize; +}