fix(Core/Pooling): Fixed less and less objects from pools being spawned the longer the server is running (#5572)

This commit is contained in:
UltraNix
2021-05-08 20:39:09 +02:00
committed by GitHub
parent 75c75a40d4
commit 44babc3c3a
26 changed files with 136 additions and 105 deletions

View File

@@ -64,33 +64,63 @@ namespace acore
namespace Containers
{
template<class T>
void RandomResizeList(std::list<T>& list, uint32 size)
// replace with std::size in C++17
template<class C>
constexpr inline std::size_t Size(C const& container)
{
size_t list_size = list.size();
while (list_size > size)
{
typename std::list<T>::iterator itr = list.begin();
std::advance(itr, urand(0, list_size - 1));
list.erase(itr);
--list_size;
}
return container.size();
}
template<class T, class Predicate>
void RandomResizeList(std::list<T>& list, Predicate& predicate, uint32 size)
template<class T, std::size_t size>
constexpr inline std::size_t Size(T const(&)[size]) noexcept
{
return size;
}
// resizes <container> to have at most <requestedSize> elements
// if it has more than <requestedSize> elements, the elements to keep are selected randomly
template<class C>
void RandomResize(C& container, std::size_t requestedSize)
{
static_assert(std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<typename C::iterator>::iterator_category>::value, "Invalid container passed to acore::Containers::RandomResize");
if (Size(container) <= requestedSize)
{
return;
}
auto keepIt = std::begin(container), curIt = std::begin(container);
uint32 elementsToKeep = requestedSize, elementsToProcess = Size(container);
while (elementsToProcess)
{
// this element has chance (elementsToKeep / elementsToProcess) of being kept
if (urand(1, elementsToProcess) <= elementsToKeep)
{
if (keepIt != curIt)
*keepIt = std::move(*curIt);
++keepIt;
--elementsToKeep;
}
++curIt;
--elementsToProcess;
}
container.erase(keepIt, std::end(container));
}
template<class C, class Predicate>
void RandomResize(C& container, Predicate&& predicate, std::size_t requestedSize)
{
//! First use predicate filter
std::list<T> listCopy;
for (typename std::list<T>::iterator itr = list.begin(); itr != list.end(); ++itr)
if (predicate(*itr))
listCopy.push_back(*itr);
C containerCopy;
std::copy_if(std::begin(container), std::end(container), std::inserter(containerCopy, std::end(containerCopy)), predicate);
if (size)
RandomResizeList(listCopy, size);
if (requestedSize)
{
RandomResize(containerCopy, requestedSize);
}
list = listCopy;
container = std::move(containerCopy);
}
/* Select a random element from a container. Note: make sure you explicitly empty check the container */