SHARE
TWEET

Untitled

a guest Jul 17th, 2017 39 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //=============================================================================
  2. //= MemoryPool.h?
  3.  
  4. #pragma once
  5.  
  6. #include <inttypes.h>
  7. #include <memory.h>
  8. #include <vector>
  9.  
  10.  
  11. template<typename UnitT,
  12.     uint16_t page_size    = 100,
  13.     uint32_t max_elements = 0x00FFFFFF>
  14. class MemPool {
  15. public:
  16.  
  17.     typedef struct {
  18.         UnitT    m_tData;
  19.         uint32_t m_index;
  20.     } block_t;
  21.  
  22.     typedef typename std::vector<block_t*> block_v;
  23.  
  24. public:
  25.  
  26.     ~MemPool() {}
  27.  
  28.     static MemPool* I() {
  29.         if (pool == NULL) {
  30.             pool = new MemPool();
  31.         }
  32.         return pool;
  33.     }
  34.  
  35.     static UnitT *Allocate() {
  36.         return I()->allocate();
  37.     }
  38.    
  39.     static void Dellocate(const uint32_t& index) {
  40.         return I()->dellocate(index);
  41.     }
  42.  
  43.     static uint32_t Index() {
  44.         return I()->index();
  45.     }
  46.  
  47.     static UnitT *Get(const uint32_t& index) {
  48.         return I()->get(index);
  49.     }
  50.  
  51.     static void Rewind() {
  52.         return I()->rewind();
  53.     }
  54.  
  55.     static UnitT *Next() {
  56.         return I()->next();
  57.     }
  58.  
  59. protected:
  60.  
  61.     // 'allocates' space for an entry of type 'UnitT'
  62.     UnitT *allocate() {
  63.         block_t *block = NULL;
  64.         UnitT *pointer = NULL;
  65.         size_t size = 0;
  66.         // performs pre-allocation (if needed)
  67.         this->preallocate();
  68.         // returns free slot (if any) or null
  69.         if ((size = m_free.size()) > 0) {
  70.             block = m_free.back();
  71.             pointer = &block->m_tData;
  72.             this->m_index = block->m_index;
  73.             m_free.pop_back();
  74.         } return pointer;
  75.     }
  76.  
  77.     // 'delocates' a pointer at given @index
  78.     void dellocate(const uint32_t& index) {
  79.         uint16_t row = index / page_size;
  80.         uint16_t col = index % page_size;
  81.         block_t *entry = NULL;
  82.         if (index > max_elements) {
  83.             return;
  84.         }
  85.         entry = &m_list[row][col];
  86.         m_free.push_back(entry);
  87.     }
  88.  
  89.     uint32_t index() {
  90.         return this->m_index;
  91.     }
  92.  
  93.     // 'retrieves' an entry at given @index
  94.     UnitT *get(const uint32_t& index) {
  95.         uint16_t row = index / page_size;
  96.         uint16_t col = index % page_size;
  97.         if (index > max_elements) {
  98.             return 0;
  99.         }
  100.         if (m_list.size() <= row) {
  101.             return 0;
  102.         }
  103.         return &pool->m_list[row][col].m_tData;
  104.     }
  105.  
  106.     // returns m_list index
  107.     void preallocate() {
  108.         uint32_t index = 0;
  109.         block_t *blocks = NULL;
  110.         size_t col = 0, rows = 0;
  111.         rows = m_list.size();
  112.         if (m_free.empty() == false) {
  113.             // not required,
  114.             // there are some free objects to pick up
  115.             return;
  116.         }
  117.         if (rows * page_size >= max_elements) {
  118.             return;// limit reached
  119.         }
  120.         try {
  121.             blocks = new block_t[page_size];
  122.             if (blocks == NULL) {
  123.                 return;// out of memory?
  124.             }
  125.            
  126.             m_list.push_back(blocks);
  127.             for (col = 0; col < page_size; ++col) {
  128.                 index = uint32_t(rows * page_size + col);
  129.                 m_free.push_back(&blocks[col]);
  130.                 blocks[col].m_index = index;
  131.             }
  132.         }
  133.         catch (const std::bad_alloc& e) {
  134.             (void)e;//-- out of memory?
  135.         }
  136.     }
  137.  
  138.     // set the iterator position at the list beginning
  139.     void rewind() {
  140.         this->m_iterator = 0;
  141.     }
  142.  
  143.     // 'retrieves' the item in where the iterator is at,
  144.     // and increases its position by 1, for its next iteration.
  145.     UnitT *next() {
  146.         uint16_t row = this->m_iterator / page_size;
  147.         uint16_t col = this->m_iterator % page_size;
  148.         this->m_iterator += 1;
  149.         if (this->m_iterator > max_elements) {
  150.             return 0;
  151.         }
  152.         if (m_list.size() <= row) {
  153.             return 0;
  154.         }
  155.         return &pool->m_list[row][col].m_tData;
  156.     }
  157.  
  158. private:
  159.     MemPool() : m_list(), m_free(), m_iterator(0), m_index(0) {}
  160.  
  161. private:
  162.     block_v m_list;
  163.     block_v m_free;
  164.     uint32_t m_iterator;
  165.     uint32_t m_index;
  166.     static MemPool *pool;
  167. };
  168.  
  169. //-- indeed to be a singleton, might be changed to work as an instance (if required)
  170. template<typename UnitT, uint16_t page_size, uint32_t max_elements>
  171. MemPool<UnitT, page_size, max_elements>*
  172. MemPool<UnitT, page_size, max_elements>::pool = NULL;
  173.  
  174. //=============================================================================
  175. //= main.cpp
  176. //=============================================================================
  177.  
  178. #include "MemoryPool.h"
  179. #include <Windows.h>
  180.  
  181. struct sData {// 40kb
  182. private:
  183.     unsigned char _its_size_[1024*40 - sizeof(uint32_t)];
  184.     uint32_t _mem_index;
  185.  
  186. public:
  187.     uint32_t GetIndex() {
  188.         return this->_mem_index;
  189.     }
  190.  
  191.     void SetIndex(uint32_t i) {
  192.         this->_mem_index = i;
  193.     }
  194.  
  195.     void Initially() {
  196.         //-- ? triggered when it is being 'allocated'
  197.     }
  198.  
  199.     void Finally() {
  200.         //-- ? triggered when it is 'deallocated'
  201.     }
  202. };
  203.  
  204. // defines a memory pool type | a shortcut
  205. typedef MemPool<
  206.     sData,     //-- object type
  207.     100,       //-- objects within each allocated page
  208.     64000      //-- maximum amount of objects
  209. > DataAllocator;
  210.  
  211.  
  212. // 'allocation' | null
  213. static sData* NewData()
  214. {
  215.     sData *data = DataAllocator::Allocate();
  216.     if (data) {
  217.         data->SetIndex(DataAllocator::Index());
  218.         data->Initially();
  219.     }   return data;
  220.     return NULL;
  221. }
  222.  
  223.  
  224. // 'deallocation'
  225. static void DelData(sData* data)
  226. {
  227.     data->Finally();
  228.         // 0xFFFFFFFF unused flag/index
  229.         data->SetIndex(0xFFFFFFFF);
  230.     DataAllocator::Dellocate(data->GetIndex());
  231. }
  232.  
  233.  
  234. // access by an index | null
  235. static sData* GetData(uint32_t i)
  236. {
  237.     return DataAllocator::Get(i);
  238. }
  239.  
  240.  
  241. // Iterator: begin
  242. static void BeginGetData()
  243. {
  244.     return DataAllocator::Rewind();
  245. }
  246.  
  247.  
  248. // Iterator: next | null
  249. static sData* GetNextData()
  250. {
  251.     sData *data = DataAllocator::Next();
  252.     do {
  253.         data = DataAllocator::Next();
  254.         if (data == NULL)
  255.             break;
  256.         // 0xFFFFFFFF unused flag/index
  257.         if (data->GetIndex() < 0xFFFFFFFF)
  258.             break;
  259.     } while (true);
  260.     return data;
  261. }
  262.  
  263. int main(int argc, const char *argv[])
  264. {
  265.     size_t allocations = 0;
  266.     BOOL more = TRUE;
  267.    
  268.     while (more) {// runs until nulled out
  269.         allocations += (more = (NewData() != NULL))? 1 : 0;
  270.     }
  271.  
  272.     // prints out the amount of allocations until reached its max. items,
  273.     // or memory allocation issues (there is not enough memory).
  274.     printf("Allocations: %lu\n", allocations);
  275.  
  276.     return system("pause");
  277. }
RAW Paste Data
Top