dvander@2226: #ifndef _INCLUDE_KNIGHT_KE_SECTOR_STACK_H_ dvander@2226: #define _INCLUDE_KNIGHT_KE_SECTOR_STACK_H_ dvander@2226: dvander@2226: #include dvander@2226: #include dvander@2226: dvander@2226: namespace Knight dvander@2226: { dvander@2226: template dvander@2226: class KeSectorStack dvander@2226: { dvander@2226: public: dvander@2226: static const size_t DEFAULT_SECTOR_SIZE = 64; dvander@2226: dvander@2226: KeSectorStack() : m_SectorSize(DEFAULT_SECTOR_SIZE), m_UsedSize(0), m_MaxUsedSize(0) dvander@2226: { dvander@2226: m_pAlloc = NULL; dvander@2226: } dvander@2226: dvander@2226: KeSectorStack(size_t sectorSize) : m_SectorSize(sectorSize), m_UsedSize(0), m_MaxUsedSize(0) dvander@2226: { dvander@2226: m_pAlloc = NULL; dvander@2226: } dvander@2226: dvander@2226: KeSectorStack(size_t sectorSize, ke_allocator_t *alloc) : dvander@2226: m_SectorSize(sectorSize), m_UsedSize(0), m_pAlloc(alloc), m_MaxUsedSize(0) dvander@2226: { dvander@2226: } dvander@2226: dvander@2226: ~KeSectorStack() dvander@2226: { dvander@2226: clear(); dvander@2226: } dvander@2226: dvander@2226: void clear() dvander@2226: { dvander@2226: T *sector; dvander@2226: size_t last_sector; dvander@2226: size_t last_sector_item; dvander@2226: dvander@2226: if (m_MaxUsedSize == 0) dvander@2226: { dvander@2226: return; dvander@2226: } dvander@2226: dvander@2226: last_sector = (m_MaxUsedSize - 1) / m_SectorSize; dvander@2226: last_sector_item = (m_MaxUsedSize - 1) % m_SectorSize; dvander@2226: dvander@2226: for (size_t i = 0; i < last_sector; i++) dvander@2226: { dvander@2226: sector = m_Sectors[i]; dvander@2226: dvander@2226: for (size_t j = 0; j < m_SectorSize; j++) dvander@2226: { dvander@2226: sector[j].~T(); dvander@2226: } dvander@2226: } dvander@2226: dvander@2226: sector = m_Sectors[last_sector]; dvander@2226: for (size_t i = 0; i <= last_sector_item; i++) dvander@2226: { dvander@2226: sector[i].~T(); dvander@2226: } dvander@2226: dvander@2226: clear_no_dtors(); dvander@2226: } dvander@2226: dvander@2226: void clear_no_dtors() dvander@2226: { dvander@2226: for (size_t i = 0; i < m_Sectors.size(); i++) dvander@2226: { dvander@2226: free_sector(m_Sectors[i]); dvander@2226: } dvander@2226: dvander@2226: m_Sectors.clear(); dvander@2226: } dvander@2226: dvander@2226: bool empty() dvander@2226: { dvander@2226: return (m_UsedSize == 0) ? true : false; dvander@2226: } dvander@2226: dvander@2226: void push(const T & val) dvander@2226: { dvander@2226: if ((m_UsedSize / m_SectorSize) >= m_Sectors.size()) dvander@2226: { dvander@2226: /* Create a new sector */ dvander@2226: T * sector; dvander@2226: dvander@2226: if (m_pAlloc == NULL) dvander@2226: { dvander@2226: sector = (T *)malloc(sizeof(T) * m_SectorSize); dvander@2226: } dvander@2226: else dvander@2226: { dvander@2226: sector = (T *)m_pAlloc->alloc(m_pAlloc, sizeof(T) * m_SectorSize); dvander@2226: } dvander@2226: dvander@2226: m_Sectors.push_back(sector); dvander@2226: } dvander@2226: dvander@2226: at(m_UsedSize) = val; dvander@2226: dvander@2226: m_UsedSize++; dvander@2226: dvander@2226: /* Keep track of the maximum used size so we can defer the dvander@2226: * massive destruction job until the end. dvander@2226: */ dvander@2226: if (m_UsedSize > m_MaxUsedSize) dvander@2226: { dvander@2226: m_MaxUsedSize = m_UsedSize; dvander@2226: } dvander@2226: } dvander@2226: dvander@2226: void pop() dvander@2226: { dvander@2226: m_UsedSize--; dvander@2226: } dvander@2226: dvander@2226: void pop_all() dvander@2226: { dvander@2226: m_UsedSize = 0; dvander@2226: } dvander@2226: dvander@2226: T & front() dvander@2226: { dvander@2226: return at(m_UsedSize - 1); dvander@2226: } dvander@2226: dvander@2226: size_t size() dvander@2226: { dvander@2226: return m_UsedSize; dvander@2226: } dvander@2226: dvander@2226: private: dvander@2226: T & at(size_t x) dvander@2226: { dvander@2226: return m_Sectors[x / m_SectorSize][x % m_SectorSize]; dvander@2226: } dvander@2226: dvander@2226: void free_sector(T * sector) dvander@2226: { dvander@2226: if (m_pAlloc == NULL) dvander@2226: { dvander@2226: free(sector); dvander@2226: } dvander@2226: else if (m_pAlloc->dealloc != NULL) dvander@2226: { dvander@2226: m_pAlloc->dealloc(m_pAlloc, sector); dvander@2226: } dvander@2226: } dvander@2226: dvander@2226: private: dvander@2226: KeVector m_Sectors; dvander@2226: size_t m_SectorSize; dvander@2226: size_t m_UsedSize; dvander@2226: ke_allocator_t *m_pAlloc; dvander@2226: size_t m_MaxUsedSize; dvander@2226: }; dvander@2226: } dvander@2226: dvander@2226: #endif //_INCLUDE_KNIGHT_KE_SECTOR_STACK_H_