1. 程式人生 > 其它 >資料庫的建立與管理(t-sql語句實現)

資料庫的建立與管理(t-sql語句實現)

  1 #ifndef PPX_BASE_MEMORY_POOL_H_
  2 #define PPX_BASE_MEMORY_POOL_H_
  3 
  4 #include <climits>
  5 #include <cstddef>
  6 #include <mutex>
  7 
  8 namespace ppx {
  9     namespace base {
 10         template <typename T, size_t BlockSize = 4096, bool ZeroOnDeallocate = true
> 11 class MemoryPool { 12 public: 13 /* Member types */ 14 typedef T value_type; 15 typedef T* pointer; 16 typedef T& reference; 17 typedef const T* const_pointer;
18 typedef const T& const_reference; 19 typedef size_t size_type; 20 typedef ptrdiff_t difference_type; 21 typedef std::false_type propagate_on_container_copy_assignment; 22 typedef std::true_type propagate_on_container_move_assignment;
23 typedef std::true_type propagate_on_container_swap; 24 25 template <typename U> struct rebind { 26 typedef MemoryPool<U> other; 27 }; 28 29 /* Member functions */ 30 MemoryPool() noexcept; 31 MemoryPool(const MemoryPool& memoryPool) noexcept; 32 MemoryPool(MemoryPool&& memoryPool) noexcept; 33 template <class U> MemoryPool(const MemoryPool<U>& memoryPool) noexcept; 34 35 ~MemoryPool() noexcept; 36 37 MemoryPool& operator=(const MemoryPool& memoryPool) = delete; 38 MemoryPool& operator=(MemoryPool&& memoryPool) noexcept; 39 40 pointer address(reference x) const noexcept; 41 const_pointer address(const_reference x) const noexcept; 42 43 // Can only allocate one object at a time. n and hint are ignored 44 pointer allocate(size_type n = 1, const_pointer hint = 0); 45 void deallocate(pointer p, size_type n = 1); 46 47 size_type max_size() const noexcept; 48 49 template <class U, class... Args> void construct(U* p, Args&&... args); 50 template <class U> void destroy(U* p); 51 52 template <class... Args> pointer newElement(Args&&... args); 53 void deleteElement(pointer p); 54 55 private: 56 struct Element_ { 57 Element_* pre; 58 Element_* next; 59 }; 60 61 typedef char* data_pointer; 62 typedef Element_ element_type; 63 typedef Element_* element_pointer; 64 65 element_pointer data_element_; 66 element_pointer free_element_; 67 68 std::recursive_mutex m_; 69 70 size_type padPointer(data_pointer p, size_type align) const noexcept; 71 void allocateBlock(); 72 73 static_assert(BlockSize >= 2 * sizeof(element_type), "BlockSize too small."); 74 }; 75 76 77 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 78 inline typename MemoryPool<T, BlockSize, ZeroOnDeallocate>::size_type 79 MemoryPool<T, BlockSize, ZeroOnDeallocate>::padPointer(data_pointer p, size_type align) 80 const noexcept { 81 uintptr_t result = reinterpret_cast<uintptr_t>(p); 82 return ((align - result) % align); 83 } 84 85 86 87 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 88 MemoryPool<T, BlockSize, ZeroOnDeallocate>::MemoryPool() 89 noexcept { 90 data_element_ = nullptr; 91 free_element_ = nullptr; 92 } 93 94 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 95 MemoryPool<T, BlockSize, ZeroOnDeallocate>::MemoryPool(const MemoryPool& memoryPool) 96 noexcept : 97 MemoryPool() { 98 } 99 100 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 101 MemoryPool<T, BlockSize, ZeroOnDeallocate>::MemoryPool(MemoryPool&& memoryPool) 102 noexcept { 103 std::lock_guard<std::recursive_mutex> lock(m_); 104 105 data_element_ = memoryPool.data_element_; 106 memoryPool.data_element_ = nullptr; 107 free_element_ = memoryPool.free_element_; 108 memoryPool.free_element_ = nullptr; 109 } 110 111 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 112 template<class U> 113 MemoryPool<T, BlockSize, ZeroOnDeallocate>::MemoryPool(const MemoryPool<U>& memoryPool) 114 noexcept : 115 MemoryPool() { 116 } 117 118 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 119 MemoryPool<T, BlockSize, ZeroOnDeallocate>& 120 MemoryPool<T, BlockSize, ZeroOnDeallocate>::operator=(MemoryPool&& memoryPool) 121 noexcept { 122 std::lock_guard<std::recursive_mutex> lock(m_); 123 124 if (this != &memoryPool) { 125 std::swap(data_element_, memoryPool.data_element_); 126 std::swap(free_element_, memoryPool.free_element_); 127 } 128 return *this; 129 } 130 131 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 132 MemoryPool<T, BlockSize, ZeroOnDeallocate>::~MemoryPool() 133 noexcept { 134 std::lock_guard<std::recursive_mutex> lock(m_); 135 136 element_pointer curr = data_element_; 137 while (curr != nullptr) { 138 element_pointer prev = curr->next; 139 operator delete(reinterpret_cast<void*>(curr)); 140 curr = prev; 141 } 142 143 curr = free_element_; 144 while (curr != nullptr) { 145 element_pointer prev = curr->next; 146 operator delete(reinterpret_cast<void*>(curr)); 147 curr = prev; 148 } 149 } 150 151 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 152 inline typename MemoryPool<T, BlockSize, ZeroOnDeallocate>::pointer 153 MemoryPool<T, BlockSize, ZeroOnDeallocate>::address(reference x) 154 const noexcept { 155 return &x; 156 } 157 158 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 159 inline typename MemoryPool<T, BlockSize, ZeroOnDeallocate>::const_pointer 160 MemoryPool<T, BlockSize, ZeroOnDeallocate>::address(const_reference x) 161 const noexcept { 162 return &x; 163 } 164 165 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 166 void 167 MemoryPool<T, BlockSize, ZeroOnDeallocate>::allocateBlock() { 168 // Allocate space for the new block and store a pointer to the previous one 169 data_pointer new_block = reinterpret_cast<data_pointer> (operator new(BlockSize)); 170 element_pointer new_ele_pointer = reinterpret_cast<element_pointer>(new_block); 171 new_ele_pointer->pre = nullptr; 172 new_ele_pointer->next = nullptr; 173 174 if (data_element_) { 175 data_element_->pre = new_ele_pointer; 176 } 177 178 new_ele_pointer->next = data_element_; 179 data_element_ = new_ele_pointer; 180 } 181 182 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 183 inline typename MemoryPool<T, BlockSize, ZeroOnDeallocate>::pointer 184 MemoryPool<T, BlockSize, ZeroOnDeallocate>::allocate(size_type n, const_pointer hint) { 185 std::lock_guard<std::recursive_mutex> lock(m_); 186 187 if (free_element_ != nullptr) { 188 data_pointer body = 189 reinterpret_cast<data_pointer>(reinterpret_cast<data_pointer>(free_element_) + sizeof(element_type)); 190 191 size_type bodyPadding = padPointer(body, alignof(element_type)); 192 193 pointer result = reinterpret_cast<pointer>(reinterpret_cast<data_pointer>(body + bodyPadding)); 194 195 element_pointer tmp = free_element_; 196 197 free_element_ = free_element_->next; 198 199 if (free_element_) 200 free_element_->pre = nullptr; 201 202 tmp->next = data_element_; 203 if (data_element_) 204 data_element_->pre = tmp; 205 tmp->pre = nullptr; 206 data_element_ = tmp; 207 208 return result; 209 } 210 else { 211 allocateBlock(); 212 213 data_pointer body = 214 reinterpret_cast<data_pointer>(reinterpret_cast<data_pointer>(data_element_) + sizeof(element_type)); 215 216 size_type bodyPadding = padPointer(body, alignof(element_type)); 217 218 pointer result = reinterpret_cast<pointer>(reinterpret_cast<data_pointer>(body + bodyPadding)); 219 220 return result; 221 } 222 } 223 224 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 225 inline void 226 MemoryPool<T, BlockSize, ZeroOnDeallocate>::deallocate(pointer p, size_type n) { 227 std::lock_guard<std::recursive_mutex> lock(m_); 228 229 if (p != nullptr) { 230 element_pointer ele_p = 231 reinterpret_cast<element_pointer>(reinterpret_cast<data_pointer>(p) - sizeof(element_type)); 232 233 if (ZeroOnDeallocate) { 234 memset(reinterpret_cast<data_pointer>(p), 0, BlockSize - sizeof(element_type)); 235 } 236 237 if (ele_p->pre) { 238 ele_p->pre->next = ele_p->next; 239 } 240 241 if (ele_p->next) { 242 ele_p->next->pre = ele_p->pre; 243 } 244 245 if (ele_p->pre == nullptr) { 246 data_element_ = ele_p->next; 247 } 248 249 ele_p->pre = nullptr; 250 if (free_element_) { 251 ele_p->next = free_element_; 252 free_element_->pre = ele_p; 253 } 254 else { 255 ele_p->next = nullptr; 256 } 257 free_element_ = ele_p; 258 } 259 } 260 261 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 262 inline typename MemoryPool<T, BlockSize, ZeroOnDeallocate>::size_type 263 MemoryPool<T, BlockSize, ZeroOnDeallocate>::max_size() 264 const noexcept { 265 size_type maxBlocks = -1 / BlockSize; 266 return (BlockSize - sizeof(data_pointer)) / sizeof(element_type) * maxBlocks; 267 } 268 269 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 270 template <class U, class... Args> 271 inline void 272 MemoryPool<T, BlockSize, ZeroOnDeallocate>::construct(U* p, Args&&... args) { 273 new (p) U(std::forward<Args>(args)...); 274 } 275 276 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 277 template <class U> 278 inline void 279 MemoryPool<T, BlockSize, ZeroOnDeallocate>::destroy(U* p) { 280 p->~U(); 281 } 282 283 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 284 template <class... Args> 285 inline typename MemoryPool<T, BlockSize, ZeroOnDeallocate>::pointer 286 MemoryPool<T, BlockSize, ZeroOnDeallocate>::newElement(Args&&... args) { 287 std::lock_guard<std::recursive_mutex> lock(m_); 288 pointer result = allocate(); 289 construct<value_type>(result, std::forward<Args>(args)...); 290 return result; 291 } 292 293 template <typename T, size_t BlockSize, bool ZeroOnDeallocate> 294 inline void 295 MemoryPool<T, BlockSize, ZeroOnDeallocate>::deleteElement(pointer p) { 296 std::lock_guard<std::recursive_mutex> lock(m_); 297 if (p != nullptr) { 298 p->~value_type(); 299 deallocate(p); 300 } 301 } 302 } 303 } 304 305 #endif // PPX_BASE_MEMORY_POOL_H_ 306 307 308 使用示例: 309 #include <iostream> 310 #include <thread> 311 using namespace std; 312 class Apple { 313 public: 314 Apple() { 315 id_ = 0; 316 cout << "Apple()" << endl; 317 } 318 319 Apple(int id) { 320 id_ = id; 321 cout << "Apple(" << id_ << ")" << endl; 322 } 323 324 ~Apple() { 325 cout << "~Apple()" << endl; 326 } 327 328 void SetId(int id) { 329 id_ = id; 330 } 331 332 int GetId() { 333 return id_; 334 } 335 private: 336 int id_; 337 }; 338 339 340 341 void ThreadProc(ppx::base::MemoryPool<char> *mp) { 342 int i = 0; 343 while (i++ < 100000) { 344 char* p0 = (char*)mp->allocate(); 345 346 char* p1 = (char*)mp->allocate(); 347 348 mp->deallocate(p0); 349 350 char* p2 = (char*)mp->allocate(); 351 352 mp->deallocate(p1); 353 354 mp->deallocate(p2); 355 356 } 357 } 358 359 int main() 360 { 361 ppx::base::MemoryPool<char> mp; 362 int i = 0; 363 while (i++ < 100000) { 364 char* p0 = (char*)mp.allocate(); 365 366 char* p1 = (char*)mp.allocate(); 367 368 mp.deallocate(p0); 369 370 char* p2 = (char*)mp.allocate(); 371 372 mp.deallocate(p1); 373 374 mp.deallocate(p2); 375 376 } 377 378 std::thread th0(ThreadProc, &mp); 379 std::thread th1(ThreadProc, &mp); 380 std::thread th2(ThreadProc, &mp); 381 382 th0.join(); 383 th1.join(); 384 th2.join(); 385 386 Apple *apple = nullptr; 387 { 388 ppx::base::MemoryPool<Apple> mp2; 389 apple = mp2.newElement(10); 390 int a = apple->GetId(); 391 apple->SetId(10); 392 a = apple->GetId(); 393 394 mp2.deleteElement(apple); 395 } 396 397 apple->SetId(12); 398 int b = -4 % 4; 399 400 int *a = nullptr; 401 { 402 ppx::base::MemoryPool<int, 18> mp3; 403 a = mp3.allocate(); 404 *a = 100; 405 //mp3.deallocate(a); 406 407 int *b = mp3.allocate(); 408 *b = 200; 409 //mp3.deallocate(b); 410 411 mp3.deallocate(a); 412 mp3.deallocate(b); 413 414 int *c = mp3.allocate(); 415 *c = 300; 416 } 417 418 getchar(); 419 return 0; 420 }