/sparrowhawk/foundation/ESFMap.cpp
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 17#ifndef ESF_MAP_H 18#include <ESFMap.h> 19#endif 20 21#ifndef ESF_ASSERT_H 22#include <ESFAssert.h> 23#endif 24 25#ifdef DEBUG 26#include <math.h> 27#endif 28 29ESFMapNode::ESFMapNode(ESFMapNode *parent, ESFMapNode *left, ESFMapNode *right, 30 bool isBlack, const void *key, void *value) : 31 _parent(parent), _left(left), _right(right), _isBlack(isBlack), _key(key), 32 _value(value) { 33} 34 35ESFMapNode::~ESFMapNode() { 36} 37 38void * 39ESFMapNode::operator new(size_t size, ESFAllocator *allocator) { 40 return allocator->allocate(size); 41} 42 43ESFMap::ESFMap(bool isUnique, ESFComparator *comparator, 44 ESFAllocator *allocator, ESFLockable *lockable) : 45 _size(0), _isUnique(isUnique), _root(&_sentinel), _allocator(allocator), 46 _lockable(lockable), _comparator(comparator), 47 _sentinel(&_sentinel, &_sentinel, &_sentinel, true, 0, 0) 48 49{ 50} 51 52ESFMap::~ESFMap() { 53} 54 55ESFError ESFMap::insert(const void *key, void *value) { 56 if (!key) { 57 return ESF_NULL_POINTER; 58 } 59 60 if (!_comparator || !_allocator || !_lockable) { 61 return ESF_INVALID_STATE; 62 } 63 64 if (ESF_UINT32_MAX == _size) { 65 return ESF_OVERFLOW; 66 } 67 68 ESFMapNode *node = new (_allocator) ESFMapNode(&_sentinel, &_sentinel, 69 &_sentinel, true, key, value); 70 71 if (!node) { 72 return ESF_OUT_OF_MEMORY; 73 } 74 75 if (false == insertNode(node)) { 76 node->~ESFMapNode(); 77 _allocator->deallocate((void *) node); 78 79 return ESF_UNIQUENESS_VIOLATION; 80 } 81 82 return ESF_SUCCESS; 83} 84 85ESFError ESFMap::erase(const void *key) { 86 if (!key) { 87 return ESF_NULL_POINTER; 88 } 89 90 if (!_comparator || !_allocator || !_lockable) { 91 return ESF_INVALID_STATE; 92 } 93 94 ESFMapNode *node = findNode(_root, key); 95 96 if (!node->_key) { 97 return ESF_CANNOT_FIND; 98 } 99 100 deleteNode(node); 101 102 return ESF_SUCCESS; 103} 104 105void *ESFMap::find(const void *key) { 106 if (!key) { 107 return 0; 108 } 109 110 if (!_comparator || !_allocator || !_lockable) { 111 return 0; 112 } 113 114 ESFMapNode *node = findNode(_root, key); 115 116 if (!node->_key) { 117 return 0; 118 } 119 120 return node->_value; 121} 122 123ESFError ESFMap::update(const void *key, void *value, void **old) { 124 if (!key) { 125 return ESF_NULL_POINTER; 126 } 127 128 if (!_comparator || !_allocator || !_lockable) { 129 return ESF_INVALID_STATE; 130 } 131 132 ESFMapNode *node = findNode(_root, key); 133 134 if (!node->_key) { 135 return ESF_CANNOT_FIND; 136 } 137 138 if (old) { 139 *old = node->_value; 140 } 141 142 node->_value = value; 143 144 return ESF_SUCCESS; 145} 146 147ESFError ESFMap::clear() { 148 ESFMapNode *x = _root; 149 150 while (x->_key) { 151 if (x->_right->_key) { 152 x = x->_right; 153 154 continue; 155 } 156 157 if (x->_left->_key) { 158 x = x->_left; 159 160 continue; 161 } 162 163 if (!x->_parent->_key) { 164 ESF_ASSERT(_root == x); 165 166 x->~ESFMapNode(); 167 _allocator->deallocate((void *) x); 168 169 _root = &_sentinel; 170 171 _size = 0; 172 173 return ESF_SUCCESS; 174 } 175 176 if (x == x->_parent->_right) { 177 x = x->_parent; 178 179 x->_right->~ESFMapNode(); 180 _allocator->deallocate((void *) x->_right); 181 182 x->_right = &_sentinel; 183 184 continue; 185 } 186 187 ESF_ASSERT(x == x->_parent->_left); 188 189 x = x->_parent; 190 191 x->_left->~ESFMapNode(); 192 _allocator->deallocate((void *) x->_left); 193 194 x->_left = &_sentinel; 195 } 196 197 return ESF_SUCCESS; 198} 199 200ESFMapIterator ESFMap::getMinimumIterator() { 201 ESFMapIterator iterator(findMinimum(_root)); 202 203 return iterator; 204} 205 206ESFMapIterator ESFMap::getMaximumIterator() { 207 ESFMapIterator iterator(findMaximum(_root)); 208 209 return iterator; 210} 211 212ESFError ESFMap::insert(const void *key, void *value, ESFMapIterator *iterator) { 213 if (!key || !value || !iterator) { 214 return ESF_NULL_POINTER; 215 } 216 217 if (!_comparator || !_allocator || !_lockable) { 218 return ESF_INVALID_STATE; 219 } 220 221 ESFMapNode *node = new (_allocator) ESFMapNode(&_sentinel, &_sentinel, 222 &_sentinel, true, key, value); 223 224 if (!node) { 225 return ESF_OUT_OF_MEMORY; 226 } 227 228 if (false == insertNode(node)) { 229 node->~ESFMapNode(); 230 _allocator->deallocate((void *) node); 231 232 return ESF_UNIQUENESS_VIOLATION; 233 } 234 235 iterator->_node = node; 236 237 return ESF_SUCCESS; 238} 239 240ESFMapIterator ESFMap::findIterator(const void *key) { 241 ESFMapIterator iterator; 242 243 if (!key) { 244 return iterator; 245 } 246 247 if (!_comparator || !_allocator || !_lockable) { 248 return iterator; 249 } 250 251 ESFMapNode *node = findNode(_root, key); 252 253 if (!node) { 254 return iterator; 255 } 256 257 iterator._node = node; 258 259 return iterator; 260} 261 262ESFError ESFMap::erase(ESFMapIterator *iterator) { 263 if (!iterator) { 264 return ESF_NULL_POINTER; 265 } 266 267 if (iterator->isNull()) { 268 return ESF_INVALID_ITERATOR; 269 } 270 271 deleteNode(iterator->_node); 272 273 iterator->_node = 0; 274 275 return ESF_SUCCESS; 276} 277 278ESFError ESFMap::writeAcquire() { 279 if (!_lockable) 280 return ESF_INVALID_STATE; 281 282 return _lockable->writeAcquire(); 283} 284 285ESFError ESFMap::readAcquire() { 286 if (!_lockable) 287 return ESF_INVALID_STATE; 288 289 return _lockable->readAcquire(); 290} 291 292ESFError ESFMap::writeAttempt() { 293 if (!_lockable) 294 return ESF_INVALID_STATE; 295 296 return _lockable->writeAttempt(); 297} 298 299ESFError ESFMap::readAttempt() { 300 if (!_lockable) 301 return ESF_INVALID_STATE; 302 303 return _lockable->readAttempt(); 304} 305 306ESFError ESFMap::writeRelease() { 307 if (!_lockable) 308 return ESF_INVALID_STATE; 309 310 return _lockable->writeRelease(); 311} 312 313ESFError ESFMap::readRelease() { 314 if (!_lockable) 315 return ESF_INVALID_STATE; 316 317 return _lockable->readRelease(); 318} 319 320ESFMapNode * 321ESFMap::findNode(ESFMapNode *x, const void *k) { 322 // 323 // See Iterative-Tree-Search in "Introduction to Algorithms", Cormen, 324 // Leiserson, Rivest, p.248. 325 // 326 327 int result = 0; 328 329 while (x->_key) { 330 result = _comparator->compare(k, x->_key); 331 332 if (0 == result) { 333 if (_isUnique) { 334 return x; 335 } 336 337 // 338 // This is a departure from Cormen et. al.'s algorithm. If the 339 // map allows multiple elements with the same key, we could have 340 // inserted them to the right of the current node. We always 341 // return the node that is the "smallest" one in the tree so that 342 // any iteration from this point would yield a different key 343 // if it did a getPrevious() and could yield a node with the 344 // same key if it did a getNext(). 345 // 346 ESFMapNode *y = 0; 347 348 while (true) { 349 y = findSuccessor(x); 350 351 if (!y->_key) 352 break; 353 354 if (0 != _comparator->compare(y->_key, x->_key)) 355 break; 356 357 x = y; 358 } 359 360 return x; 361 } else if (0 < result) { 362 x = x->_right; 363 } else { 364 x = x->_left; 365 } 366 } 367 368 return &_sentinel; 369} 370 371ESFMapNode * 372ESFMap::findMinimum(ESFMapNode *x) { 373 // 374 // See Tree-Minimum in "Introduction to Algorithms", Cormen, Leiserson, 375 // Rivest, p. 248. 376 // 377 378 while (x->_left->_key) { 379 x = x->_left; 380 } 381 382 return x; 383} 384 385ESFMapNode * 386ESFMap::findMaximum(ESFMapNode *x) { 387 // 388 // See Tree-Maximum in "Introduction to Algorithms", Cormen, Leiserson, 389 // Rivest, p. 248. 390 // 391 392 while (x->_right->_key) { 393 x = x->_right; 394 } 395 396 return x; 397} 398 399ESFMapNode * 400ESFMap::findSuccessor(ESFMapNode *x) { 401 // 402 // See Tree-Successor in "Introduction to Algorithms", Cormen, Leiserson, 403 // Rivest, p. 249. 404 // 405 406 if (x->_right->_key) { 407 return findMinimum(x->_right); 408 } 409 410 ESFMapNode *y = x->_parent; 411 412 while (y->_key && x == y->_right) { 413 x = y; 414 y = y->_parent; 415 } 416 417 return y; 418} 419 420ESFMapNode * 421ESFMap::findPredecessor(ESFMapNode *x) { 422 // 423 // See Tree-Successor in "Introduction to Algorithms", Cormen, Leiserson, 424 // Rivest, p. 249. 425 // 426 // Tree-Predecessor is symmetric to Tree-Successor. 427 // 428 429 if (x->_left->_key) { 430 return findMaximum(x->_left); 431 } 432 433 ESFMapNode *y = x->_parent; 434 435 while (y->_key && x == y->_left) { 436 x = y; 437 y = y->_parent; 438 } 439 440 return y; 441} 442 443bool ESFMap::insertNode(ESFMapNode *z) { 444 // 445 // See Tree-Insert in "Introduction to Algorithms", Cormen, Leiserson, 446 // Rivest, p. 251. 447 // 448 449 int result = 0; 450 ESFMapNode *y = &_sentinel; 451 ESFMapNode *x = _root; 452 453 while (x->_key) { 454 y = x; 455 456 result = _comparator->compare(z->_key, x->_key); 457 458 if (0 > result) { 459 x = x->_left; 460 } else if (0 < result) { 461 x = x->_right; 462 } else if (_isUnique) { 463 return false; 464 } else { 465 break; 466 } 467 } 468 469 z->_parent = y; 470 z->_left = &_sentinel; 471 z->_right = &_sentinel; 472 473 if (&_sentinel == y) { 474 _root = z; 475 } else if (0 > result) { 476 y->_left = z; 477 } else { 478 y->_right = z; 479 } 480 481 ++_size; 482 483 // 484 // See RB-Insert in "Introduction to Algorithms", Cormen, Leiserson, 485 // Rivest, p. 268. 486 // 487 488 x = z; 489 490 x->_isBlack = false; 491 492 while (x != _root && false == x->_parent->_isBlack) { 493 if (x->_parent == x->_parent->_parent->_left) { 494 y = x->_parent->_parent->_right; 495 496 if (false == y->_isBlack) { 497 x->_parent->_isBlack = true; 498 y->_isBlack = true; 499 x->_parent->_parent->_isBlack = false; 500 x = x->_parent->_parent; 501 } else if (x == x->_parent->_right) { 502 x = x->_parent; 503 leftRotate(x); 504 } else { 505 x->_parent->_isBlack = true; 506 x->_parent->_parent->_isBlack = false; 507 rightRotate(x->_parent->_parent); 508 } 509 } else { 510 y = x->_parent->_parent->_left; 511 512 if (false == y->_isBlack) { 513 x->_parent->_isBlack = true; 514 y->_isBlack = true; 515 x->_parent->_parent->_isBlack = false; 516 x = x->_parent->_parent; 517 } else if (x == x->_parent->_left) { 518 x = x->_parent; 519 rightRotate(x); 520 } else { 521 x->_parent->_isBlack = true; 522 x->_parent->_parent->_isBlack = false; 523 leftRotate(x->_parent->_parent); 524 } 525 } 526 } 527 528 _root->_isBlack = true; 529 530 return true; 531} 532 533void ESFMap::deleteNode(ESFMapNode *z) { 534 // 535 // See RB-Delete in "Introduction to Algorithms", Cormen, Leiserson, 536 // Rivest, p. 273. 537 // 538 539 ESFMapNode *y = 0; 540 ESFMapNode *x = 0; 541 542 if (!z->_left->_key || !z->_right->_key) { 543 y = z; 544 } else { 545 y = findSuccessor(z); 546 } 547 548 if (y->_left->_key) { 549 x = y->_left; 550 } else { 551 x = y->_right; 552 } 553 554 x->_parent = y->_parent; 555 556 if (!y->_parent->_key) { 557 _root = x; 558 } else if (y == y->_parent->_left) { 559 y->_parent->_left = x; 560 } else { 561 y->_parent->_right = x; 562 } 563 564 bool isBlack = y->_isBlack; 565 566 if (y != z) { 567 // 568 // Cormen et. al. simplify this step by copying all fields from 569 // y into z, but since this would violate our iterator invalidation 570 // rules, we really have to replace node z with node y. 571 // 572 573 // Replace all of y's links with z's 574 575 y->_parent = z->_parent; 576 y->_left = z->_left; 577 y->_right = z->_right; 578 y->_isBlack = z->_isBlack; 579 580 // Change the all the links that point to z to instead point to y. 581 582 y->_right->_parent = y; 583 y->_left->_parent = y; 584 585 if (z == y->_parent->_right) { 586 y->_parent->_right = y; 587 } else { 588 y->_parent->_left = y; 589 } 590 591 // If z was the root, y is now the root. 592 593 if (_root == z) { 594 _root = y; 595 } 596 } 597 598 z->~ESFMapNode(); 599 _allocator->deallocate((void *) z); 600 z = 0; 601 602 --_size; 603 604 if (!isBlack) 605 return; 606 607 // 608 // See RB-Delete-Fixup in "Introduction to Algorithms", Cormen, Leiserson, 609 // Rivest, p. 274. 610 // 611 612 ESFMapNode *w = 0; 613 614 while (_root != x && x->_isBlack) { 615 if (x == x->_parent->_left) { 616 w = x->_parent->_right; 617 618 if (!w->_isBlack) { 619 w->_isBlack = true; 620 x->_parent->_isBlack = false; 621 leftRotate(x->_parent); 622 w = x->_parent->_right; 623 } 624 625 if (w->_left->_isBlack && w->_right->_isBlack) { 626 w->_isBlack = false; 627 x = x->_parent; 628 } else if (w->_right->_isBlack) { 629 w->_left->_isBlack = true; 630 w->_isBlack = false; 631 rightRotate(w); 632 w = x->_parent->_right; 633 } else { 634 w->_isBlack = x->_parent->_isBlack; 635 x->_parent->_isBlack = true; 636 w->_right->_isBlack = true; 637 leftRotate(x->_parent); 638 x = _root; 639 } 640 } else { 641 w = x->_parent->_left; 642 643 if (!w->_isBlack) { 644 w->_isBlack = true; 645 x->_parent->_isBlack = false; 646 rightRotate(x->_parent); 647 w = x->_parent->_left; 648 } 649 650 if (w->_right->_isBlack && w->_left->_isBlack) { 651 w->_isBlack = false; 652 x = x->_parent; 653 } else if (w->_left->_isBlack) { 654 w->_right->_isBlack = true; 655 w->_isBlack = false; 656 leftRotate(w); 657 w = x->_parent->_left; 658 } else { 659 w->_isBlack = x->_parent->_isBlack; 660 x->_parent->_isBlack = true; 661 w->_left->_isBlack = true; 662 rightRotate(x->_parent); 663 x = _root; 664 } 665 } 666 } 667 668 x->_isBlack = true; 669} 670 671void ESFMap::rightRotate(ESFMapNode *x) { 672 // 673 // See Left-Rotate in "Introduction to Algorithms", Cormen, Leiserson, 674 // Rivest, p. 266. 675 // 676 // Right-Rotate is symmetric to Left-Rotate. 677 // 678 679 ESFMapNode *y = x->_left; 680 681 x->_left = y->_right; 682 683 if (y->_right->_key) { 684 y->_right->_parent = x; 685 } 686 687 y->_parent = x->_parent; 688 689 if (!x->_parent->_key) { 690 _root = y; 691 } else if (x == x->_parent->_right) { 692 x->_parent->_right = y; 693 } else { 694 x->_parent->_left = y; 695 } 696 697 y->_right = x; 698 x->_parent = y; 699} 700 701void ESFMap::leftRotate(ESFMapNode *x) { 702 // 703 // See Left-Rotate in "Introduction to Algorithms", Cormen, Leiserson, 704 // Rivest, p. 266. 705 // 706 707 ESFMapNode *y = x->_right; 708 709 x->_right = y->_left; 710 711 if (y->_left->_key) { 712 y->_left->_parent = x; 713 } 714 715 y->_parent = x->_parent; 716 717 if (!x->_parent->_key) { 718 _root = y; 719 } else if (x == x->_parent->_left) { 720 x->_parent->_left = y; 721 } else { 722 x->_parent->_right = y; 723 } 724 725 y->_left = x; 726 x->_parent = y; 727} 728 729ESFUInt32 ESFMap::getSize() const { 730 return _size; 731} 732 733bool ESFMap::isEmpty() const { 734 return 0 == _size; 735} 736 737#ifdef DEBUG 738bool ESFMap::isBalanced() const { 739 int height = 0; 740 int blackHeight = 0; 741 bool unbalanced = false; 742 743 height = getHeight(_root); 744 745 // 746 // See Lemma 14.1 in "Introduction to Algorithms", Cormen, Leiserson, 747 // Rivest, p. 264. 748 // 749 // "A red-black tree with n internal nodes has a height at most 2lg(n+1). 750 // 751 752 if (height > 2 * (log10(_size + 1) / log10(2))) { 753 return false; 754 } 755 756 // 757 // See red-black properties in "Introduction to Algorithms", Cormen, 758 // Leiserson, Rivest, p. 263. 759 // 760 // "Every simple path from a node to a descendant leaf contains the 761 // same number of black nodes." 762 // 763 764 blackHeight = getBlackHeight(_root, &unbalanced); 765 766 return !unbalanced; 767} 768 769int ESFMap::getBlackHeight(ESFMapNode *node, bool *unbalanced) const { 770 // 771 // Base case. 772 // 773 if (!node->_key) { 774 ESF_ASSERT( node->_isBlack ); 775 return 0; 776 } 777 778 int right = getBlackHeight(node->_right, unbalanced); 779 int left = getBlackHeight(node->_left, unbalanced); 780 781 if (right != left) { 782 *unbalanced = true; 783 } 784 785 if (node->_isBlack) { 786 return (right > left) ? right + 1 : left + 1; 787 } 788 789 return (right > left) ? right : left; 790} 791 792int ESFMap::getHeight(ESFMapNode *node) const { 793 // 794 // Base case. 795 // 796 if (!node->_key) { 797 return 0; 798 } 799 800 int right = getHeight(node->_right); 801 int left = getHeight(node->_left); 802 803 return (right > left) ? right + 1 : left + 1; 804} 805 806#endif /* defined DEBUG */ 807 808ESFSize ESFMap::GetAllocationSize() { 809 return sizeof(ESFMapNode); 810} 811 812ESFMapIterator::ESFMapIterator() : 813 _node(0) { 814} 815 816ESFMapIterator::ESFMapIterator(ESFMapNode *node) : 817 _node(node) { 818} 819 820ESFMapIterator::ESFMapIterator(const ESFMapIterator &iterator) : 821 _node(iterator._node) { 822} 823 824ESFMapIterator::~ESFMapIterator() { 825} 826