knight/shared/KeSectorStack.h
author Ruben Gonzalez <drifter01620@gmail.com>
Thu May 22 09:49:27 2014 -0400 (2014-05-22)
changeset 4378 568f4497ef4a
parent 2226 d10b38524be3
permissions -rw-r--r--
Update CS:GO team score gamedata.
     1 #ifndef _INCLUDE_KNIGHT_KE_SECTOR_STACK_H_
     2 #define _INCLUDE_KNIGHT_KE_SECTOR_STACK_H_
     3 
     4 #include <KnightAllocator.h>
     5 #include <KeVector.h>
     6 
     7 namespace Knight
     8 {
     9 	template <class T>
    10 	class KeSectorStack
    11 	{
    12 	public:
    13 		static const size_t DEFAULT_SECTOR_SIZE = 64;
    14 
    15 		KeSectorStack() : m_SectorSize(DEFAULT_SECTOR_SIZE), m_UsedSize(0), m_MaxUsedSize(0)
    16 		{
    17 			m_pAlloc = NULL;
    18 		}
    19 
    20 		KeSectorStack(size_t sectorSize) : m_SectorSize(sectorSize), m_UsedSize(0), m_MaxUsedSize(0)
    21 		{
    22 			m_pAlloc = NULL;
    23 		}
    24 
    25 		KeSectorStack(size_t sectorSize, ke_allocator_t *alloc) : 
    26 			m_SectorSize(sectorSize), m_UsedSize(0), m_pAlloc(alloc), m_MaxUsedSize(0)
    27 		{
    28 		}
    29 
    30 		~KeSectorStack()
    31 		{
    32 			clear();
    33 		}
    34 
    35 		void clear()
    36 		{
    37 			T *sector;
    38 			size_t last_sector;
    39 			size_t last_sector_item;
    40 
    41 			if (m_MaxUsedSize == 0)
    42 			{
    43 				return;
    44 			}
    45 
    46 			last_sector = (m_MaxUsedSize - 1) / m_SectorSize;
    47 			last_sector_item = (m_MaxUsedSize - 1) % m_SectorSize;
    48 
    49 			for (size_t i = 0; i < last_sector; i++)
    50 			{
    51 				sector = m_Sectors[i];
    52 
    53 				for (size_t j = 0; j < m_SectorSize; j++)
    54 				{
    55 					sector[j].~T();
    56 				}
    57 			}
    58 
    59 			sector = m_Sectors[last_sector];
    60 			for (size_t i = 0; i <= last_sector_item; i++)
    61 			{
    62 				sector[i].~T();
    63 			}
    64 
    65 			clear_no_dtors();
    66 		}
    67 
    68 		void clear_no_dtors()
    69 		{
    70 			for (size_t i = 0; i < m_Sectors.size(); i++)
    71 			{
    72 				free_sector(m_Sectors[i]);
    73 			}
    74 
    75 			m_Sectors.clear();
    76 		}
    77 
    78 		bool empty()
    79 		{
    80 			return (m_UsedSize == 0) ? true : false;
    81 		}
    82 
    83 		void push(const T & val)
    84 		{
    85 			if ((m_UsedSize / m_SectorSize) >= m_Sectors.size())
    86 			{
    87 				/* Create a new sector */
    88 				T * sector;
    89 				
    90 				if (m_pAlloc == NULL)
    91 				{
    92 					sector = (T *)malloc(sizeof(T) * m_SectorSize);
    93 				}
    94 				else 
    95 				{
    96 					sector = (T *)m_pAlloc->alloc(m_pAlloc, sizeof(T) * m_SectorSize);
    97 				}
    98 
    99 				m_Sectors.push_back(sector);
   100 			}
   101 
   102 			at(m_UsedSize) = val;
   103 
   104 			m_UsedSize++;
   105 
   106 			/* Keep track of the maximum used size so we can defer the 
   107 			 * massive destruction job until the end.
   108 			 */
   109 			if (m_UsedSize > m_MaxUsedSize)
   110 			{
   111 				m_MaxUsedSize = m_UsedSize;
   112 			}
   113 		}
   114 
   115 		void pop()
   116 		{
   117 			m_UsedSize--;
   118 		}
   119 
   120 		void pop_all()
   121 		{
   122 			m_UsedSize = 0;
   123 		}
   124 
   125 		T & front()
   126 		{
   127 			return at(m_UsedSize - 1);
   128 		}
   129 
   130 		size_t size()
   131 		{
   132 			return m_UsedSize;
   133 		}
   134 
   135 	private:
   136 		T & at(size_t x)
   137 		{
   138 			return m_Sectors[x / m_SectorSize][x % m_SectorSize];
   139 		}
   140 
   141 		void free_sector(T * sector)
   142 		{
   143 			if (m_pAlloc == NULL)
   144 			{
   145 				free(sector);
   146 			}
   147 			else if (m_pAlloc->dealloc != NULL)
   148 			{
   149 				m_pAlloc->dealloc(m_pAlloc, sector);
   150 			}
   151 		}
   152 
   153 	private:
   154 		KeVector<T *> m_Sectors;
   155 		size_t m_SectorSize;
   156 		size_t m_UsedSize;
   157 		ke_allocator_t *m_pAlloc;
   158 		size_t m_MaxUsedSize;
   159 	};
   160 }
   161 
   162 #endif //_INCLUDE_KNIGHT_KE_SECTOR_STACK_H_