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