BTree.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #ifndef __BTREE_H__
  21. #define __BTREE_H__
  22. /*
  23. ===============================================================================
  24. Balanced Search Tree
  25. ===============================================================================
  26. */
  27. //#define BTREE_CHECK
  28. template< class objType, class keyType >
  29. class idBTreeNode {
  30. public:
  31. keyType key; // key used for sorting
  32. objType * object; // if != NULL pointer to object stored in leaf node
  33. idBTreeNode * parent; // parent node
  34. idBTreeNode * next; // next sibling
  35. idBTreeNode * prev; // prev sibling
  36. int numChildren; // number of children
  37. idBTreeNode * firstChild; // first child
  38. idBTreeNode * lastChild; // last child
  39. };
  40. template< class objType, class keyType, int maxChildrenPerNode >
  41. class idBTree {
  42. public:
  43. idBTree();
  44. ~idBTree();
  45. void Init();
  46. void Shutdown();
  47. idBTreeNode<objType,keyType> * Add( objType *object, keyType key ); // add an object to the tree
  48. void Remove( idBTreeNode<objType,keyType> *node ); // remove an object node from the tree
  49. idBTreeNode<objType,keyType> * NodeFind( keyType key ) const; // find an object using the given key
  50. idBTreeNode<objType,keyType> * NodeFindSmallestLargerEqual( keyType key ) const; // find an object with the smallest key larger equal the given key
  51. idBTreeNode<objType,keyType> * NodeFindLargestSmallerEqual( keyType key ) const; // find an object with the largest key smaller equal the given key
  52. objType * Find( keyType key ) const; // find an object using the given key
  53. objType * FindSmallestLargerEqual( keyType key ) const; // find an object with the smallest key larger equal the given key
  54. objType * FindLargestSmallerEqual( keyType key ) const; // find an object with the largest key smaller equal the given key
  55. idBTreeNode<objType,keyType> * GetRoot() const; // returns the root node of the tree
  56. int GetNodeCount() const; // returns the total number of nodes in the tree
  57. idBTreeNode<objType,keyType> * GetNext( idBTreeNode<objType,keyType> *node ) const; // goes through all nodes of the tree
  58. idBTreeNode<objType,keyType> * GetNextLeaf( idBTreeNode<objType,keyType> *node ) const; // goes through all leaf nodes of the tree
  59. private:
  60. idBTreeNode<objType,keyType> * root;
  61. idBlockAlloc<idBTreeNode<objType,keyType>,128> nodeAllocator;
  62. idBTreeNode<objType,keyType> * AllocNode();
  63. void FreeNode( idBTreeNode<objType,keyType> *node );
  64. void SplitNode( idBTreeNode<objType,keyType> *node );
  65. idBTreeNode<objType,keyType> * MergeNodes( idBTreeNode<objType,keyType> *node1, idBTreeNode<objType,keyType> *node2 );
  66. void CheckTree_r( idBTreeNode<objType,keyType> *node, int &numNodes ) const;
  67. void CheckTree() const;
  68. };
  69. template< class objType, class keyType, int maxChildrenPerNode >
  70. ID_INLINE idBTree<objType,keyType,maxChildrenPerNode>::idBTree() {
  71. assert( maxChildrenPerNode >= 4 );
  72. root = NULL;
  73. }
  74. template< class objType, class keyType, int maxChildrenPerNode >
  75. ID_INLINE idBTree<objType,keyType,maxChildrenPerNode>::~idBTree() {
  76. Shutdown();
  77. }
  78. template< class objType, class keyType, int maxChildrenPerNode >
  79. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::Init() {
  80. root = AllocNode();
  81. }
  82. template< class objType, class keyType, int maxChildrenPerNode >
  83. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::Shutdown() {
  84. nodeAllocator.Shutdown();
  85. root = NULL;
  86. }
  87. template< class objType, class keyType, int maxChildrenPerNode >
  88. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::Add( objType *object, keyType key ) {
  89. idBTreeNode<objType,keyType> *node, *child, *newNode;
  90. if ( root == NULL ) {
  91. root = AllocNode();
  92. }
  93. if ( root->numChildren >= maxChildrenPerNode ) {
  94. newNode = AllocNode();
  95. newNode->key = root->key;
  96. newNode->firstChild = root;
  97. newNode->lastChild = root;
  98. newNode->numChildren = 1;
  99. root->parent = newNode;
  100. SplitNode( root );
  101. root = newNode;
  102. }
  103. newNode = AllocNode();
  104. newNode->key = key;
  105. newNode->object = object;
  106. for ( node = root; node->firstChild != NULL; node = child ) {
  107. if ( key > node->key ) {
  108. node->key = key;
  109. }
  110. // find the first child with a key larger equal to the key of the new node
  111. for( child = node->firstChild; child->next; child = child->next ) {
  112. if ( key <= child->key ) {
  113. break;
  114. }
  115. }
  116. if ( child->object ) {
  117. if ( key <= child->key ) {
  118. // insert new node before child
  119. if ( child->prev ) {
  120. child->prev->next = newNode;
  121. } else {
  122. node->firstChild = newNode;
  123. }
  124. newNode->prev = child->prev;
  125. newNode->next = child;
  126. child->prev = newNode;
  127. } else {
  128. // insert new node after child
  129. if ( child->next ) {
  130. child->next->prev = newNode;
  131. } else {
  132. node->lastChild = newNode;
  133. }
  134. newNode->prev = child;
  135. newNode->next = child->next;
  136. child->next = newNode;
  137. }
  138. newNode->parent = node;
  139. node->numChildren++;
  140. #ifdef BTREE_CHECK
  141. CheckTree();
  142. #endif
  143. return newNode;
  144. }
  145. // make sure the child has room to store another node
  146. if ( child->numChildren >= maxChildrenPerNode ) {
  147. SplitNode( child );
  148. if ( key <= child->prev->key ) {
  149. child = child->prev;
  150. }
  151. }
  152. }
  153. // we only end up here if the root node is empty
  154. newNode->parent = root;
  155. root->key = key;
  156. root->firstChild = newNode;
  157. root->lastChild = newNode;
  158. root->numChildren++;
  159. #ifdef BTREE_CHECK
  160. CheckTree();
  161. #endif
  162. return newNode;
  163. }
  164. template< class objType, class keyType, int maxChildrenPerNode >
  165. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::Remove( idBTreeNode<objType,keyType> *node ) {
  166. idBTreeNode<objType,keyType> *parent;
  167. assert( node->object != NULL );
  168. // unlink the node from it's parent
  169. if ( node->prev ) {
  170. node->prev->next = node->next;
  171. } else {
  172. node->parent->firstChild = node->next;
  173. }
  174. if ( node->next ) {
  175. node->next->prev = node->prev;
  176. } else {
  177. node->parent->lastChild = node->prev;
  178. }
  179. node->parent->numChildren--;
  180. // make sure there are no parent nodes with a single child
  181. for ( parent = node->parent; parent != root && parent->numChildren <= 1; parent = parent->parent ) {
  182. if ( parent->next ) {
  183. parent = MergeNodes( parent, parent->next );
  184. } else if ( parent->prev ) {
  185. parent = MergeNodes( parent->prev, parent );
  186. }
  187. // a parent may not use a key higher than the key of it's last child
  188. if ( parent->key > parent->lastChild->key ) {
  189. parent->key = parent->lastChild->key;
  190. }
  191. if ( parent->numChildren > maxChildrenPerNode ) {
  192. SplitNode( parent );
  193. break;
  194. }
  195. }
  196. for ( ; parent != NULL && parent->lastChild != NULL; parent = parent->parent ) {
  197. // a parent may not use a key higher than the key of it's last child
  198. if ( parent->key > parent->lastChild->key ) {
  199. parent->key = parent->lastChild->key;
  200. }
  201. }
  202. // free the node
  203. FreeNode( node );
  204. // remove the root node if it has a single internal node as child
  205. if ( root->numChildren == 1 && root->firstChild->object == NULL ) {
  206. idBTreeNode<objType,keyType> *oldRoot = root;
  207. root->firstChild->parent = NULL;
  208. root = root->firstChild;
  209. FreeNode( oldRoot );
  210. }
  211. #ifdef BTREE_CHECK
  212. CheckTree();
  213. #endif
  214. }
  215. template< class objType, class keyType, int maxChildrenPerNode >
  216. ID_INLINE idBTreeNode<objType,keyType> * idBTree<objType,keyType,maxChildrenPerNode>::NodeFind( keyType key ) const {
  217. idBTreeNode<objType,keyType> *node;
  218. for ( node = root->firstChild; node != NULL; node = node->firstChild ) {
  219. while( node->next ) {
  220. if ( node->key >= key ) {
  221. break;
  222. }
  223. node = node->next;
  224. }
  225. if ( node->object ) {
  226. if ( node->key == key ) {
  227. return node;
  228. } else {
  229. return NULL;
  230. }
  231. }
  232. }
  233. return NULL;
  234. }
  235. template< class objType, class keyType, int maxChildrenPerNode >
  236. ID_INLINE idBTreeNode<objType,keyType> * idBTree<objType,keyType,maxChildrenPerNode>::NodeFindSmallestLargerEqual( keyType key ) const {
  237. idBTreeNode<objType,keyType> *node;
  238. if ( root == NULL ) {
  239. return NULL;
  240. }
  241. for ( node = root->firstChild; node != NULL; node = node->firstChild ) {
  242. while( node->next ) {
  243. if ( node->key >= key ) {
  244. break;
  245. }
  246. node = node->next;
  247. }
  248. if ( node->object ) {
  249. if ( node->key >= key ) {
  250. return node;
  251. } else {
  252. return NULL;
  253. }
  254. }
  255. }
  256. return NULL;
  257. }
  258. template< class objType, class keyType, int maxChildrenPerNode >
  259. ID_INLINE idBTreeNode<objType,keyType> * idBTree<objType,keyType,maxChildrenPerNode>::NodeFindLargestSmallerEqual( keyType key ) const {
  260. idBTreeNode<objType,keyType> *node;
  261. if ( root == NULL ) {
  262. return NULL;
  263. }
  264. idBTreeNode<objType,keyType> * smaller = NULL;
  265. for ( node = root->firstChild; node != NULL; node = node->firstChild ) {
  266. while( node->next ) {
  267. if ( node->key >= key ) {
  268. break;
  269. }
  270. smaller = node;
  271. node = node->next;
  272. }
  273. if ( node->object ) {
  274. if ( node->key <= key ) {
  275. return node;
  276. } else if ( smaller == NULL ) {
  277. return NULL;
  278. } else {
  279. node = smaller;
  280. if ( node->object ) {
  281. return node;
  282. }
  283. }
  284. }
  285. }
  286. return NULL;
  287. }
  288. template< class objType, class keyType, int maxChildrenPerNode >
  289. ID_INLINE objType *idBTree<objType,keyType,maxChildrenPerNode>::Find( keyType key ) const {
  290. idBTreeNode<objType,keyType> * node = NodeFind( key );
  291. if ( node == NULL ) {
  292. return NULL;
  293. } else {
  294. return node->object;
  295. }
  296. }
  297. template< class objType, class keyType, int maxChildrenPerNode >
  298. ID_INLINE objType *idBTree<objType,keyType,maxChildrenPerNode>::FindSmallestLargerEqual( keyType key ) const {
  299. idBTreeNode<objType,keyType> * node = NodeFindSmallestLargerEqual( key );
  300. if ( node == NULL ) {
  301. return NULL;
  302. } else {
  303. return node->object;
  304. }
  305. }
  306. template< class objType, class keyType, int maxChildrenPerNode >
  307. ID_INLINE objType *idBTree<objType,keyType,maxChildrenPerNode>::FindLargestSmallerEqual( keyType key ) const {
  308. idBTreeNode<objType,keyType> * node = NodeFindLargestSmallerEqual( key );
  309. if ( node == NULL ) {
  310. return NULL;
  311. } else {
  312. return node->object;
  313. }
  314. }
  315. template< class objType, class keyType, int maxChildrenPerNode >
  316. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::GetRoot() const {
  317. return root;
  318. }
  319. template< class objType, class keyType, int maxChildrenPerNode >
  320. ID_INLINE int idBTree<objType,keyType,maxChildrenPerNode>::GetNodeCount() const {
  321. return nodeAllocator.GetAllocCount();
  322. }
  323. template< class objType, class keyType, int maxChildrenPerNode >
  324. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::GetNext( idBTreeNode<objType,keyType> *node ) const {
  325. if ( node->firstChild ) {
  326. return node->firstChild;
  327. } else {
  328. while( node && node->next == NULL ) {
  329. node = node->parent;
  330. }
  331. return node;
  332. }
  333. }
  334. template< class objType, class keyType, int maxChildrenPerNode >
  335. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::GetNextLeaf( idBTreeNode<objType,keyType> *node ) const {
  336. if ( node->firstChild ) {
  337. while ( node->firstChild ) {
  338. node = node->firstChild;
  339. }
  340. return node;
  341. } else {
  342. while( node && node->next == NULL ) {
  343. node = node->parent;
  344. }
  345. if ( node ) {
  346. node = node->next;
  347. while ( node->firstChild ) {
  348. node = node->firstChild;
  349. }
  350. return node;
  351. } else {
  352. return NULL;
  353. }
  354. }
  355. }
  356. template< class objType, class keyType, int maxChildrenPerNode >
  357. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::AllocNode() {
  358. idBTreeNode<objType,keyType> *node = nodeAllocator.Alloc();
  359. node->key = 0;
  360. node->parent = NULL;
  361. node->next = NULL;
  362. node->prev = NULL;
  363. node->numChildren = 0;
  364. node->firstChild = NULL;
  365. node->lastChild = NULL;
  366. node->object = NULL;
  367. return node;
  368. }
  369. template< class objType, class keyType, int maxChildrenPerNode >
  370. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::FreeNode( idBTreeNode<objType,keyType> *node ) {
  371. nodeAllocator.Free( node );
  372. }
  373. template< class objType, class keyType, int maxChildrenPerNode >
  374. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::SplitNode( idBTreeNode<objType,keyType> *node ) {
  375. int i;
  376. idBTreeNode<objType,keyType> *child, *newNode;
  377. // allocate a new node
  378. newNode = AllocNode();
  379. newNode->parent = node->parent;
  380. // divide the children over the two nodes
  381. child = node->firstChild;
  382. child->parent = newNode;
  383. for ( i = 3; i < node->numChildren; i += 2 ) {
  384. child = child->next;
  385. child->parent = newNode;
  386. }
  387. newNode->key = child->key;
  388. newNode->numChildren = node->numChildren / 2;
  389. newNode->firstChild = node->firstChild;
  390. newNode->lastChild = child;
  391. node->numChildren -= newNode->numChildren;
  392. node->firstChild = child->next;
  393. child->next->prev = NULL;
  394. child->next = NULL;
  395. // add the new child to the parent before the split node
  396. assert( node->parent->numChildren < maxChildrenPerNode );
  397. if ( node->prev ) {
  398. node->prev->next = newNode;
  399. } else {
  400. node->parent->firstChild = newNode;
  401. }
  402. newNode->prev = node->prev;
  403. newNode->next = node;
  404. node->prev = newNode;
  405. node->parent->numChildren++;
  406. }
  407. template< class objType, class keyType, int maxChildrenPerNode >
  408. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::MergeNodes( idBTreeNode<objType,keyType> *node1, idBTreeNode<objType,keyType> *node2 ) {
  409. idBTreeNode<objType,keyType> *child;
  410. assert( node1->parent == node2->parent );
  411. assert( node1->next == node2 && node2->prev == node1 );
  412. assert( node1->object == NULL && node2->object == NULL );
  413. assert( node1->numChildren >= 1 && node2->numChildren >= 1 );
  414. for ( child = node1->firstChild; child->next; child = child->next ) {
  415. child->parent = node2;
  416. }
  417. child->parent = node2;
  418. child->next = node2->firstChild;
  419. node2->firstChild->prev = child;
  420. node2->firstChild = node1->firstChild;
  421. node2->numChildren += node1->numChildren;
  422. // unlink the first node from the parent
  423. if ( node1->prev ) {
  424. node1->prev->next = node2;
  425. } else {
  426. node1->parent->firstChild = node2;
  427. }
  428. node2->prev = node1->prev;
  429. node2->parent->numChildren--;
  430. FreeNode( node1 );
  431. return node2;
  432. }
  433. template< class objType, class keyType, int maxChildrenPerNode >
  434. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::CheckTree_r( idBTreeNode<objType,keyType> *node, int &numNodes ) const {
  435. int numChildren;
  436. idBTreeNode<objType,keyType> *child;
  437. numNodes++;
  438. // the root node may have zero children and leaf nodes always have zero children, all other nodes should have at least 2 and at most maxChildrenPerNode children
  439. assert( ( node == root ) || ( node->object != NULL && node->numChildren == 0 ) || ( node->numChildren >= 2 && node->numChildren <= maxChildrenPerNode ) );
  440. // the key of a node may never be larger than the key of it's last child
  441. assert( ( node->lastChild == NULL ) || ( node->key <= node->lastChild->key ) );
  442. numChildren = 0;
  443. for ( child = node->firstChild; child; child = child->next ) {
  444. numChildren++;
  445. // make sure the children are properly linked
  446. if ( child->prev == NULL ) {
  447. assert( node->firstChild == child );
  448. } else {
  449. assert( child->prev->next == child );
  450. }
  451. if ( child->next == NULL ) {
  452. assert( node->lastChild == child );
  453. } else {
  454. assert( child->next->prev == child );
  455. }
  456. // recurse down the tree
  457. CheckTree_r( child, numNodes );
  458. }
  459. // the number of children should equal the number of linked children
  460. assert( numChildren == node->numChildren );
  461. }
  462. template< class objType, class keyType, int maxChildrenPerNode >
  463. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::CheckTree() const {
  464. int numNodes = 0;
  465. idBTreeNode<objType,keyType> *node, *lastNode;
  466. CheckTree_r( root, numNodes );
  467. // the number of nodes in the tree should equal the number of allocated nodes
  468. assert( numNodes == nodeAllocator.GetAllocCount() );
  469. // all the leaf nodes should be ordered
  470. lastNode = GetNextLeaf( GetRoot() );
  471. if ( lastNode ) {
  472. for ( node = GetNextLeaf( lastNode ); node; lastNode = node, node = GetNextLeaf( node ) ) {
  473. assert( lastNode->key <= node->key );
  474. }
  475. }
  476. }
  477. #endif /* !__BTREE_H__ */