File: HeapAllocator.h

package info (click to toggle)
freespace2 24.0.2%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: trixie
  • size: 43,188 kB
  • sloc: cpp: 583,107; ansic: 21,729; python: 1,174; sh: 464; makefile: 248; xml: 181
file content (74 lines) | stat: -rw-r--r-- 1,891 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#pragma once

#include "globalincs/pstypes.h"

#include <functional>

namespace util {

/**
 * @brief A generic heap manager
 *
 * This class does not allocate memory! It only keeps track of where memory is stored and which memory ranges may be
 * reused later. This needs some kind of underlying memory manager before it can do anything.
 */
class HeapAllocator {
 public:
	/**
	 * @brief A function that can resize a generic heap structure.
	 *
	 * This takes the new size of the heap as its only parameter.
	 */
	typedef std::function<void(size_t)> HeapResizer;

 private:
	struct MemoryRange {
		size_t offset = 0;
		size_t size = 0;

		bool operator<(const MemoryRange& other) const;
		bool operator==(const MemoryRange& other) const;
	};

	size_t _heapSize = 0;
	size_t _lastSizeIncraese = 0;

	HeapResizer _heapResizer;

	SCP_vector<MemoryRange> _freeRanges;
	SCP_vector<MemoryRange> _allocatedRanges;

	void addFreeRange(const MemoryRange& range);
	void addAllocatedRange(const MemoryRange& range);

	/**
	 * @brief Checks if all free ranges are merged properly.
	 */
	void checkRangesMerged();

	static bool check_connected_range(const MemoryRange& left, const MemoryRange& right);
 public:
	explicit HeapAllocator(const HeapResizer& creatorFunction);
	~HeapAllocator() = default;

	/**
	 * @brief Allocates the specified amount of memory
	 * @param size The size of the memory block to allocate
	 * @return The offset at which the specified amount of memory can be used
	 */
	size_t allocate(size_t size);

	/**
	 * @brief Frees the memory starting at the specified offset.
	 * @param offset The offset at which to free memory. This value must have been returned by allocate previously!
	 */
	void free(size_t offset);

	/**
	 * @brief Retrieves the amount of allocations currently active
	 * @return The active allocations in this heap.
	 */
	size_t numAllocations() const;
};

}