BTree.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. // Copyright (C) 2004 Id Software, Inc.
  2. //
  3. #ifndef __BTREE_H__
  4. #define __BTREE_H__
  5. /*
  6. ===============================================================================
  7. Balanced Search Tree
  8. ===============================================================================
  9. */
  10. //#define BTREE_CHECK
  11. template< class objType, class keyType >
  12. class idBTreeNode {
  13. public:
  14. keyType key; // key used for sorting
  15. objType * object; // if != NULL pointer to object stored in leaf node
  16. idBTreeNode * parent; // parent node
  17. idBTreeNode * next; // next sibling
  18. idBTreeNode * prev; // prev sibling
  19. int numChildren; // number of children
  20. idBTreeNode * firstChild; // first child
  21. idBTreeNode * lastChild; // last child
  22. };
  23. template< class objType, class keyType, int maxChildrenPerNode >
  24. class idBTree {
  25. public:
  26. idBTree( void );
  27. ~idBTree( void );
  28. void Init( void );
  29. void Shutdown( void );
  30. idBTreeNode<objType,keyType> * Add( objType *object, keyType key ); // add an object to the tree
  31. void Remove( idBTreeNode<objType,keyType> *node ); // remove an object node from the tree
  32. objType * Find( keyType key ) const; // find an object using the given key
  33. objType * FindSmallestLargerEqual( keyType key ) const; // find an object with the smallest key larger equal the given key
  34. objType * FindLargestSmallerEqual( keyType key ) const; // find an object with the largest key smaller equal the given key
  35. idBTreeNode<objType,keyType> * GetRoot( void ) const; // returns the root node of the tree
  36. int GetNodeCount( void ) const; // returns the total number of nodes in the tree
  37. idBTreeNode<objType,keyType> * GetNext( idBTreeNode<objType,keyType> *node ) const; // goes through all nodes of the tree
  38. idBTreeNode<objType,keyType> * GetNextLeaf( idBTreeNode<objType,keyType> *node ) const; // goes through all leaf nodes of the tree
  39. private:
  40. idBTreeNode<objType,keyType> * root;
  41. idBlockAlloc<idBTreeNode<objType,keyType>,128> nodeAllocator;
  42. idBTreeNode<objType,keyType> * AllocNode( void );
  43. void FreeNode( idBTreeNode<objType,keyType> *node );
  44. void SplitNode( idBTreeNode<objType,keyType> *node );
  45. idBTreeNode<objType,keyType> * MergeNodes( idBTreeNode<objType,keyType> *node1, idBTreeNode<objType,keyType> *node2 );
  46. void CheckTree_r( idBTreeNode<objType,keyType> *node, int &numNodes ) const;
  47. void CheckTree( void ) const;
  48. };
  49. template< class objType, class keyType, int maxChildrenPerNode >
  50. ID_INLINE idBTree<objType,keyType,maxChildrenPerNode>::idBTree( void ) {
  51. assert( maxChildrenPerNode >= 4 );
  52. root = NULL;
  53. }
  54. template< class objType, class keyType, int maxChildrenPerNode >
  55. ID_INLINE idBTree<objType,keyType,maxChildrenPerNode>::~idBTree( void ) {
  56. Shutdown();
  57. }
  58. template< class objType, class keyType, int maxChildrenPerNode >
  59. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::Init( void ) {
  60. root = AllocNode();
  61. }
  62. template< class objType, class keyType, int maxChildrenPerNode >
  63. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::Shutdown( void ) {
  64. nodeAllocator.Shutdown();
  65. root = NULL;
  66. }
  67. template< class objType, class keyType, int maxChildrenPerNode >
  68. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::Add( objType *object, keyType key ) {
  69. idBTreeNode<objType,keyType> *node, *child, *newNode;
  70. if ( root->numChildren >= maxChildrenPerNode ) {
  71. newNode = AllocNode();
  72. newNode->key = root->key;
  73. newNode->firstChild = root;
  74. newNode->lastChild = root;
  75. newNode->numChildren = 1;
  76. root->parent = newNode;
  77. SplitNode( root );
  78. root = newNode;
  79. }
  80. newNode = AllocNode();
  81. newNode->key = key;
  82. newNode->object = object;
  83. for ( node = root; node->firstChild != NULL; node = child ) {
  84. if ( key > node->key ) {
  85. node->key = key;
  86. }
  87. // find the first child with a key larger equal to the key of the new node
  88. for( child = node->firstChild; child->next; child = child->next ) {
  89. if ( key <= child->key ) {
  90. break;
  91. }
  92. }
  93. if ( child->object ) {
  94. if ( key <= child->key ) {
  95. // insert new node before child
  96. if ( child->prev ) {
  97. child->prev->next = newNode;
  98. } else {
  99. node->firstChild = newNode;
  100. }
  101. newNode->prev = child->prev;
  102. newNode->next = child;
  103. child->prev = newNode;
  104. } else {
  105. // insert new node after child
  106. if ( child->next ) {
  107. child->next->prev = newNode;
  108. } else {
  109. node->lastChild = newNode;
  110. }
  111. newNode->prev = child;
  112. newNode->next = child->next;
  113. child->next = newNode;
  114. }
  115. newNode->parent = node;
  116. node->numChildren++;
  117. #ifdef BTREE_CHECK
  118. CheckTree();
  119. #endif
  120. return newNode;
  121. }
  122. // make sure the child has room to store another node
  123. if ( child->numChildren >= maxChildrenPerNode ) {
  124. SplitNode( child );
  125. if ( key <= child->prev->key ) {
  126. child = child->prev;
  127. }
  128. }
  129. }
  130. // we only end up here if the root node is empty
  131. newNode->parent = root;
  132. root->key = key;
  133. root->firstChild = newNode;
  134. root->lastChild = newNode;
  135. root->numChildren++;
  136. #ifdef BTREE_CHECK
  137. CheckTree();
  138. #endif
  139. return newNode;
  140. }
  141. template< class objType, class keyType, int maxChildrenPerNode >
  142. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::Remove( idBTreeNode<objType,keyType> *node ) {
  143. idBTreeNode<objType,keyType> *parent;
  144. assert( node->object != NULL );
  145. // unlink the node from it's parent
  146. if ( node->prev ) {
  147. node->prev->next = node->next;
  148. } else {
  149. node->parent->firstChild = node->next;
  150. }
  151. if ( node->next ) {
  152. node->next->prev = node->prev;
  153. } else {
  154. node->parent->lastChild = node->prev;
  155. }
  156. node->parent->numChildren--;
  157. // make sure there are no parent nodes with a single child
  158. for ( parent = node->parent; parent != root && parent->numChildren <= 1; parent = parent->parent ) {
  159. if ( parent->next ) {
  160. parent = MergeNodes( parent, parent->next );
  161. } else if ( parent->prev ) {
  162. parent = MergeNodes( parent->prev, parent );
  163. }
  164. // a parent may not use a key higher than the key of it's last child
  165. if ( parent->key > parent->lastChild->key ) {
  166. parent->key = parent->lastChild->key;
  167. }
  168. if ( parent->numChildren > maxChildrenPerNode ) {
  169. SplitNode( parent );
  170. break;
  171. }
  172. }
  173. for ( ; parent != NULL && parent->lastChild != NULL; parent = parent->parent ) {
  174. // a parent may not use a key higher than the key of it's last child
  175. if ( parent->key > parent->lastChild->key ) {
  176. parent->key = parent->lastChild->key;
  177. }
  178. }
  179. // free the node
  180. FreeNode( node );
  181. // remove the root node if it has a single internal node as child
  182. if ( root->numChildren == 1 && root->firstChild->object == NULL ) {
  183. idBTreeNode<objType,keyType> *oldRoot = root;
  184. root->firstChild->parent = NULL;
  185. root = root->firstChild;
  186. FreeNode( oldRoot );
  187. }
  188. #ifdef BTREE_CHECK
  189. CheckTree();
  190. #endif
  191. }
  192. template< class objType, class keyType, int maxChildrenPerNode >
  193. ID_INLINE objType *idBTree<objType,keyType,maxChildrenPerNode>::Find( keyType key ) const {
  194. idBTreeNode<objType,keyType> *node;
  195. for ( node = root->firstChild; node != NULL; node = node->firstChild ) {
  196. while( node->next ) {
  197. if ( node->key >= key ) {
  198. break;
  199. }
  200. node = node->next;
  201. }
  202. if ( node->object ) {
  203. if ( node->key == key ) {
  204. return node->object;
  205. } else {
  206. return NULL;
  207. }
  208. }
  209. }
  210. return NULL;
  211. }
  212. template< class objType, class keyType, int maxChildrenPerNode >
  213. ID_INLINE objType *idBTree<objType,keyType,maxChildrenPerNode>::FindSmallestLargerEqual( keyType key ) const {
  214. idBTreeNode<objType,keyType> *node;
  215. for ( node = root->firstChild; node != NULL; node = node->firstChild ) {
  216. while( node->next ) {
  217. if ( node->key >= key ) {
  218. break;
  219. }
  220. node = node->next;
  221. }
  222. if ( node->object ) {
  223. if ( node->key >= key ) {
  224. return node->object;
  225. } else {
  226. return NULL;
  227. }
  228. }
  229. }
  230. return NULL;
  231. }
  232. template< class objType, class keyType, int maxChildrenPerNode >
  233. ID_INLINE objType *idBTree<objType,keyType,maxChildrenPerNode>::FindLargestSmallerEqual( keyType key ) const {
  234. idBTreeNode<objType,keyType> *node;
  235. for ( node = root->lastChild; node != NULL; node = node->lastChild ) {
  236. while( node->prev ) {
  237. if ( node->key <= key ) {
  238. break;
  239. }
  240. node = node->prev;
  241. }
  242. if ( node->object ) {
  243. if ( node->key <= key ) {
  244. return node->object;
  245. } else {
  246. return NULL;
  247. }
  248. }
  249. }
  250. return NULL;
  251. }
  252. template< class objType, class keyType, int maxChildrenPerNode >
  253. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::GetRoot( void ) const {
  254. return root;
  255. }
  256. template< class objType, class keyType, int maxChildrenPerNode >
  257. ID_INLINE int idBTree<objType,keyType,maxChildrenPerNode>::GetNodeCount( void ) const {
  258. return nodeAllocator.GetAllocCount();
  259. }
  260. template< class objType, class keyType, int maxChildrenPerNode >
  261. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::GetNext( idBTreeNode<objType,keyType> *node ) const {
  262. if ( node->firstChild ) {
  263. return node->firstChild;
  264. } else {
  265. while( node && node->next == NULL ) {
  266. node = node->parent;
  267. }
  268. return node;
  269. }
  270. }
  271. template< class objType, class keyType, int maxChildrenPerNode >
  272. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::GetNextLeaf( idBTreeNode<objType,keyType> *node ) const {
  273. if ( node->firstChild ) {
  274. while ( node->firstChild ) {
  275. node = node->firstChild;
  276. }
  277. return node;
  278. } else {
  279. while( node && node->next == NULL ) {
  280. node = node->parent;
  281. }
  282. if ( node ) {
  283. node = node->next;
  284. while ( node->firstChild ) {
  285. node = node->firstChild;
  286. }
  287. return node;
  288. } else {
  289. return NULL;
  290. }
  291. }
  292. }
  293. template< class objType, class keyType, int maxChildrenPerNode >
  294. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::AllocNode( void ) {
  295. idBTreeNode<objType,keyType> *node = nodeAllocator.Alloc();
  296. node->key = 0;
  297. node->parent = NULL;
  298. node->next = NULL;
  299. node->prev = NULL;
  300. node->numChildren = 0;
  301. node->firstChild = NULL;
  302. node->lastChild = NULL;
  303. node->object = NULL;
  304. return node;
  305. }
  306. template< class objType, class keyType, int maxChildrenPerNode >
  307. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::FreeNode( idBTreeNode<objType,keyType> *node ) {
  308. nodeAllocator.Free( node );
  309. }
  310. template< class objType, class keyType, int maxChildrenPerNode >
  311. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::SplitNode( idBTreeNode<objType,keyType> *node ) {
  312. int i;
  313. idBTreeNode<objType,keyType> *child, *newNode;
  314. // allocate a new node
  315. newNode = AllocNode();
  316. newNode->parent = node->parent;
  317. // divide the children over the two nodes
  318. child = node->firstChild;
  319. child->parent = newNode;
  320. for ( i = 3; i < node->numChildren; i += 2 ) {
  321. child = child->next;
  322. child->parent = newNode;
  323. }
  324. newNode->key = child->key;
  325. newNode->numChildren = node->numChildren / 2;
  326. newNode->firstChild = node->firstChild;
  327. newNode->lastChild = child;
  328. node->numChildren -= newNode->numChildren;
  329. node->firstChild = child->next;
  330. child->next->prev = NULL;
  331. child->next = NULL;
  332. // add the new child to the parent before the split node
  333. assert( node->parent->numChildren < maxChildrenPerNode );
  334. if ( node->prev ) {
  335. node->prev->next = newNode;
  336. } else {
  337. node->parent->firstChild = newNode;
  338. }
  339. newNode->prev = node->prev;
  340. newNode->next = node;
  341. node->prev = newNode;
  342. node->parent->numChildren++;
  343. }
  344. template< class objType, class keyType, int maxChildrenPerNode >
  345. ID_INLINE idBTreeNode<objType,keyType> *idBTree<objType,keyType,maxChildrenPerNode>::MergeNodes( idBTreeNode<objType,keyType> *node1, idBTreeNode<objType,keyType> *node2 ) {
  346. idBTreeNode<objType,keyType> *child;
  347. assert( node1->parent == node2->parent );
  348. assert( node1->next == node2 && node2->prev == node1 );
  349. assert( node1->object == NULL && node2->object == NULL );
  350. assert( node1->numChildren >= 1 && node2->numChildren >= 1 );
  351. for ( child = node1->firstChild; child->next; child = child->next ) {
  352. child->parent = node2;
  353. }
  354. child->parent = node2;
  355. child->next = node2->firstChild;
  356. node2->firstChild->prev = child;
  357. node2->firstChild = node1->firstChild;
  358. node2->numChildren += node1->numChildren;
  359. // unlink the first node from the parent
  360. if ( node1->prev ) {
  361. node1->prev->next = node2;
  362. } else {
  363. node1->parent->firstChild = node2;
  364. }
  365. node2->prev = node1->prev;
  366. node2->parent->numChildren--;
  367. FreeNode( node1 );
  368. return node2;
  369. }
  370. template< class objType, class keyType, int maxChildrenPerNode >
  371. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::CheckTree_r( idBTreeNode<objType,keyType> *node, int &numNodes ) const {
  372. int numChildren;
  373. idBTreeNode<objType,keyType> *child;
  374. numNodes++;
  375. // 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
  376. assert( ( node == root ) || ( node->object != NULL && node->numChildren == 0 ) || ( node->numChildren >= 2 && node->numChildren <= maxChildrenPerNode ) );
  377. // the key of a node may never be larger than the key of it's last child
  378. assert( ( node->lastChild == NULL ) || ( node->key <= node->lastChild->key ) );
  379. numChildren = 0;
  380. for ( child = node->firstChild; child; child = child->next ) {
  381. numChildren++;
  382. // make sure the children are properly linked
  383. if ( child->prev == NULL ) {
  384. assert( node->firstChild == child );
  385. } else {
  386. assert( child->prev->next == child );
  387. }
  388. if ( child->next == NULL ) {
  389. assert( node->lastChild == child );
  390. } else {
  391. assert( child->next->prev == child );
  392. }
  393. // recurse down the tree
  394. CheckTree_r( child, numNodes );
  395. }
  396. // the number of children should equal the number of linked children
  397. assert( numChildren == node->numChildren );
  398. }
  399. template< class objType, class keyType, int maxChildrenPerNode >
  400. ID_INLINE void idBTree<objType,keyType,maxChildrenPerNode>::CheckTree( void ) const {
  401. int numNodes = 0;
  402. idBTreeNode<objType,keyType> *node, *lastNode;
  403. CheckTree_r( root, numNodes );
  404. // the number of nodes in the tree should equal the number of allocated nodes
  405. assert( numNodes == nodeAllocator.GetAllocCount() );
  406. // all the leaf nodes should be ordered
  407. lastNode = GetNextLeaf( GetRoot() );
  408. if ( lastNode ) {
  409. for ( node = GetNextLeaf( lastNode ); node; lastNode = node, node = GetNextLeaf( node ) ) {
  410. assert( lastNode->key <= node->key );
  411. }
  412. }
  413. }
  414. #endif /* !__BTREE_H__ */