as_map.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. /*
  2. AngelCode Scripting Library
  3. Copyright (c) 2003-2013 Andreas Jonsson
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any
  6. damages arising from the use of this software.
  7. Permission is granted to anyone to use this software for any
  8. purpose, including commercial applications, and to alter it and
  9. redistribute it freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you
  11. must not claim that you wrote the original software. If you use
  12. this software in a product, an acknowledgment in the product
  13. documentation would be appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and
  15. must not be misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source
  17. distribution.
  18. The original version of this library can be located at:
  19. http://www.angelcode.com/angelscript/
  20. Andreas Jonsson
  21. andreas@angelcode.com
  22. */
  23. //
  24. // as_map.h
  25. //
  26. // This class is used for mapping a value to another
  27. //
  28. #ifndef AS_MAP_H
  29. #define AS_MAP_H
  30. template <class KEY, class VAL> struct asSMapNode;
  31. template <class KEY, class VAL> class asCMap
  32. {
  33. public:
  34. asCMap();
  35. ~asCMap();
  36. int Insert(const KEY &key, const VAL &value);
  37. int Insert(asSMapNode<KEY,VAL> *node);
  38. int GetCount() const;
  39. const KEY &GetKey(const asSMapNode<KEY,VAL> *cursor) const;
  40. const VAL &GetValue(const asSMapNode<KEY,VAL> *cursor) const;
  41. VAL &GetValue(asSMapNode<KEY,VAL> *cursor);
  42. void Erase(asSMapNode<KEY,VAL> *cursor);
  43. asSMapNode<KEY,VAL> *Remove(asSMapNode<KEY,VAL> *cursor);
  44. void EraseAll();
  45. void SwapWith(asCMap<KEY,VAL> &other);
  46. // Returns true as long as cursor is valid
  47. bool MoveTo(asSMapNode<KEY,VAL> **out, const KEY &key) const;
  48. bool MoveFirst(asSMapNode<KEY,VAL> **out) const;
  49. bool MoveLast(asSMapNode<KEY,VAL> **out) const;
  50. bool MoveNext(asSMapNode<KEY,VAL> **out, asSMapNode<KEY,VAL> *cursor) const;
  51. bool MovePrev(asSMapNode<KEY,VAL> **out, asSMapNode<KEY,VAL> *cursor) const;
  52. // For debugging only
  53. int CheckIntegrity(asSMapNode<KEY,VAL> *node) const;
  54. protected:
  55. // Don't allow value assignment
  56. asCMap &operator=(const asCMap &) { return *this; }
  57. void BalanceInsert(asSMapNode<KEY,VAL> *node);
  58. void BalanceErase(asSMapNode<KEY,VAL> *child, asSMapNode<KEY,VAL> *parent);
  59. int EraseAll(asSMapNode<KEY,VAL> *node);
  60. int RotateLeft(asSMapNode<KEY,VAL> *node);
  61. int RotateRight(asSMapNode<KEY,VAL> *node);
  62. asSMapNode<KEY,VAL> *root;
  63. asSMapNode<KEY,VAL> dummy;
  64. int count;
  65. };
  66. //---------------------------------------------------------------------------
  67. // Implementation
  68. // Properties of a Red-Black Tree
  69. //
  70. // 1. The root is always black
  71. // 2. All single paths from the root to leafs
  72. // contain the same amount of black nodes
  73. // 3. No red node can have a red node as parent
  74. #define ISRED(x) ((x != 0) && (x)->isRed)
  75. #define ISBLACK(x) (!ISRED(x))
  76. template <class KEY, class VAL> struct asSMapNode
  77. {
  78. asSMapNode() {parent = 0; left = 0; right = 0; isRed = true;}
  79. void Init(KEY k, VAL v) {key = k; value = v; parent = 0; left = 0; right = 0; isRed = true;}
  80. asSMapNode *parent;
  81. asSMapNode *left;
  82. asSMapNode *right;
  83. bool isRed;
  84. KEY key;
  85. VAL value;
  86. };
  87. template <class KEY, class VAL>
  88. asCMap<KEY, VAL>::asCMap()
  89. {
  90. root = 0;
  91. count = 0;
  92. }
  93. template <class KEY, class VAL>
  94. asCMap<KEY, VAL>::~asCMap()
  95. {
  96. EraseAll();
  97. }
  98. template <class KEY, class VAL>
  99. void asCMap<KEY,VAL>::SwapWith(asCMap<KEY,VAL> &other)
  100. {
  101. asSMapNode<KEY,VAL> *tmpRoot = root;
  102. int tmpCount = count;
  103. root = other.root;
  104. count = other.count;
  105. other.root = tmpRoot;
  106. other.count = tmpCount;
  107. }
  108. template <class KEY, class VAL>
  109. void asCMap<KEY, VAL>::EraseAll()
  110. {
  111. EraseAll(root);
  112. root = 0;
  113. }
  114. template <class KEY, class VAL>
  115. int asCMap<KEY, VAL>::EraseAll(asSMapNode<KEY, VAL> *p)
  116. {
  117. if( p == 0 ) return -1;
  118. EraseAll( p->left );
  119. EraseAll( p->right );
  120. typedef asSMapNode<KEY,VAL> node_t;
  121. asDELETE(p,node_t);
  122. count--;
  123. return 0;
  124. }
  125. template <class KEY, class VAL>
  126. int asCMap<KEY, VAL>::GetCount() const
  127. {
  128. return count;
  129. }
  130. template <class KEY, class VAL>
  131. int asCMap<KEY, VAL>::Insert(const KEY &key, const VAL &value)
  132. {
  133. typedef asSMapNode<KEY,VAL> node_t;
  134. asSMapNode<KEY,VAL> *nnode = asNEW(node_t);
  135. if( nnode == 0 )
  136. {
  137. // Out of memory
  138. return -1;
  139. }
  140. nnode->key = key;
  141. nnode->value = value;
  142. return Insert(nnode);
  143. }
  144. template <class KEY, class VAL>
  145. int asCMap<KEY, VAL>::Insert(asSMapNode<KEY,VAL> *nnode)
  146. {
  147. // Insert the node
  148. if( root == 0 )
  149. root = nnode;
  150. else
  151. {
  152. asSMapNode<KEY,VAL> *p = root;
  153. for(;;)
  154. {
  155. if( nnode->key < p->key )
  156. {
  157. if( p->left == 0 )
  158. {
  159. nnode->parent = p;
  160. p->left = nnode;
  161. break;
  162. }
  163. else
  164. p = p->left;
  165. }
  166. else
  167. {
  168. if( p->right == 0 )
  169. {
  170. nnode->parent = p;
  171. p->right = nnode;
  172. break;
  173. }
  174. else
  175. p = p->right;
  176. }
  177. }
  178. }
  179. BalanceInsert(nnode);
  180. count++;
  181. return 0;
  182. }
  183. template <class KEY, class VAL>
  184. void asCMap<KEY, VAL>::BalanceInsert(asSMapNode<KEY, VAL> *node)
  185. {
  186. // The node, that is red, can't have a red parent
  187. while( node != root && node->parent->isRed )
  188. {
  189. // Check color of uncle
  190. if( node->parent == node->parent->parent->left )
  191. {
  192. asSMapNode<KEY,VAL> *uncle = node->parent->parent->right;
  193. if( ISRED(uncle) )
  194. {
  195. // B
  196. // R R
  197. // N
  198. // Change color on parent, uncle, and grand parent
  199. node->parent->isRed = false;
  200. uncle->isRed = false;
  201. node->parent->parent->isRed = true;
  202. // Continue balancing from grand parent
  203. node = node->parent->parent;
  204. }
  205. else
  206. {
  207. // B
  208. // R B
  209. // N
  210. if( node == node->parent->right )
  211. {
  212. // Make the node a left child
  213. node = node->parent;
  214. RotateLeft(node);
  215. }
  216. // Change color on parent and grand parent
  217. // Then rotate grand parent to the right
  218. node->parent->isRed = false;
  219. node->parent->parent->isRed = true;
  220. RotateRight(node->parent->parent);
  221. }
  222. }
  223. else
  224. {
  225. asSMapNode<KEY,VAL> *uncle = node->parent->parent->left;
  226. if( ISRED(uncle) )
  227. {
  228. // B
  229. // R R
  230. // N
  231. // Change color on parent, uncle, and grand parent
  232. // Continue balancing from grand parent
  233. node->parent->isRed = false;
  234. uncle->isRed = false;
  235. node = node->parent->parent;
  236. node->isRed = true;
  237. }
  238. else
  239. {
  240. // B
  241. // B R
  242. // N
  243. if( node == node->parent->left )
  244. {
  245. // Make the node a right child
  246. node = node->parent;
  247. RotateRight(node);
  248. }
  249. // Change color on parent and grand parent
  250. // Then rotate grand parent to the right
  251. node->parent->isRed = false;
  252. node->parent->parent->isRed = true;
  253. RotateLeft(node->parent->parent);
  254. }
  255. }
  256. }
  257. root->isRed = false;
  258. }
  259. // For debugging purposes only
  260. template <class KEY, class VAL>
  261. int asCMap<KEY, VAL>::CheckIntegrity(asSMapNode<KEY, VAL> *node) const
  262. {
  263. if( node == 0 )
  264. {
  265. if( root == 0 )
  266. return 0;
  267. else if( ISRED(root) )
  268. return -1;
  269. else
  270. node = root;
  271. }
  272. int left = 0, right = 0;
  273. if( node->left )
  274. left = CheckIntegrity(node->left);
  275. if( node->right )
  276. right = CheckIntegrity(node->right);
  277. if( left != right || left == -1 )
  278. return -1;
  279. if( ISBLACK(node) )
  280. return left+1;
  281. return left;
  282. }
  283. // Returns true if successful
  284. template <class KEY, class VAL>
  285. bool asCMap<KEY, VAL>::MoveTo(asSMapNode<KEY,VAL> **out, const KEY &key) const
  286. {
  287. asSMapNode<KEY,VAL> *p = root;
  288. while( p )
  289. {
  290. if( key < p->key )
  291. p = p->left;
  292. else if( key == p->key )
  293. {
  294. if( out ) *out = p;
  295. return true;
  296. }
  297. else
  298. p = p->right;
  299. }
  300. if( out ) *out = 0;
  301. return false;
  302. }
  303. template <class KEY, class VAL>
  304. void asCMap<KEY, VAL>::Erase(asSMapNode<KEY,VAL> *cursor)
  305. {
  306. asSMapNode<KEY,VAL> *node = Remove(cursor);
  307. asASSERT( node == cursor );
  308. typedef asSMapNode<KEY,VAL> node_t;
  309. asDELETE(node,node_t);
  310. }
  311. template <class KEY, class VAL>
  312. asSMapNode<KEY,VAL> *asCMap<KEY, VAL>::Remove(asSMapNode<KEY,VAL> *cursor)
  313. {
  314. if( cursor == 0 ) return 0;
  315. asSMapNode<KEY,VAL> *node = cursor;
  316. //---------------------------------------------------
  317. // Choose the node that will replace the erased one
  318. asSMapNode<KEY,VAL> *remove;
  319. if( node->left == 0 || node->right == 0 )
  320. remove = node;
  321. else
  322. {
  323. remove = node->right;
  324. while( remove->left ) remove = remove->left;
  325. }
  326. //--------------------------------------------------
  327. // Remove the node
  328. asSMapNode<KEY,VAL> *child;
  329. if( remove->left )
  330. child = remove->left;
  331. else
  332. child = remove->right;
  333. if( child ) child->parent = remove->parent;
  334. if( remove->parent )
  335. {
  336. if( remove == remove->parent->left )
  337. remove->parent->left = child;
  338. else
  339. remove->parent->right = child;
  340. }
  341. else
  342. root = child;
  343. // If we remove a black node we must make sure the tree is balanced
  344. if( ISBLACK(remove) )
  345. BalanceErase(child, remove->parent);
  346. //----------------------------------------
  347. // Replace the erased node with the removed one
  348. if( remove != node )
  349. {
  350. if( node->parent )
  351. {
  352. if( node->parent->left == node )
  353. node->parent->left = remove;
  354. else
  355. node->parent->right = remove;
  356. }
  357. else
  358. root = remove;
  359. remove->isRed = node->isRed;
  360. remove->parent = node->parent;
  361. remove->left = node->left;
  362. if( remove->left ) remove->left->parent = remove;
  363. remove->right = node->right;
  364. if( remove->right ) remove->right->parent = remove;
  365. }
  366. count--;
  367. return node;
  368. }
  369. // Call method only if removed node was black
  370. // child is the child of the removed node
  371. template <class KEY, class VAL>
  372. void asCMap<KEY, VAL>::BalanceErase(asSMapNode<KEY, VAL> *child, asSMapNode<KEY, VAL> *parent)
  373. {
  374. // If child is red
  375. // Color child black
  376. // Terminate
  377. // These tests assume brother is to the right.
  378. // 1. Brother is red
  379. // Color parent red and brother black
  380. // Rotate parent left
  381. // Transforms to 2b
  382. // 2a. Parent and brother is black, brother's children are black
  383. // Color brother red
  384. // Continue test with parent as child
  385. // 2b. Parent is red, brother is black, brother's children are black
  386. // Color parent black and brother red
  387. // Terminate
  388. // 3. Brother is black, and brother's left is red and brother's right is black
  389. // Color brother red and brother's left black
  390. // Rotate brother to right
  391. // Transforms to 4.
  392. // 4. Brother is black, brother's right is red
  393. // Color brother's right black
  394. // Color brother to color of parent
  395. // Color parent black
  396. // Rotate parent left
  397. // Terminate
  398. while( child != root && ISBLACK(child) )
  399. {
  400. if( child == parent->left )
  401. {
  402. asSMapNode<KEY,VAL> *brother = parent->right;
  403. // Case 1
  404. if( ISRED(brother) )
  405. {
  406. brother->isRed = false;
  407. parent->isRed = true;
  408. RotateLeft(parent);
  409. brother = parent->right;
  410. }
  411. // Case 2
  412. if( brother == 0 ) break;
  413. if( ISBLACK(brother->left) && ISBLACK(brother->right) )
  414. {
  415. // Case 2b
  416. if( ISRED(parent) )
  417. {
  418. parent->isRed = false;
  419. brother->isRed = true;
  420. break;
  421. }
  422. brother->isRed = true;
  423. child = parent;
  424. parent = child->parent;
  425. }
  426. else
  427. {
  428. // Case 3
  429. if( ISBLACK(brother->right) )
  430. {
  431. brother->left->isRed = false;
  432. brother->isRed = true;
  433. RotateRight(brother);
  434. brother = parent->right;
  435. }
  436. // Case 4
  437. brother->isRed = parent->isRed;
  438. parent->isRed = false;
  439. brother->right->isRed = false;
  440. RotateLeft(parent);
  441. break;
  442. }
  443. }
  444. else
  445. {
  446. asSMapNode<KEY,VAL> *brother = parent->left;
  447. // Case 1
  448. if( ISRED(brother) )
  449. {
  450. brother->isRed = false;
  451. parent->isRed = true;
  452. RotateRight(parent);
  453. brother = parent->left;
  454. }
  455. // Case 2
  456. if( brother == 0 ) break;
  457. if( ISBLACK(brother->left) && ISBLACK(brother->right) )
  458. {
  459. // Case 2b
  460. if( ISRED(parent) )
  461. {
  462. parent->isRed = false;
  463. brother->isRed = true;
  464. break;
  465. }
  466. brother->isRed = true;
  467. child = parent;
  468. parent = child->parent;
  469. }
  470. else
  471. {
  472. // Case 3
  473. if( ISBLACK(brother->left) )
  474. {
  475. brother->right->isRed = false;
  476. brother->isRed = true;
  477. RotateLeft(brother);
  478. brother = parent->left;
  479. }
  480. // Case 4
  481. brother->isRed = parent->isRed;
  482. parent->isRed = false;
  483. brother->left->isRed = false;
  484. RotateRight(parent);
  485. break;
  486. }
  487. }
  488. }
  489. if( child )
  490. child->isRed = false;
  491. }
  492. template <class KEY, class VAL>
  493. int asCMap<KEY, VAL>::RotateRight(asSMapNode<KEY, VAL> *node)
  494. {
  495. // P L //
  496. // / \ / \ //
  497. // L R => Ll P //
  498. // / \ / \ //
  499. // Ll Lr Lr R //
  500. if( node->left == 0 ) return -1;
  501. asSMapNode<KEY,VAL> *left = node->left;
  502. // Update parent
  503. if( node->parent )
  504. {
  505. asSMapNode<KEY,VAL> *parent = node->parent;
  506. if( parent->left == node )
  507. parent->left = left;
  508. else
  509. parent->right = left;
  510. left->parent = parent;
  511. }
  512. else
  513. {
  514. root = left;
  515. left->parent = 0;
  516. }
  517. // Move left's right child to node's left child
  518. node->left = left->right;
  519. if( node->left ) node->left->parent = node;
  520. // Put node as left's right child
  521. left->right = node;
  522. node->parent = left;
  523. return 0;
  524. }
  525. template <class KEY, class VAL>
  526. int asCMap<KEY, VAL>::RotateLeft(asSMapNode<KEY, VAL> *node)
  527. {
  528. // P R //
  529. // / \ / \ //
  530. // L R => P Rr //
  531. // / \ / \ //
  532. // Rl Rr L Rl //
  533. if( node->right == 0 ) return -1;
  534. asSMapNode<KEY,VAL> *right = node->right;
  535. // Update parent
  536. if( node->parent )
  537. {
  538. asSMapNode<KEY,VAL> *parent = node->parent;
  539. if( parent->right == node )
  540. parent->right = right;
  541. else
  542. parent->left = right;
  543. right->parent = parent;
  544. }
  545. else
  546. {
  547. root = right;
  548. right->parent = 0;
  549. }
  550. // Move right's left child to node's right child
  551. node->right = right->left;
  552. if( node->right ) node->right->parent = node;
  553. // Put node as right's left child
  554. right->left = node;
  555. node->parent = right;
  556. return 0;
  557. }
  558. template <class KEY, class VAL>
  559. const VAL &asCMap<KEY, VAL>::GetValue(const asSMapNode<KEY,VAL> *cursor) const
  560. {
  561. if( cursor == 0 )
  562. return dummy.value;
  563. return cursor->value;
  564. }
  565. template <class KEY, class VAL>
  566. VAL &asCMap<KEY, VAL>::GetValue(asSMapNode<KEY,VAL> *cursor)
  567. {
  568. if( cursor == 0 )
  569. return dummy.value;
  570. return cursor->value;
  571. }
  572. template <class KEY, class VAL>
  573. const KEY &asCMap<KEY, VAL>::GetKey(const asSMapNode<KEY,VAL> *cursor) const
  574. {
  575. if( cursor == 0 )
  576. return dummy.key;
  577. return cursor->key;
  578. }
  579. template <class KEY, class VAL>
  580. bool asCMap<KEY, VAL>::MoveFirst(asSMapNode<KEY,VAL> **out) const
  581. {
  582. *out = root;
  583. if( root == 0 ) return false;
  584. while( (*out)->left )
  585. *out = (*out)->left;
  586. return true;
  587. }
  588. template <class KEY, class VAL>
  589. bool asCMap<KEY, VAL>::MoveLast(asSMapNode<KEY,VAL> **out) const
  590. {
  591. *out = root;
  592. if( root == 0 ) return false;
  593. while( (*out)->right )
  594. *out = (*out)->right;
  595. return true;
  596. }
  597. template <class KEY, class VAL>
  598. bool asCMap<KEY, VAL>::MoveNext(asSMapNode<KEY,VAL> **out, asSMapNode<KEY,VAL> *cursor) const
  599. {
  600. if( cursor == 0 )
  601. {
  602. *out = 0;
  603. return false;
  604. }
  605. if( cursor->right == 0 )
  606. {
  607. // Move upwards until we find a parent node to the right
  608. while( cursor->parent && cursor->parent->right == cursor )
  609. cursor = cursor->parent;
  610. cursor = cursor->parent;
  611. *out = cursor;
  612. if( cursor == 0 )
  613. return false;
  614. return true;
  615. }
  616. cursor = cursor->right;
  617. while( cursor->left )
  618. cursor = cursor->left;
  619. *out = cursor;
  620. return true;
  621. }
  622. template <class KEY, class VAL>
  623. bool asCMap<KEY, VAL>::MovePrev(asSMapNode<KEY,VAL> **out, asSMapNode<KEY,VAL> *cursor) const
  624. {
  625. if( cursor == 0 )
  626. {
  627. *out = 0;
  628. return false;
  629. }
  630. if( cursor->left == 0 )
  631. {
  632. // Move upwards until we find a parent node to the left
  633. while( cursor->parent && cursor->parent->left == cursor )
  634. cursor = cursor->parent;
  635. cursor = cursor->parent;
  636. *out = cursor;
  637. if( cursor == 0 )
  638. return false;
  639. return true;
  640. }
  641. cursor = cursor->left;
  642. while( cursor->right )
  643. cursor = cursor->right;
  644. *out = cursor;
  645. return true;
  646. }
  647. #endif