-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRBTreeAllocator.h
100 lines (76 loc) · 2.29 KB
/
RBTreeAllocator.h
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#pragma once
#include "Allocator.h"
#include "Util.h"
#include "VMLinearAllocator.h"
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <memory>
/*
* TODO
* Share functionality between classes using compile-time code generation
* Right now, it follows STATIC mode
* Since the mechanism is working, port the STATIC_PREALLOC and VMDYNAMIC modes
*/
class RBTreeAllocator : public Allocator
{
public:
RBTreeAllocator(size_t sz);
~RBTreeAllocator();
void* Alloc(size_t sz, size_t alignment) final;
void Free(void*&) final;
inline void Release() final;
inline void Reset() final;
inline void ZeroMem() final;
void Layout() final;
protected:
enum COLOR : uint8_t {
BLACK,
RED
};
class Node {
public:
Node* parent;
Node* left;
Node* right;
COLOR color;
uintptr_t sz;
Node* llPrev;
Node* llNext;
Node* sibling();
};
struct FreeBlockHeader {
Node rbtreeNode;
size_t sz;
};
struct AllocatedBlockHeader {
size_t sz;
size_t padding;
};
private:
void build();
static Node* _rbtreeInsert(Node*& root, Node* node, size_t key);
static void _rbtreeFixup(Node *&root, Node *&pt);
static void _rbtreeRotateLeft(Node *&root, Node *&pt);
static void _rbtreeRotateRight(Node *&root, Node *&pt);
Node* _smallestInSubtree(Node* node);
Node* _BSTSubst(Node* node);
void _rbtreeFixDoubleBlack(Node* node);
void _rbtreeDelete(Node* node);
void _rbtreeSwapNodes(Node* node, Node* subst);
Node* _rbtreeFindKey(size_t key);
void* _rbtreeStrictBestFit(Node* node, size_t key, size_t alignment, Node*& block, ptrdiff_t& padding);
void _deleteNode(Node* node);
inline void _fitPadding(ptrdiff_t& padding, size_t alignment);
inline size_t _splitBlock(void* block, void* ptr, size_t sz);
inline void* _fitToBlock(void* block, size_t sz, size_t alignment, ptrdiff_t& leftover, ptrdiff_t& padding);
size_t m_size;
Node* m_root = NULL;
void* m_start;
void* m_end;
bool m_initialized;
/* CONSTEXPRS */
static constexpr size_t allocHeaderSize = sizeof(AllocatedBlockHeader);
static constexpr size_t freeHeaderSize = sizeof(FreeBlockHeader);
};