diff options
Diffstat (limited to 'src/util/pool.h')
-rw-r--r-- | src/util/pool.h | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/util/pool.h b/src/util/pool.h new file mode 100644 index 0000000..544ece6 --- /dev/null +++ b/src/util/pool.h @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** \file Pool + * Block allocator optimised for many allocations that are freed all at once. + */ +#ifndef INKSCAPE_UTIL_POOL_H +#define INKSCAPE_UTIL_POOL_H + +#include <memory> +#include <vector> +#include <utility> +#include <cstddef> + +namespace Inkscape { +namespace Util { + +/** + * A Pool is a block allocator with the following characteristics: + * + * - When a block cannot be allocated from the current buffer, a new 50% larger buffer is requested. + * - When all blocks are freed, the largest buffer is retained. + * + * The only difference from std::pmr::monotonic_buffer_resource is the second point. + * Like std::pmr::monotonic_buffer_resource, it is also not thread-safe. + */ +class Pool final +{ +public: + Pool() = default; + Pool(Pool const &) = delete; + Pool &operator=(Pool const &) = delete; + Pool(Pool &&other) noexcept { movefrom(other); } + Pool &operator=(Pool &&other) noexcept { movefrom(other); return *this; } + + /// Ensure that the next buffer requested has at least the specified size. + void reserve(std::size_t size) { nextsize = std::max(nextsize, size); } + + /// Allocate a block of the given size and alignment. + std::byte *allocate(std::size_t size, std::size_t alignment); + + /// Convenience function: allocate a block of size and aligment for T. + template<typename T> + T *allocate() { return reinterpret_cast<T*>(allocate(sizeof(T), alignof(T))); } + + /// Free all previous allocations, retaining the largest existing buffer for re-use. + void free_all() noexcept; + +private: + std::vector<std::unique_ptr<std::byte[]>> buffers; + std::byte *cur = nullptr, *end = nullptr; + std::size_t cursize = 0, nextsize = 2; + + void movefrom(Pool &other) noexcept; + void resetblock() noexcept; +}; + +} // namespace Util +} // namespace Inkscape + +#endif // INKSCAPE_UTIL_POOL_H |