/sparrowhawk/foundation/ESFMap.cpp

http://github.com/jtblatt/duderino · C++ · 826 lines · 530 code · 197 blank · 99 comment · 162 complexity · c67e85e7d1f0926a3c09b843b394c06c MD5 · raw file

  1. /** @file ESFMap.cpp
  2. * @brief A balanced binary tree
  3. *
  4. * Copyright (c) 2009 Yahoo! Inc.
  5. * The copyrights embodied in the content of this file are licensed by Yahoo! Inc.
  6. * under the BSD (revised) open source license.
  7. *
  8. * Derived from code that is Copyright (c) 2009 Joshua Blatt and offered under both
  9. * BSD and Apache 2.0 licenses (http://sourceforge.net/projects/sparrowhawk/).
  10. *
  11. * $Author: blattj $
  12. * $Date: 2009/05/25 21:51:08 $
  13. * $Name: $
  14. * $Revision: 1.3 $
  15. */
  16. #ifndef ESF_MAP_H
  17. #include <ESFMap.h>
  18. #endif
  19. #ifndef ESF_ASSERT_H
  20. #include <ESFAssert.h>
  21. #endif
  22. #ifdef DEBUG
  23. #include <math.h>
  24. #endif
  25. ESFMapNode::ESFMapNode(ESFMapNode *parent, ESFMapNode *left, ESFMapNode *right,
  26. bool isBlack, const void *key, void *value) :
  27. _parent(parent), _left(left), _right(right), _isBlack(isBlack), _key(key),
  28. _value(value) {
  29. }
  30. ESFMapNode::~ESFMapNode() {
  31. }
  32. void *
  33. ESFMapNode::operator new(size_t size, ESFAllocator *allocator) {
  34. return allocator->allocate(size);
  35. }
  36. ESFMap::ESFMap(bool isUnique, ESFComparator *comparator,
  37. ESFAllocator *allocator, ESFLockable *lockable) :
  38. _size(0), _isUnique(isUnique), _root(&_sentinel), _allocator(allocator),
  39. _lockable(lockable), _comparator(comparator),
  40. _sentinel(&_sentinel, &_sentinel, &_sentinel, true, 0, 0)
  41. {
  42. }
  43. ESFMap::~ESFMap() {
  44. }
  45. ESFError ESFMap::insert(const void *key, void *value) {
  46. if (!key) {
  47. return ESF_NULL_POINTER;
  48. }
  49. if (!_comparator || !_allocator || !_lockable) {
  50. return ESF_INVALID_STATE;
  51. }
  52. if (ESF_UINT32_MAX == _size) {
  53. return ESF_OVERFLOW;
  54. }
  55. ESFMapNode *node = new (_allocator) ESFMapNode(&_sentinel, &_sentinel,
  56. &_sentinel, true, key, value);
  57. if (!node) {
  58. return ESF_OUT_OF_MEMORY;
  59. }
  60. if (false == insertNode(node)) {
  61. node->~ESFMapNode();
  62. _allocator->deallocate((void *) node);
  63. return ESF_UNIQUENESS_VIOLATION;
  64. }
  65. return ESF_SUCCESS;
  66. }
  67. ESFError ESFMap::erase(const void *key) {
  68. if (!key) {
  69. return ESF_NULL_POINTER;
  70. }
  71. if (!_comparator || !_allocator || !_lockable) {
  72. return ESF_INVALID_STATE;
  73. }
  74. ESFMapNode *node = findNode(_root, key);
  75. if (!node->_key) {
  76. return ESF_CANNOT_FIND;
  77. }
  78. deleteNode(node);
  79. return ESF_SUCCESS;
  80. }
  81. void *ESFMap::find(const void *key) {
  82. if (!key) {
  83. return 0;
  84. }
  85. if (!_comparator || !_allocator || !_lockable) {
  86. return 0;
  87. }
  88. ESFMapNode *node = findNode(_root, key);
  89. if (!node->_key) {
  90. return 0;
  91. }
  92. return node->_value;
  93. }
  94. ESFError ESFMap::update(const void *key, void *value, void **old) {
  95. if (!key) {
  96. return ESF_NULL_POINTER;
  97. }
  98. if (!_comparator || !_allocator || !_lockable) {
  99. return ESF_INVALID_STATE;
  100. }
  101. ESFMapNode *node = findNode(_root, key);
  102. if (!node->_key) {
  103. return ESF_CANNOT_FIND;
  104. }
  105. if (old) {
  106. *old = node->_value;
  107. }
  108. node->_value = value;
  109. return ESF_SUCCESS;
  110. }
  111. ESFError ESFMap::clear() {
  112. ESFMapNode *x = _root;
  113. while (x->_key) {
  114. if (x->_right->_key) {
  115. x = x->_right;
  116. continue;
  117. }
  118. if (x->_left->_key) {
  119. x = x->_left;
  120. continue;
  121. }
  122. if (!x->_parent->_key) {
  123. ESF_ASSERT(_root == x);
  124. x->~ESFMapNode();
  125. _allocator->deallocate((void *) x);
  126. _root = &_sentinel;
  127. _size = 0;
  128. return ESF_SUCCESS;
  129. }
  130. if (x == x->_parent->_right) {
  131. x = x->_parent;
  132. x->_right->~ESFMapNode();
  133. _allocator->deallocate((void *) x->_right);
  134. x->_right = &_sentinel;
  135. continue;
  136. }
  137. ESF_ASSERT(x == x->_parent->_left);
  138. x = x->_parent;
  139. x->_left->~ESFMapNode();
  140. _allocator->deallocate((void *) x->_left);
  141. x->_left = &_sentinel;
  142. }
  143. return ESF_SUCCESS;
  144. }
  145. ESFMapIterator ESFMap::getMinimumIterator() {
  146. ESFMapIterator iterator(findMinimum(_root));
  147. return iterator;
  148. }
  149. ESFMapIterator ESFMap::getMaximumIterator() {
  150. ESFMapIterator iterator(findMaximum(_root));
  151. return iterator;
  152. }
  153. ESFError ESFMap::insert(const void *key, void *value, ESFMapIterator *iterator) {
  154. if (!key || !value || !iterator) {
  155. return ESF_NULL_POINTER;
  156. }
  157. if (!_comparator || !_allocator || !_lockable) {
  158. return ESF_INVALID_STATE;
  159. }
  160. ESFMapNode *node = new (_allocator) ESFMapNode(&_sentinel, &_sentinel,
  161. &_sentinel, true, key, value);
  162. if (!node) {
  163. return ESF_OUT_OF_MEMORY;
  164. }
  165. if (false == insertNode(node)) {
  166. node->~ESFMapNode();
  167. _allocator->deallocate((void *) node);
  168. return ESF_UNIQUENESS_VIOLATION;
  169. }
  170. iterator->_node = node;
  171. return ESF_SUCCESS;
  172. }
  173. ESFMapIterator ESFMap::findIterator(const void *key) {
  174. ESFMapIterator iterator;
  175. if (!key) {
  176. return iterator;
  177. }
  178. if (!_comparator || !_allocator || !_lockable) {
  179. return iterator;
  180. }
  181. ESFMapNode *node = findNode(_root, key);
  182. if (!node) {
  183. return iterator;
  184. }
  185. iterator._node = node;
  186. return iterator;
  187. }
  188. ESFError ESFMap::erase(ESFMapIterator *iterator) {
  189. if (!iterator) {
  190. return ESF_NULL_POINTER;
  191. }
  192. if (iterator->isNull()) {
  193. return ESF_INVALID_ITERATOR;
  194. }
  195. deleteNode(iterator->_node);
  196. iterator->_node = 0;
  197. return ESF_SUCCESS;
  198. }
  199. ESFError ESFMap::writeAcquire() {
  200. if (!_lockable)
  201. return ESF_INVALID_STATE;
  202. return _lockable->writeAcquire();
  203. }
  204. ESFError ESFMap::readAcquire() {
  205. if (!_lockable)
  206. return ESF_INVALID_STATE;
  207. return _lockable->readAcquire();
  208. }
  209. ESFError ESFMap::writeAttempt() {
  210. if (!_lockable)
  211. return ESF_INVALID_STATE;
  212. return _lockable->writeAttempt();
  213. }
  214. ESFError ESFMap::readAttempt() {
  215. if (!_lockable)
  216. return ESF_INVALID_STATE;
  217. return _lockable->readAttempt();
  218. }
  219. ESFError ESFMap::writeRelease() {
  220. if (!_lockable)
  221. return ESF_INVALID_STATE;
  222. return _lockable->writeRelease();
  223. }
  224. ESFError ESFMap::readRelease() {
  225. if (!_lockable)
  226. return ESF_INVALID_STATE;
  227. return _lockable->readRelease();
  228. }
  229. ESFMapNode *
  230. ESFMap::findNode(ESFMapNode *x, const void *k) {
  231. //
  232. // See Iterative-Tree-Search in "Introduction to Algorithms", Cormen,
  233. // Leiserson, Rivest, p.248.
  234. //
  235. int result = 0;
  236. while (x->_key) {
  237. result = _comparator->compare(k, x->_key);
  238. if (0 == result) {
  239. if (_isUnique) {
  240. return x;
  241. }
  242. //
  243. // This is a departure from Cormen et. al.'s algorithm. If the
  244. // map allows multiple elements with the same key, we could have
  245. // inserted them to the right of the current node. We always
  246. // return the node that is the "smallest" one in the tree so that
  247. // any iteration from this point would yield a different key
  248. // if it did a getPrevious() and could yield a node with the
  249. // same key if it did a getNext().
  250. //
  251. ESFMapNode *y = 0;
  252. while (true) {
  253. y = findSuccessor(x);
  254. if (!y->_key)
  255. break;
  256. if (0 != _comparator->compare(y->_key, x->_key))
  257. break;
  258. x = y;
  259. }
  260. return x;
  261. } else if (0 < result) {
  262. x = x->_right;
  263. } else {
  264. x = x->_left;
  265. }
  266. }
  267. return &_sentinel;
  268. }
  269. ESFMapNode *
  270. ESFMap::findMinimum(ESFMapNode *x) {
  271. //
  272. // See Tree-Minimum in "Introduction to Algorithms", Cormen, Leiserson,
  273. // Rivest, p. 248.
  274. //
  275. while (x->_left->_key) {
  276. x = x->_left;
  277. }
  278. return x;
  279. }
  280. ESFMapNode *
  281. ESFMap::findMaximum(ESFMapNode *x) {
  282. //
  283. // See Tree-Maximum in "Introduction to Algorithms", Cormen, Leiserson,
  284. // Rivest, p. 248.
  285. //
  286. while (x->_right->_key) {
  287. x = x->_right;
  288. }
  289. return x;
  290. }
  291. ESFMapNode *
  292. ESFMap::findSuccessor(ESFMapNode *x) {
  293. //
  294. // See Tree-Successor in "Introduction to Algorithms", Cormen, Leiserson,
  295. // Rivest, p. 249.
  296. //
  297. if (x->_right->_key) {
  298. return findMinimum(x->_right);
  299. }
  300. ESFMapNode *y = x->_parent;
  301. while (y->_key && x == y->_right) {
  302. x = y;
  303. y = y->_parent;
  304. }
  305. return y;
  306. }
  307. ESFMapNode *
  308. ESFMap::findPredecessor(ESFMapNode *x) {
  309. //
  310. // See Tree-Successor in "Introduction to Algorithms", Cormen, Leiserson,
  311. // Rivest, p. 249.
  312. //
  313. // Tree-Predecessor is symmetric to Tree-Successor.
  314. //
  315. if (x->_left->_key) {
  316. return findMaximum(x->_left);
  317. }
  318. ESFMapNode *y = x->_parent;
  319. while (y->_key && x == y->_left) {
  320. x = y;
  321. y = y->_parent;
  322. }
  323. return y;
  324. }
  325. bool ESFMap::insertNode(ESFMapNode *z) {
  326. //
  327. // See Tree-Insert in "Introduction to Algorithms", Cormen, Leiserson,
  328. // Rivest, p. 251.
  329. //
  330. int result = 0;
  331. ESFMapNode *y = &_sentinel;
  332. ESFMapNode *x = _root;
  333. while (x->_key) {
  334. y = x;
  335. result = _comparator->compare(z->_key, x->_key);
  336. if (0 > result) {
  337. x = x->_left;
  338. } else if (0 < result) {
  339. x = x->_right;
  340. } else if (_isUnique) {
  341. return false;
  342. } else {
  343. break;
  344. }
  345. }
  346. z->_parent = y;
  347. z->_left = &_sentinel;
  348. z->_right = &_sentinel;
  349. if (&_sentinel == y) {
  350. _root = z;
  351. } else if (0 > result) {
  352. y->_left = z;
  353. } else {
  354. y->_right = z;
  355. }
  356. ++_size;
  357. //
  358. // See RB-Insert in "Introduction to Algorithms", Cormen, Leiserson,
  359. // Rivest, p. 268.
  360. //
  361. x = z;
  362. x->_isBlack = false;
  363. while (x != _root && false == x->_parent->_isBlack) {
  364. if (x->_parent == x->_parent->_parent->_left) {
  365. y = x->_parent->_parent->_right;
  366. if (false == y->_isBlack) {
  367. x->_parent->_isBlack = true;
  368. y->_isBlack = true;
  369. x->_parent->_parent->_isBlack = false;
  370. x = x->_parent->_parent;
  371. } else if (x == x->_parent->_right) {
  372. x = x->_parent;
  373. leftRotate(x);
  374. } else {
  375. x->_parent->_isBlack = true;
  376. x->_parent->_parent->_isBlack = false;
  377. rightRotate(x->_parent->_parent);
  378. }
  379. } else {
  380. y = x->_parent->_parent->_left;
  381. if (false == y->_isBlack) {
  382. x->_parent->_isBlack = true;
  383. y->_isBlack = true;
  384. x->_parent->_parent->_isBlack = false;
  385. x = x->_parent->_parent;
  386. } else if (x == x->_parent->_left) {
  387. x = x->_parent;
  388. rightRotate(x);
  389. } else {
  390. x->_parent->_isBlack = true;
  391. x->_parent->_parent->_isBlack = false;
  392. leftRotate(x->_parent->_parent);
  393. }
  394. }
  395. }
  396. _root->_isBlack = true;
  397. return true;
  398. }
  399. void ESFMap::deleteNode(ESFMapNode *z) {
  400. //
  401. // See RB-Delete in "Introduction to Algorithms", Cormen, Leiserson,
  402. // Rivest, p. 273.
  403. //
  404. ESFMapNode *y = 0;
  405. ESFMapNode *x = 0;
  406. if (!z->_left->_key || !z->_right->_key) {
  407. y = z;
  408. } else {
  409. y = findSuccessor(z);
  410. }
  411. if (y->_left->_key) {
  412. x = y->_left;
  413. } else {
  414. x = y->_right;
  415. }
  416. x->_parent = y->_parent;
  417. if (!y->_parent->_key) {
  418. _root = x;
  419. } else if (y == y->_parent->_left) {
  420. y->_parent->_left = x;
  421. } else {
  422. y->_parent->_right = x;
  423. }
  424. bool isBlack = y->_isBlack;
  425. if (y != z) {
  426. //
  427. // Cormen et. al. simplify this step by copying all fields from
  428. // y into z, but since this would violate our iterator invalidation
  429. // rules, we really have to replace node z with node y.
  430. //
  431. // Replace all of y's links with z's
  432. y->_parent = z->_parent;
  433. y->_left = z->_left;
  434. y->_right = z->_right;
  435. y->_isBlack = z->_isBlack;
  436. // Change the all the links that point to z to instead point to y.
  437. y->_right->_parent = y;
  438. y->_left->_parent = y;
  439. if (z == y->_parent->_right) {
  440. y->_parent->_right = y;
  441. } else {
  442. y->_parent->_left = y;
  443. }
  444. // If z was the root, y is now the root.
  445. if (_root == z) {
  446. _root = y;
  447. }
  448. }
  449. z->~ESFMapNode();
  450. _allocator->deallocate((void *) z);
  451. z = 0;
  452. --_size;
  453. if (!isBlack)
  454. return;
  455. //
  456. // See RB-Delete-Fixup in "Introduction to Algorithms", Cormen, Leiserson,
  457. // Rivest, p. 274.
  458. //
  459. ESFMapNode *w = 0;
  460. while (_root != x && x->_isBlack) {
  461. if (x == x->_parent->_left) {
  462. w = x->_parent->_right;
  463. if (!w->_isBlack) {
  464. w->_isBlack = true;
  465. x->_parent->_isBlack = false;
  466. leftRotate(x->_parent);
  467. w = x->_parent->_right;
  468. }
  469. if (w->_left->_isBlack && w->_right->_isBlack) {
  470. w->_isBlack = false;
  471. x = x->_parent;
  472. } else if (w->_right->_isBlack) {
  473. w->_left->_isBlack = true;
  474. w->_isBlack = false;
  475. rightRotate(w);
  476. w = x->_parent->_right;
  477. } else {
  478. w->_isBlack = x->_parent->_isBlack;
  479. x->_parent->_isBlack = true;
  480. w->_right->_isBlack = true;
  481. leftRotate(x->_parent);
  482. x = _root;
  483. }
  484. } else {
  485. w = x->_parent->_left;
  486. if (!w->_isBlack) {
  487. w->_isBlack = true;
  488. x->_parent->_isBlack = false;
  489. rightRotate(x->_parent);
  490. w = x->_parent->_left;
  491. }
  492. if (w->_right->_isBlack && w->_left->_isBlack) {
  493. w->_isBlack = false;
  494. x = x->_parent;
  495. } else if (w->_left->_isBlack) {
  496. w->_right->_isBlack = true;
  497. w->_isBlack = false;
  498. leftRotate(w);
  499. w = x->_parent->_left;
  500. } else {
  501. w->_isBlack = x->_parent->_isBlack;
  502. x->_parent->_isBlack = true;
  503. w->_left->_isBlack = true;
  504. rightRotate(x->_parent);
  505. x = _root;
  506. }
  507. }
  508. }
  509. x->_isBlack = true;
  510. }
  511. void ESFMap::rightRotate(ESFMapNode *x) {
  512. //
  513. // See Left-Rotate in "Introduction to Algorithms", Cormen, Leiserson,
  514. // Rivest, p. 266.
  515. //
  516. // Right-Rotate is symmetric to Left-Rotate.
  517. //
  518. ESFMapNode *y = x->_left;
  519. x->_left = y->_right;
  520. if (y->_right->_key) {
  521. y->_right->_parent = x;
  522. }
  523. y->_parent = x->_parent;
  524. if (!x->_parent->_key) {
  525. _root = y;
  526. } else if (x == x->_parent->_right) {
  527. x->_parent->_right = y;
  528. } else {
  529. x->_parent->_left = y;
  530. }
  531. y->_right = x;
  532. x->_parent = y;
  533. }
  534. void ESFMap::leftRotate(ESFMapNode *x) {
  535. //
  536. // See Left-Rotate in "Introduction to Algorithms", Cormen, Leiserson,
  537. // Rivest, p. 266.
  538. //
  539. ESFMapNode *y = x->_right;
  540. x->_right = y->_left;
  541. if (y->_left->_key) {
  542. y->_left->_parent = x;
  543. }
  544. y->_parent = x->_parent;
  545. if (!x->_parent->_key) {
  546. _root = y;
  547. } else if (x == x->_parent->_left) {
  548. x->_parent->_left = y;
  549. } else {
  550. x->_parent->_right = y;
  551. }
  552. y->_left = x;
  553. x->_parent = y;
  554. }
  555. ESFUInt32 ESFMap::getSize() const {
  556. return _size;
  557. }
  558. bool ESFMap::isEmpty() const {
  559. return 0 == _size;
  560. }
  561. #ifdef DEBUG
  562. bool ESFMap::isBalanced() const {
  563. int height = 0;
  564. int blackHeight = 0;
  565. bool unbalanced = false;
  566. height = getHeight(_root);
  567. //
  568. // See Lemma 14.1 in "Introduction to Algorithms", Cormen, Leiserson,
  569. // Rivest, p. 264.
  570. //
  571. // "A red-black tree with n internal nodes has a height at most 2lg(n+1).
  572. //
  573. if (height > 2 * (log10(_size + 1) / log10(2))) {
  574. return false;
  575. }
  576. //
  577. // See red-black properties in "Introduction to Algorithms", Cormen,
  578. // Leiserson, Rivest, p. 263.
  579. //
  580. // "Every simple path from a node to a descendant leaf contains the
  581. // same number of black nodes."
  582. //
  583. blackHeight = getBlackHeight(_root, &unbalanced);
  584. return !unbalanced;
  585. }
  586. int ESFMap::getBlackHeight(ESFMapNode *node, bool *unbalanced) const {
  587. //
  588. // Base case.
  589. //
  590. if (!node->_key) {
  591. ESF_ASSERT( node->_isBlack );
  592. return 0;
  593. }
  594. int right = getBlackHeight(node->_right, unbalanced);
  595. int left = getBlackHeight(node->_left, unbalanced);
  596. if (right != left) {
  597. *unbalanced = true;
  598. }
  599. if (node->_isBlack) {
  600. return (right > left) ? right + 1 : left + 1;
  601. }
  602. return (right > left) ? right : left;
  603. }
  604. int ESFMap::getHeight(ESFMapNode *node) const {
  605. //
  606. // Base case.
  607. //
  608. if (!node->_key) {
  609. return 0;
  610. }
  611. int right = getHeight(node->_right);
  612. int left = getHeight(node->_left);
  613. return (right > left) ? right + 1 : left + 1;
  614. }
  615. #endif /* defined DEBUG */
  616. ESFSize ESFMap::GetAllocationSize() {
  617. return sizeof(ESFMapNode);
  618. }
  619. ESFMapIterator::ESFMapIterator() :
  620. _node(0) {
  621. }
  622. ESFMapIterator::ESFMapIterator(ESFMapNode *node) :
  623. _node(node) {
  624. }
  625. ESFMapIterator::ESFMapIterator(const ESFMapIterator &iterator) :
  626. _node(iterator._node) {
  627. }
  628. ESFMapIterator::~ESFMapIterator() {
  629. }