handlealloc.inl 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. /*
  2. * Copyright 2010-2018 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  4. */
  5. #ifndef BX_HANDLE_ALLOC_H_HEADER_GUARD
  6. # error "Must be included from bx/handlealloc.h!"
  7. #endif // BX_HANDLE_ALLOC_H_HEADER_GUARD
  8. namespace bx
  9. {
  10. inline HandleAlloc::HandleAlloc(uint16_t _maxHandles)
  11. : m_numHandles(0)
  12. , m_maxHandles(_maxHandles)
  13. {
  14. reset();
  15. }
  16. inline HandleAlloc::~HandleAlloc()
  17. {
  18. }
  19. inline const uint16_t* HandleAlloc::getHandles() const
  20. {
  21. return getDensePtr();
  22. }
  23. inline uint16_t HandleAlloc::getHandleAt(uint16_t _at) const
  24. {
  25. return getDensePtr()[_at];
  26. }
  27. inline uint16_t HandleAlloc::getNumHandles() const
  28. {
  29. return m_numHandles;
  30. }
  31. inline uint16_t HandleAlloc::getMaxHandles() const
  32. {
  33. return m_maxHandles;
  34. }
  35. inline uint16_t HandleAlloc::alloc()
  36. {
  37. if (m_numHandles < m_maxHandles)
  38. {
  39. uint16_t index = m_numHandles;
  40. ++m_numHandles;
  41. uint16_t* dense = getDensePtr();
  42. uint16_t handle = dense[index];
  43. uint16_t* sparse = getSparsePtr();
  44. sparse[handle] = index;
  45. return handle;
  46. }
  47. return kInvalidHandle;
  48. }
  49. inline bool HandleAlloc::isValid(uint16_t _handle) const
  50. {
  51. uint16_t* dense = getDensePtr();
  52. uint16_t* sparse = getSparsePtr();
  53. uint16_t index = sparse[_handle];
  54. return index < m_numHandles
  55. && dense[index] == _handle
  56. ;
  57. }
  58. inline void HandleAlloc::free(uint16_t _handle)
  59. {
  60. uint16_t* dense = getDensePtr();
  61. uint16_t* sparse = getSparsePtr();
  62. uint16_t index = sparse[_handle];
  63. --m_numHandles;
  64. uint16_t temp = dense[m_numHandles];
  65. dense[m_numHandles] = _handle;
  66. sparse[temp] = index;
  67. dense[index] = temp;
  68. }
  69. inline void HandleAlloc::reset()
  70. {
  71. m_numHandles = 0;
  72. uint16_t* dense = getDensePtr();
  73. for (uint16_t ii = 0, num = m_maxHandles; ii < num; ++ii)
  74. {
  75. dense[ii] = ii;
  76. }
  77. }
  78. inline uint16_t* HandleAlloc::getDensePtr() const
  79. {
  80. uint8_t* ptr = (uint8_t*)reinterpret_cast<const uint8_t*>(this);
  81. return (uint16_t*)&ptr[sizeof(HandleAlloc)];
  82. }
  83. inline uint16_t* HandleAlloc::getSparsePtr() const
  84. {
  85. return &getDensePtr()[m_maxHandles];
  86. }
  87. inline HandleAlloc* createHandleAlloc(AllocatorI* _allocator, uint16_t _maxHandles)
  88. {
  89. uint8_t* ptr = (uint8_t*)BX_ALLOC(_allocator, sizeof(HandleAlloc) + 2*_maxHandles*sizeof(uint16_t) );
  90. return BX_PLACEMENT_NEW(ptr, HandleAlloc)(_maxHandles);
  91. }
  92. inline void destroyHandleAlloc(AllocatorI* _allocator, HandleAlloc* _handleAlloc)
  93. {
  94. _handleAlloc->~HandleAlloc();
  95. BX_FREE(_allocator, _handleAlloc);
  96. }
  97. template <uint16_t MaxHandlesT>
  98. inline HandleAllocT<MaxHandlesT>::HandleAllocT()
  99. : HandleAlloc(MaxHandlesT)
  100. {
  101. }
  102. template <uint16_t MaxHandlesT>
  103. inline HandleAllocT<MaxHandlesT>::~HandleAllocT()
  104. {
  105. }
  106. template <uint16_t MaxHandlesT>
  107. inline HandleListT<MaxHandlesT>::HandleListT()
  108. {
  109. reset();
  110. }
  111. template <uint16_t MaxHandlesT>
  112. inline void HandleListT<MaxHandlesT>::pushBack(uint16_t _handle)
  113. {
  114. insertAfter(m_back, _handle);
  115. }
  116. template <uint16_t MaxHandlesT>
  117. inline uint16_t HandleListT<MaxHandlesT>::popBack()
  118. {
  119. uint16_t last = kInvalidHandle != m_back
  120. ? m_back
  121. : m_front
  122. ;
  123. if (kInvalidHandle != last)
  124. {
  125. remove(last);
  126. }
  127. return last;
  128. }
  129. template <uint16_t MaxHandlesT>
  130. inline void HandleListT<MaxHandlesT>::pushFront(uint16_t _handle)
  131. {
  132. insertBefore(m_front, _handle);
  133. }
  134. template <uint16_t MaxHandlesT>
  135. inline uint16_t HandleListT<MaxHandlesT>::popFront()
  136. {
  137. uint16_t front = m_front;
  138. if (kInvalidHandle != front)
  139. {
  140. remove(front);
  141. }
  142. return front;
  143. }
  144. template <uint16_t MaxHandlesT>
  145. inline uint16_t HandleListT<MaxHandlesT>::getFront() const
  146. {
  147. return m_front;
  148. }
  149. template <uint16_t MaxHandlesT>
  150. inline uint16_t HandleListT<MaxHandlesT>::getBack() const
  151. {
  152. return m_back;
  153. }
  154. template <uint16_t MaxHandlesT>
  155. inline uint16_t HandleListT<MaxHandlesT>::getNext(uint16_t _handle) const
  156. {
  157. BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
  158. const Link& curr = m_links[_handle];
  159. return curr.m_next;
  160. }
  161. template <uint16_t MaxHandlesT>
  162. inline uint16_t HandleListT<MaxHandlesT>::getPrev(uint16_t _handle) const
  163. {
  164. BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
  165. const Link& curr = m_links[_handle];
  166. return curr.m_prev;
  167. }
  168. template <uint16_t MaxHandlesT>
  169. inline void HandleListT<MaxHandlesT>::remove(uint16_t _handle)
  170. {
  171. BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
  172. Link& curr = m_links[_handle];
  173. if (kInvalidHandle != curr.m_prev)
  174. {
  175. Link& prev = m_links[curr.m_prev];
  176. prev.m_next = curr.m_next;
  177. }
  178. else
  179. {
  180. m_front = curr.m_next;
  181. }
  182. if (kInvalidHandle != curr.m_next)
  183. {
  184. Link& next = m_links[curr.m_next];
  185. next.m_prev = curr.m_prev;
  186. }
  187. else
  188. {
  189. m_back = curr.m_prev;
  190. }
  191. curr.m_prev = kInvalidHandle;
  192. curr.m_next = kInvalidHandle;
  193. }
  194. template <uint16_t MaxHandlesT>
  195. inline void HandleListT<MaxHandlesT>::reset()
  196. {
  197. memSet(m_links, 0xff, sizeof(m_links) );
  198. m_front = kInvalidHandle;
  199. m_back = kInvalidHandle;
  200. }
  201. template <uint16_t MaxHandlesT>
  202. inline void HandleListT<MaxHandlesT>::insertBefore(uint16_t _before, uint16_t _handle)
  203. {
  204. Link& curr = m_links[_handle];
  205. curr.m_next = _before;
  206. if (kInvalidHandle != _before)
  207. {
  208. Link& link = m_links[_before];
  209. if (kInvalidHandle != link.m_prev)
  210. {
  211. Link& prev = m_links[link.m_prev];
  212. prev.m_next = _handle;
  213. }
  214. curr.m_prev = link.m_prev;
  215. link.m_prev = _handle;
  216. }
  217. updateFrontBack(_handle);
  218. }
  219. template <uint16_t MaxHandlesT>
  220. inline void HandleListT<MaxHandlesT>::insertAfter(uint16_t _after, uint16_t _handle)
  221. {
  222. Link& curr = m_links[_handle];
  223. curr.m_prev = _after;
  224. if (kInvalidHandle != _after)
  225. {
  226. Link& link = m_links[_after];
  227. if (kInvalidHandle != link.m_next)
  228. {
  229. Link& next = m_links[link.m_next];
  230. next.m_prev = _handle;
  231. }
  232. curr.m_next = link.m_next;
  233. link.m_next = _handle;
  234. }
  235. updateFrontBack(_handle);
  236. }
  237. template <uint16_t MaxHandlesT>
  238. inline bool HandleListT<MaxHandlesT>::isValid(uint16_t _handle) const
  239. {
  240. return _handle < MaxHandlesT;
  241. }
  242. template <uint16_t MaxHandlesT>
  243. inline void HandleListT<MaxHandlesT>::updateFrontBack(uint16_t _handle)
  244. {
  245. Link& curr = m_links[_handle];
  246. if (kInvalidHandle == curr.m_prev)
  247. {
  248. m_front = _handle;
  249. }
  250. if (kInvalidHandle == curr.m_next)
  251. {
  252. m_back = _handle;
  253. }
  254. }
  255. template <uint16_t MaxHandlesT>
  256. inline HandleAllocLruT<MaxHandlesT>::HandleAllocLruT()
  257. {
  258. reset();
  259. }
  260. template <uint16_t MaxHandlesT>
  261. inline HandleAllocLruT<MaxHandlesT>::~HandleAllocLruT()
  262. {
  263. }
  264. template <uint16_t MaxHandlesT>
  265. inline const uint16_t* HandleAllocLruT<MaxHandlesT>::getHandles() const
  266. {
  267. return m_alloc.getHandles();
  268. }
  269. template <uint16_t MaxHandlesT>
  270. inline uint16_t HandleAllocLruT<MaxHandlesT>::getHandleAt(uint16_t _at) const
  271. {
  272. return m_alloc.getHandleAt(_at);
  273. }
  274. template <uint16_t MaxHandlesT>
  275. inline uint16_t HandleAllocLruT<MaxHandlesT>::getNumHandles() const
  276. {
  277. return m_alloc.getNumHandles();
  278. }
  279. template <uint16_t MaxHandlesT>
  280. inline uint16_t HandleAllocLruT<MaxHandlesT>::getMaxHandles() const
  281. {
  282. return m_alloc.getMaxHandles();
  283. }
  284. template <uint16_t MaxHandlesT>
  285. inline uint16_t HandleAllocLruT<MaxHandlesT>::alloc()
  286. {
  287. uint16_t handle = m_alloc.alloc();
  288. if (kInvalidHandle != handle)
  289. {
  290. m_list.pushFront(handle);
  291. }
  292. return handle;
  293. }
  294. template <uint16_t MaxHandlesT>
  295. inline bool HandleAllocLruT<MaxHandlesT>::isValid(uint16_t _handle) const
  296. {
  297. return m_alloc.isValid(_handle);
  298. }
  299. template <uint16_t MaxHandlesT>
  300. inline void HandleAllocLruT<MaxHandlesT>::free(uint16_t _handle)
  301. {
  302. BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
  303. m_list.remove(_handle);
  304. m_alloc.free(_handle);
  305. }
  306. template <uint16_t MaxHandlesT>
  307. inline void HandleAllocLruT<MaxHandlesT>::touch(uint16_t _handle)
  308. {
  309. BX_CHECK(isValid(_handle), "Invalid handle %d!", _handle);
  310. m_list.remove(_handle);
  311. m_list.pushFront(_handle);
  312. }
  313. template <uint16_t MaxHandlesT>
  314. inline uint16_t HandleAllocLruT<MaxHandlesT>::getFront() const
  315. {
  316. return m_list.getFront();
  317. }
  318. template <uint16_t MaxHandlesT>
  319. inline uint16_t HandleAllocLruT<MaxHandlesT>::getBack() const
  320. {
  321. return m_list.getBack();
  322. }
  323. template <uint16_t MaxHandlesT>
  324. inline uint16_t HandleAllocLruT<MaxHandlesT>::getNext(uint16_t _handle) const
  325. {
  326. return m_list.getNext(_handle);
  327. }
  328. template <uint16_t MaxHandlesT>
  329. inline uint16_t HandleAllocLruT<MaxHandlesT>::getPrev(uint16_t _handle) const
  330. {
  331. return m_list.getPrev(_handle);
  332. }
  333. template <uint16_t MaxHandlesT>
  334. inline void HandleAllocLruT<MaxHandlesT>::reset()
  335. {
  336. m_list.reset();
  337. m_alloc.reset();
  338. }
  339. template <uint32_t MaxCapacityT, typename KeyT>
  340. inline HandleHashMapT<MaxCapacityT, KeyT>::HandleHashMapT()
  341. : m_maxCapacity(MaxCapacityT)
  342. {
  343. reset();
  344. }
  345. template <uint32_t MaxCapacityT, typename KeyT>
  346. inline HandleHashMapT<MaxCapacityT, KeyT>::~HandleHashMapT()
  347. {
  348. }
  349. template <uint32_t MaxCapacityT, typename KeyT>
  350. inline bool HandleHashMapT<MaxCapacityT, KeyT>::insert(KeyT _key, uint16_t _handle)
  351. {
  352. if (kInvalidHandle == _handle)
  353. {
  354. return false;
  355. }
  356. const KeyT hash = mix(_key);
  357. const uint32_t firstIdx = hash % MaxCapacityT;
  358. uint32_t idx = firstIdx;
  359. do
  360. {
  361. if (m_handle[idx] == kInvalidHandle)
  362. {
  363. m_key[idx] = _key;
  364. m_handle[idx] = _handle;
  365. ++m_numElements;
  366. return true;
  367. }
  368. if (m_key[idx] == _key)
  369. {
  370. return false;
  371. }
  372. idx = (idx + 1) % MaxCapacityT;
  373. } while (idx != firstIdx);
  374. return false;
  375. }
  376. template <uint32_t MaxCapacityT, typename KeyT>
  377. inline bool HandleHashMapT<MaxCapacityT, KeyT>::removeByKey(KeyT _key)
  378. {
  379. uint32_t idx = findIndex(_key);
  380. if (UINT32_MAX != idx)
  381. {
  382. removeIndex(idx);
  383. return true;
  384. }
  385. return false;
  386. }
  387. template <uint32_t MaxCapacityT, typename KeyT>
  388. inline bool HandleHashMapT<MaxCapacityT, KeyT>::removeByHandle(uint16_t _handle)
  389. {
  390. if (kInvalidHandle != _handle)
  391. {
  392. for (uint32_t idx = 0; idx < MaxCapacityT; ++idx)
  393. {
  394. if (m_handle[idx] == _handle)
  395. {
  396. removeIndex(idx);
  397. }
  398. }
  399. }
  400. return false;
  401. }
  402. template <uint32_t MaxCapacityT, typename KeyT>
  403. inline uint16_t HandleHashMapT<MaxCapacityT, KeyT>::find(KeyT _key) const
  404. {
  405. uint32_t idx = findIndex(_key);
  406. if (UINT32_MAX != idx)
  407. {
  408. return m_handle[idx];
  409. }
  410. return kInvalidHandle;
  411. }
  412. template <uint32_t MaxCapacityT, typename KeyT>
  413. inline void HandleHashMapT<MaxCapacityT, KeyT>::reset()
  414. {
  415. memSet(m_handle, 0xff, sizeof(m_handle) );
  416. m_numElements = 0;
  417. }
  418. template <uint32_t MaxCapacityT, typename KeyT>
  419. inline uint32_t HandleHashMapT<MaxCapacityT, KeyT>::getNumElements() const
  420. {
  421. return m_numElements;
  422. }
  423. template <uint32_t MaxCapacityT, typename KeyT>
  424. inline uint32_t HandleHashMapT<MaxCapacityT, KeyT>::getMaxCapacity() const
  425. {
  426. return m_maxCapacity;
  427. }
  428. template <uint32_t MaxCapacityT, typename KeyT>
  429. inline typename HandleHashMapT<MaxCapacityT, KeyT>::Iterator HandleHashMapT<MaxCapacityT, KeyT>::first() const
  430. {
  431. Iterator it;
  432. it.handle = kInvalidHandle;
  433. it.pos = 0;
  434. it.num = m_numElements;
  435. if (0 == it.num)
  436. {
  437. return it;
  438. }
  439. ++it.num;
  440. next(it);
  441. return it;
  442. }
  443. template <uint32_t MaxCapacityT, typename KeyT>
  444. inline bool HandleHashMapT<MaxCapacityT, KeyT>::next(Iterator& _it) const
  445. {
  446. if (0 == _it.num)
  447. {
  448. return false;
  449. }
  450. for (
  451. ;_it.pos < MaxCapacityT && kInvalidHandle == m_handle[_it.pos]
  452. ; ++_it.pos
  453. );
  454. _it.handle = m_handle[_it.pos];
  455. ++_it.pos;
  456. --_it.num;
  457. return true;
  458. }
  459. template <uint32_t MaxCapacityT, typename KeyT>
  460. inline uint32_t HandleHashMapT<MaxCapacityT, KeyT>::findIndex(KeyT _key) const
  461. {
  462. const KeyT hash = mix(_key);
  463. const uint32_t firstIdx = hash % MaxCapacityT;
  464. uint32_t idx = firstIdx;
  465. do
  466. {
  467. if (m_handle[idx] == kInvalidHandle)
  468. {
  469. return UINT32_MAX;
  470. }
  471. if (m_key[idx] == _key)
  472. {
  473. return idx;
  474. }
  475. idx = (idx + 1) % MaxCapacityT;
  476. } while (idx != firstIdx);
  477. return UINT32_MAX;
  478. }
  479. template <uint32_t MaxCapacityT, typename KeyT>
  480. inline void HandleHashMapT<MaxCapacityT, KeyT>::removeIndex(uint32_t _idx)
  481. {
  482. m_handle[_idx] = kInvalidHandle;
  483. --m_numElements;
  484. for (uint32_t idx = (_idx + 1) % MaxCapacityT
  485. ; m_handle[idx] != kInvalidHandle
  486. ; idx = (idx + 1) % MaxCapacityT)
  487. {
  488. if (m_handle[idx] != kInvalidHandle)
  489. {
  490. const KeyT key = m_key[idx];
  491. if (idx != findIndex(key) )
  492. {
  493. const uint16_t handle = m_handle[idx];
  494. m_handle[idx] = kInvalidHandle;
  495. --m_numElements;
  496. insert(key, handle);
  497. }
  498. }
  499. }
  500. }
  501. template <uint32_t MaxCapacityT, typename KeyT>
  502. inline uint32_t HandleHashMapT<MaxCapacityT, KeyT>::mix(uint32_t _x) const
  503. {
  504. const uint32_t tmp0 = uint32_mul(_x, UINT32_C(2246822519) );
  505. const uint32_t tmp1 = uint32_rol(tmp0, 13);
  506. const uint32_t result = uint32_mul(tmp1, UINT32_C(2654435761) );
  507. return result;
  508. }
  509. template <uint32_t MaxCapacityT, typename KeyT>
  510. inline uint64_t HandleHashMapT<MaxCapacityT, KeyT>::mix(uint64_t _x) const
  511. {
  512. const uint64_t tmp0 = uint64_mul(_x, UINT64_C(14029467366897019727) );
  513. const uint64_t tmp1 = uint64_rol(tmp0, 31);
  514. const uint64_t result = uint64_mul(tmp1, UINT64_C(11400714785074694791) );
  515. return result;
  516. }
  517. template <uint16_t MaxHandlesT, typename KeyT>
  518. inline HandleHashMapAllocT<MaxHandlesT, KeyT>::HandleHashMapAllocT()
  519. {
  520. reset();
  521. }
  522. template <uint16_t MaxHandlesT, typename KeyT>
  523. inline HandleHashMapAllocT<MaxHandlesT, KeyT>::~HandleHashMapAllocT()
  524. {
  525. }
  526. template <uint16_t MaxHandlesT, typename KeyT>
  527. inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::alloc(KeyT _key)
  528. {
  529. uint16_t handle = m_alloc.alloc();
  530. if (kInvalidHandle == handle)
  531. {
  532. return kInvalidHandle;
  533. }
  534. bool ok = m_table.insert(_key, handle);
  535. if (!ok)
  536. {
  537. m_alloc.free(handle);
  538. return kInvalidHandle;
  539. }
  540. return handle;
  541. }
  542. template <uint16_t MaxHandlesT, typename KeyT>
  543. inline void HandleHashMapAllocT<MaxHandlesT, KeyT>::free(KeyT _key)
  544. {
  545. uint16_t handle = m_table.find(_key);
  546. if (kInvalidHandle == handle)
  547. {
  548. return;
  549. }
  550. m_table.removeByKey(_key);
  551. m_alloc.free(handle);
  552. }
  553. template <uint16_t MaxHandlesT, typename KeyT>
  554. inline void HandleHashMapAllocT<MaxHandlesT, KeyT>::free(uint16_t _handle)
  555. {
  556. m_table.removeByHandle(_handle);
  557. m_alloc.free(_handle);
  558. }
  559. template <uint16_t MaxHandlesT, typename KeyT>
  560. inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::find(KeyT _key) const
  561. {
  562. return m_table.find(_key);
  563. }
  564. template <uint16_t MaxHandlesT, typename KeyT>
  565. inline const uint16_t* HandleHashMapAllocT<MaxHandlesT, KeyT>::getHandles() const
  566. {
  567. return m_alloc.getHandles();
  568. }
  569. template <uint16_t MaxHandlesT, typename KeyT>
  570. inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::getHandleAt(uint16_t _at) const
  571. {
  572. return m_alloc.getHandleAt(_at);
  573. }
  574. template <uint16_t MaxHandlesT, typename KeyT>
  575. inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::getNumHandles() const
  576. {
  577. return m_alloc.getNumHandles();
  578. }
  579. template <uint16_t MaxHandlesT, typename KeyT>
  580. inline uint16_t HandleHashMapAllocT<MaxHandlesT, KeyT>::getMaxHandles() const
  581. {
  582. return m_alloc.getMaxHandles();
  583. }
  584. template <uint16_t MaxHandlesT, typename KeyT>
  585. inline bool HandleHashMapAllocT<MaxHandlesT, KeyT>::isValid(uint16_t _handle) const
  586. {
  587. return m_alloc.isValid(_handle);
  588. }
  589. template <uint16_t MaxHandlesT, typename KeyT>
  590. inline void HandleHashMapAllocT<MaxHandlesT, KeyT>::reset()
  591. {
  592. m_table.reset();
  593. m_alloc.reset();
  594. }
  595. } // namespace bx