first run implementation of Queue
authorPatrik Gornicz <Gornicz.P@gmail.com>
Tue, 4 Aug 2009 01:32:51 +0000 (21:32 -0400)
committerPatrik Gornicz <Gornicz.P@gmail.com>
Tue, 4 Aug 2009 01:32:51 +0000 (21:32 -0400)
lib/include/bear/Queue.h

index 21df35b..d224cd8 100644 (file)
@@ -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<Item>::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<Item>::Queue()
 template < class Item >
 void bear::Queue<Item>::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<Item>::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<Item>::alloc(int iSize)
+void bear::Queue<Item>::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<Item>::trim()
@@ -92,30 +154,72 @@ void bear::Queue<Item>::trim()
 template < class Item >
 bool bear::Queue<Item>::isEmpty() const
 {
-    return false;
+    return m_fIsEmpty;
 }
 
 template < class Item >
-Item& bear::Queue<Item>::getFront()
+const Item& bear::Queue<Item>::getFront() const
 {
+  // This is very bad. Fix your code
+  DASSERT(!isEmpty());
 
+  return m_pArrayItems[m_uiHead];
 }
 
 template < class Item >
-Item& bear::Queue<Item>::getBack()
+const Item& bear::Queue<Item>::getBack() const
 {
+  // This is very bad. Fix your code
+  DASSERT(!isEmpty());
 
+  return m_pArrayItems[m_uiTail];
 }
 
 template < class Item >
 void bear::Queue<Item>::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<Item>::popBack(const Item& i)
+void bear::Queue<Item>::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<Item>::getLength() const
+{
+  if ( isEmpty() )
+  {
+    return 0;
+  }
+  else
+  {
+    return mod( m_uiTail - m_uiHead, m_uiAllocated ) + 1;
+  }
 }
 
+template < class Item >
+unsigned int bear::Queue<Item>::getSpaceNeeded(unsigned int uiSize) const
+{
+  unsigned int uiNewSize = m_uiAllocated;
+
+  while ( uiNewSize < uiSize )
+  {
+    uiNewSize *= m_uiSizeMultiplier;
+  }
+
+  return uiNewSize;
+}