Jump to content

Extended memory pool


Recommended Posts

  • Honorable Member

Hello guys,

I didn't like the basic memory pooling solution in the client so I extended and rewrote some parts of it.

  • now it allocates memory in chunks instead of one by one, the chunk's size can grow
  • Alloc can have any parameters, so you don't need to use only default constructors
  • ctors and dtors are called properly for each object created by the pool and also on unfreed objects on Clear

Keep in mind, that it's not a drop-in replacement for every case where the old one was used, you may need to modify your code at some places, so I suggest porting to this new version one by one.

Good luck!

template<typename T>
class CMemoryPoolNew
{
public:
	CMemoryPoolNew(size_t uChunkSize = 16, bool bGrowChunkSize = true)
		: m_uChunkSize(uChunkSize)
		, m_bGrowChunkSize(bGrowChunkSize)
	{

	}

	~CMemoryPoolNew()
	{
		Clear();
	}

	void Clear()
	{
		assert(m_Free.size() == m_Data.size() && "Memory pool has unfreed objects!");

		if (m_Free.size() != m_Data.size())
		{
			for (T* pData : m_Data)
			{
				if (std::find(m_Free.begin(), m_Free.end(), pData) == m_Free.end())
				{
					pData->~T();
				}
			}
		}

		m_Data.clear();
		m_Data.shrink_to_fit();

		m_Free.clear();
		m_Free.shrink_to_fit();

		for (T* pChunk : m_Chunk)
		{
			::free(pChunk);
		}

		m_Chunk.clear();
		m_Chunk.shrink_to_fit();
	}

	template<class... _Types>
	T* Alloc(_Types&&... _Args)
	{
		if (m_Free.empty())
			Grow();

		T* pNew = m_Free.back();
		m_Free.pop_back();
		return new(pNew) T(std::forward<_Types>(_Args)...);
	}

	void Free(T* pData)
	{
		pData->~T();
		m_Free.push_back(pData);
	}

	size_t GetCapacity() const
	{
		return m_Data.size();
	}

private:
	void Grow()
	{
		size_t uChunkSize = m_uChunkSize;

		if (m_bGrowChunkSize)
			uChunkSize += uChunkSize * m_Chunk.size();

		T* pStart = (T*) ::malloc(uChunkSize * sizeof(T));
		m_Chunk.push_back(pStart);

		m_Data.reserve(m_Data.size() + uChunkSize);
		m_Free.reserve(m_Free.size() + uChunkSize);

		for (size_t i = 0; i < uChunkSize; ++i)
		{
			m_Data.push_back(pStart + i);
			m_Free.push_back(pStart + i);
		}
	}

private:
	size_t m_uChunkSize;
	bool m_bGrowChunkSize;

	std::vector<T*> m_Data;
	std::vector<T*> m_Free;

	std::vector<T*> m_Chunk;
};

 

Edited by Distraught
  • Metin2 Dev 6
  • Good 3
  • Love 1
  • Love 9

WRnRW3H.gif

Link to comment
Share on other sites

  • Honorable Member

Thanks for sharing, I had the chance to try it out and it's working well of course, I like the way you have built this memory pool, the standard ones are somehow confusing and old. I would recommend everyone trying this out, of course it's not just copy paste but for better support you can add these to the memory pool template.

	void Create(size_t uChunkSize = 16, bool bGrowChunkSize = true)
	{
		m_uChunkSize = uChunkSize;
		m_bGrowChunkSize = bGrowChunkSize;
	}
	void Destroy()
	{
		Clear();
	}
	void FreeAll()
	{
		Clear();
	}

With this you don't have to chase down all the functions that allocate memory and simply just replace CDynamicPool with CMemoryPoolNew If I'm using it wrong, please let me know, so far so good and keep up the nice work.

Edited by Owsap
  • Good 2
  • Love 1
Link to comment
Share on other sites

Announcements



  • Similar Content

  • Similar Content

  • Similar Content

  • Tags

  • Activity

    1. 2

      Feeding game source to LLM

    2. 0

      Target Information System

    3. 2

      Feeding game source to LLM

    4. 2

      anti exp explanation pls

    5. 2

      Feeding game source to LLM

    6. 2

      anti exp explanation pls

    7. 0

      [GR2] Positioning an object added with "Attach"

  • Recently Browsing

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.