dl
dl_buffer_pool.h
浏览该文件的文档.
1
12#pragma once
13
14#include <vector>
15#include <cassert>
16
17namespace dl
18{
21 {
22 public:
23 // index、size仅做返回值(内存不会置0)
24 std::byte* Malloc(size_t new_size, size_t& index, size_t& size)
25 {
26 // 新大小所在index
27 size_t new_index = ToIndex(new_size);
28 index = new_index;
29 if (index == 16)
30 {// 需要的太大
31 size = new_size;
32 return (std::byte*)malloc(new_size);
33 }
34 size = ToSize(new_index);
35 return _allNode[index].Get(size);
36 }
37
38 // 传入旧地址、需求大小(不是2的幂)、所在index(返回新index),旧大小(返回新size)
39 // 保留旧内存值,新内存不置0
40 std::byte* Realloc(std::byte* p, size_t new_size, size_t& index, size_t& size)
41 {
42 assert(new_size > size);
43 assert(index <= 16);
44
45 // 新大小所在index
46 size_t new_index = ToIndex(new_size);
47 if (new_index == 16)
48 {// 需要的太大
49 if (index == 16)
50 {// 之前就是自由内存
51 size = new_size * 2;
52 return (std::byte*)realloc(p, size);
53 }
54 else
55 {// 之前是小内存
56 // 归还小内存,并且分配自由内存
57 _allNode[index].Put(p);
58 size_t old_size = size;
59 index = 16;
60 size = new_size;
61 std::byte* ret = (std::byte*)malloc(size);
62 memcpy(ret, p, old_size);
63 memset(ret + old_size, 0, size - old_size);
64 return ret;
65 }
66 }
67
68 // 新的是小内存
69 assert(index != 16 && index != new_index);// 之前不可能是自由内存 且不在同一空间
70
71
72 // 归还小内存,并且分配新的小内存(更大的)
73 _allNode[index].Put(p);
74
75 new_size = ToSize(new_index);
76 std::byte* ret = _allNode[new_index].Get(new_size);
77 memcpy(ret, p, size);
78 index = new_index;
79 size = new_size;
80 return ret;
81 }
82 void Free(std::byte* p, size_t index, size_t size)
83 {
84 if (index == 16)
85 {
86 free(p);
87 return;
88 }
89 _allNode[index].Put(p);
90 }
91 std::string Dump()
92 {
93 std::string ret = "--------------Buffer Pool--------------\n";
94 for (size_t i = 0; i < 16; ++i)
95 {
96 size_t size = ToSize(i);
97 std::string unit;
98 if (size < 1024)
99 unit = "byte";
100 else if(size < 1024 * 1024)
101 {
102 unit = "kb";
103 size /= 1024;
104 }
105 else
106 {
107 unit = "mb";
108 size /= 1024 * 1024;
109 }
110 ret += fmt::format("[{:02}] {:<3} {:<4} x {}\n", i, size, unit, _allNode[i]._memFree.size());
111 }
112 return ret;
113 }
114 size_t ToSize(size_t index)
115 {
116 switch (index)
117 {
118 case 0: return 256;
119 case 1: return 512;
120 case 2: return 1024;
121 case 3: return 2048;
122 case 4: return 4096;
123 case 5: return 8192;
124 case 6: return 16384;
125 case 7: return 32768;
126 case 8: return 65536;
127 case 9: return 131072;
128 case 10: return 262144;
129 case 11: return 524288;
130 case 12: return 1048576;
131 case 13: return 2097152;
132 case 14: return 4194304;
133 case 15: return 8388608;
134 default: return 0;
135 }
136 }
137 size_t ToIndex(size_t size)
138 {
139 if (size <= 256) return 0;
140 if (size <= 512) return 1;
141 if (size <= 1024) return 2;
142 if (size <= 2048) return 3;
143 if (size <= 4096) return 4;
144 if (size <= 8192) return 5;
145 if (size <= 16384) return 6;
146 if (size <= 32768) return 7;
147 if (size <= 65536) return 8;
148 if (size <= 131072) return 9;
149 if (size <= 262144) return 10;
150 if (size <= 524288) return 11;
151 if (size <= 1048576) return 12;
152 if (size <= 2097152) return 13;
153 if (size <= 4194304) return 14;
154 if (size <= 8388608) return 15;
155 return 16;
156 }
158 {
159 _allNode.resize(16);
160 }
162 {
163 for (auto& iter : _allNode)
164 {
165 while (!iter._memFree.empty())
166 {
167 free(iter._memFree.top());
168 iter._memFree.pop();
169 }
170 }
171 }
172 private:
173
174 class Node
175 {
176 public:
177 std::byte* Get(size_t size)
178 {
179 if (_memFree.empty())
180 return (std::byte*)malloc(size);
181 else
182 {
183 std::byte* ret = _memFree.top();
184 _memFree.pop();
185 return ret;
186 }
187 }
188 void Put(std::byte* p)
189 {
190 _memFree.push(p);
191 }
192 std::stack<std::byte*> _memFree;
193 };
194 std::vector<Node> _allNode;
195 };
196
198}
void Free(std::byte *p, size_t index, size_t size)
size_t ToSize(size_t index)
std::byte * Realloc(std::byte *p, size_t new_size, size_t &index, size_t &size)
size_t ToIndex(size_t size)
std::byte * Malloc(size_t new_size, size_t &index, size_t &size)
BufferPool g_bufferPool