1 // ========================================================================== 2 // SeqAn - The Library for Sequence Analysis 3 // ========================================================================== 4 // Copyright (c) 2006-2018, Knut Reinert, FU Berlin 5 // All rights reserved. 6 // 7 // Redistribution and use in source and binary forms, with or without 8 // modification, are permitted provided that the following conditions are met: 9 // 10 // * Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // * Redistributions in binary form must reproduce the above copyright 13 // notice, this list of conditions and the following disclaimer in the 14 // documentation and/or other materials provided with the distribution. 15 // * Neither the name of Knut Reinert or the FU Berlin nor the names of 16 // its contributors may be used to endorse or promote products derived 17 // from this software without specific prior written permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE 23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 29 // DAMAGE. 30 // 31 // ========================================================================== 32 33 #ifndef SEQAN_HEADER_MISC_SKIPLIST_H 34 #define SEQAN_HEADER_MISC_SKIPLIST_H 35 36 37 #include <random> 38 39 40 namespace seqan 41 { 42 43 /*! 44 * @class Skiplist 45 * @extends Map 46 * @headerfile <seqan/map.h> 47 * 48 * @brief General purpose map container. 49 * 50 * @signature template <typename TValue, typename TSpec> 51 * class Map<TValue, Skiplist<TSpec> >; 52 * 53 * @tparam TSpec The specializing type. 54 * @tparam TValue The type of value stored in the map. 55 * 56 * The skiplist takes in average an oberhead of only two pointers per value stored in the map. 57 */ 58 59 ////////////////////////////////////////////////////////////////////////////// 60 // Skiplist 61 ////////////////////////////////////////////////////////////////////////////// 62 63 //forwards 64 65 template <typename TValue, typename TSpec> 66 class Map; 67 68 template <typename TValue, typename TSpec> 69 class SkiplistElement; 70 71 template <typename TValue, typename TSpec> 72 class SkiplistNext; 73 74 template <typename TValue, typename TSpec> 75 class SkiplistPath; 76 77 ////////////////////////////////////////////////////////////////////////////// 78 // Tags 79 80 struct SkiplistIterator; 81 82 ////////////////////////////////////////////////////////////////////////////// 83 84 template <typename T> 85 struct AllocatorType; 86 87 template <typename TValue, typename TSpec> 88 struct AllocatorType<Map<TValue, Skiplist<TSpec> > > 89 { 90 typedef Allocator<SimpleAlloc<> > Type; 91 }; 92 93 ////////////////////////////////////////////////////////////////////////////// 94 95 template <typename TValue, typename TSpec> 96 struct Value<Map<TValue, Skiplist<TSpec> > > 97 { 98 typedef TValue Type; 99 }; 100 101 ////////////////////////////////////////////////////////////////////////////// 102 103 template <typename T> 104 struct SkiplistElement_ 105 { 106 typedef char Type; //dummy implementation for VC++ bug 107 }; 108 109 template <typename TValue, typename TSpec> 110 struct SkiplistElement_<Map<TValue, Skiplist<TSpec> > > 111 { 112 typedef SkiplistElement<TValue, TSpec> Type; 113 }; 114 115 ////////////////////////////////////////////////////////////////////////////// 116 117 template <typename TValue, typename TSpec> 118 struct Key<Map<TValue, Skiplist<TSpec> > >: 119 Key<typename Value< Map<TValue, Skiplist<TSpec> > >::Type> 120 { 121 }; 122 123 ////////////////////////////////////////////////////////////////////////////// 124 125 template <typename TValue, typename TSpec> 126 struct Cargo<Map<TValue, Skiplist<TSpec> > >: 127 Cargo<typename Value< Map<TValue, Skiplist<TSpec> > >::Type> 128 { 129 }; 130 131 ////////////////////////////////////////////////////////////////////////////// 132 133 template <typename TValue, typename TSpec, typename TIteratorSpec> 134 struct Iterator<Map<TValue, Skiplist<TSpec> >, TIteratorSpec > 135 { 136 typedef Map<TValue, Skiplist<TSpec> > TSkiplist_; 137 typedef Iter<TSkiplist_, SkiplistIterator> Type; 138 }; 139 140 141 ////////////////////////////////////////////////////////////////////////////// 142 // Skiplist Map 143 ////////////////////////////////////////////////////////////////////////////// 144 145 template <typename TValue, typename TSpec> 146 class Map<TValue, Skiplist<TSpec> > 147 { 148 public: 149 typedef typename AllocatorType<Map>::Type TAllocator; 150 typedef SkiplistElement<TValue, TSpec> TElement; 151 typedef typename Size<Map>::Type TSize; 152 153 enum 154 { 155 MAX_HEIGHT = 28, //heights are in {0, 1, ..., MAX_HEIGHT-1} 156 BLOCK_SIZE_1_ = sizeof(TElement) * 20, //store min. 20 elements 157 BLOCK_SIZE_2_ = 0x200, //minimal block size 158 BLOCK_SIZE = (BLOCK_SIZE_1_ > BLOCK_SIZE_2_) ? BLOCK_SIZE_1_ : BLOCK_SIZE_2_ //block size is the max out of both values 159 }; 160 161 Holder<TAllocator> data_allocator; 162 TElement * data_recycle[MAX_HEIGHT]; 163 unsigned char * data_mem_begin; 164 unsigned char * data_mem_end; 165 166 SkiplistElement<TValue, TSpec> data_border; 167 TSize data_length; 168 unsigned char data_height; 169 170 std::mt19937 rng; 171 172 Map() 173 : data_mem_begin(0) 174 , data_mem_end(0) 175 , data_length(0) 176 , data_height(0) 177 , rng(0) 178 { 179 for (unsigned char i = 0; i < MAX_HEIGHT; ++i) 180 { 181 data_recycle[i] = 0; 182 valueConstruct(data_border.data_next + i, NonMinimalCtor()); 183 } 184 } 185 Map(Map const & other) 186 : data_mem_begin(0) 187 , data_mem_end(0) 188 , data_length(0) 189 , data_height(0) 190 , rng(0) 191 { 192 assign(*this, other); 193 } 194 195 Map & 196 operator=(Map const & other) 197 { 198 assign(*this, other); 199 return *this; 200 } 201 202 template <typename TKey> 203 inline typename MapValue<Map>::Type 204 operator [] (TKey const & key) 205 { 206 return mapValue(*this, key); 207 } 208 }; 209 210 ////////////////////////////////////////////////////////////////////////////// 211 212 template <typename TValue, typename TSpec> 213 class SkiplistElement 214 { 215 public: 216 typedef Map<TValue, Skiplist<TSpec> > TSkiplist; 217 typedef SkiplistNext<TValue, TSpec> TNext; 218 219 enum 220 { 221 MAX_HEIGHT = TSkiplist::MAX_HEIGHT 222 }; 223 224 TValue data_value; 225 TNext data_next[MAX_HEIGHT]; //note: only parts of this array available 226 227 //indirect constructor in _skiplistConstructElement 228 //indirect destructor in _skiplistDestructElement 229 }; 230 231 ////////////////////////////////////////////////////////////////////////////// 232 233 //representation of "horizontal" pointer in skiplist 234 //can be overloaded if label is needed 235 template <typename TValue, typename TSpec> 236 class SkiplistNext 237 { 238 public: 239 typedef SkiplistElement<TValue, TSpec> TElement; 240 241 TElement * data_element; 242 243 SkiplistNext() : data_element(0) 244 {} 245 246 SkiplistNext(NonMinimalCtor) : data_element(0) 247 {} 248 249 SkiplistNext(SkiplistNext const & other) : data_element(other.data_element) 250 {} 251 }; 252 253 ////////////////////////////////////////////////////////////////////////////// 254 255 //represents a path from the root to the predecessor of a skiplist element 256 template <typename TValue, typename TSpec> 257 class SkiplistPath 258 { 259 public: 260 typedef Map<TValue, Skiplist<TSpec> > TSkiplist; 261 typedef SkiplistElement<TValue, TSpec> TElement; 262 263 enum 264 { 265 MAX_HEIGHT = TSkiplist::MAX_HEIGHT 266 }; 267 268 TElement * data_elements[MAX_HEIGHT]; 269 }; 270 271 ////////////////////////////////////////////////////////////////////////////// 272 273 template<typename TValue, typename TSpec> 274 inline void 275 assign(Map<TValue, Skiplist<TSpec> > & target, 276 Map<TValue, Skiplist<TSpec> > const & source) 277 { 278 typedef Map<TValue, Skiplist<TSpec> > TSkiplist; 279 typedef SkiplistPath<TValue, TSpec> TPath; 280 typedef SkiplistElement<TValue, TSpec> TElement; 281 typedef typename Iterator<TSkiplist>::Type TIterator; 282 283 clear(target); 284 285 TPath path; 286 path.data_elements[0] = & target.data_border; 287 288 for (TIterator it(source); !atEnd(it); goNext(it)) 289 { 290 unsigned char height = _skiplistCreateHeight(target, path); 291 TElement & el = _skiplistConstructElement(target, height, value(it)); 292 293 for (int i = 0; i <= height; ++i) 294 { 295 el.data_next[i].data_element = 0; 296 path.data_elements[i]->data_next[i].data_element = & el; 297 path.data_elements[i] = & el; 298 } 299 300 } 301 302 target.data_length = length(source); 303 } 304 305 ////////////////////////////////////////////////////////////////////////////// 306 307 //create Space for SkiplistElement of given height 308 309 template <typename TValue, typename TSpec> 310 inline SkiplistElement<TValue, TSpec> & 311 _skiplistAllocateElement(Map<TValue, Skiplist<TSpec> > & me, 312 unsigned char height) 313 { 314 typedef Map<TValue, Skiplist<TSpec> > TSkiplist; 315 typedef SkiplistElement<TValue, TSpec> TElement; 316 typedef SkiplistNext<TValue, TSpec> TNext; 317 318 TElement * ret; 319 320 if (me.data_recycle[height]) 321 {//use recycled 322 ret = me.data_recycle[height]; 323 me.data_recycle[height] = * reinterpret_cast<TElement **>(me.data_recycle[height]); 324 } 325 else 326 { 327 int const element_base_size = sizeof(TElement) - TSkiplist::MAX_HEIGHT * sizeof(TNext); 328 int need_size = element_base_size + (height+1) * sizeof(TNext); 329 int buf_size = me.data_mem_end - me.data_mem_begin; 330 if (buf_size < need_size) 331 {//need new memory 332 if (buf_size >= (int) (element_base_size + sizeof(TNext))) 333 {//link rest memory in recycle 334 int rest_height = (buf_size - element_base_size) / sizeof(TNext) - 1; //must be < height, because buf_size < need_size 335 * reinterpret_cast<TElement **>(me.data_mem_begin) = me.data_recycle[rest_height]; 336 me.data_recycle[rest_height] = reinterpret_cast<TElement *>(me.data_mem_begin); 337 } 338 //else: a small part of memory is wasted 339 allocate(value(me.data_allocator), me.data_mem_begin, (size_t) TSkiplist::BLOCK_SIZE, TagAllocateStorage()); 340 me.data_mem_end = me.data_mem_begin + TSkiplist::BLOCK_SIZE; 341 } 342 ret = reinterpret_cast<TElement *>(me.data_mem_begin); 343 me.data_mem_begin += need_size; 344 } 345 346 return *ret; 347 } 348 349 ////////////////////////////////////////////////////////////////////////////// 350 351 //Creates New SkiplistElement 352 template <typename TValue, typename TSpec, typename TValue2> 353 inline SkiplistElement<TValue, TSpec> & 354 _skiplistConstructElement(Map<TValue, Skiplist<TSpec> > & me, 355 unsigned char height, 356 TValue2 const & _value) 357 { 358 typedef SkiplistElement<TValue, TSpec> TElement; 359 TElement & el = _skiplistAllocateElement(me, height); 360 valueConstruct(& (el.data_value), _value); 361 //no need to construct the next array 362 363 return el; 364 } 365 366 ////////////////////////////////////////////////////////////////////////////// 367 368 template <typename TValue, typename TSpec> 369 inline void 370 _skiplistDeallocateElement(Map<TValue, Skiplist<TSpec> > & me, 371 SkiplistElement<TValue, TSpec> & el, 372 unsigned char height) 373 { 374 typedef SkiplistElement<TValue, TSpec> TElement; 375 * reinterpret_cast<TElement **>(& el) = me.data_recycle[height]; 376 me.data_recycle[height] = reinterpret_cast<TElement *>(&el); 377 //the real deallocation is done by the allocator on destruction 378 } 379 380 ////////////////////////////////////////////////////////////////////////////// 381 382 //Destroys New SkiplistElement 383 template <typename TValue, typename TSpec> 384 inline void 385 _skiplistDestructElement(Map<TValue, Skiplist<TSpec> > & me, 386 SkiplistElement<TValue, TSpec> & el, 387 unsigned char height) 388 { 389 valueDestruct(& (el.value) ); 390 //no need to construct the next array 391 _skiplistDeallocateElement(me, el, height); 392 } 393 394 ////////////////////////////////////////////////////////////////////////////// 395 396 //creates height for new SkiplistElement. 397 //increases the Skiplist height if necessary 398 template <typename TValue, typename TSpec> 399 inline unsigned char 400 _skiplistCreateHeight(Map<TValue, Skiplist<TSpec> > & me) 401 { 402 typedef Map<TValue, Skiplist<TSpec> > TSkiplist; 403 404 unsigned char height = static_cast<unsigned char>(std::geometric_distribution<unsigned int>()(me.rng)); 405 if (height >= TSkiplist::MAX_HEIGHT) height = TSkiplist::MAX_HEIGHT-1; 406 407 if (height > me.data_height) me.data_height = height; 408 409 return height; 410 } 411 412 template <typename TValue, typename TSpec> 413 inline unsigned char 414 _skiplistCreateHeight(Map<TValue, Skiplist<TSpec> > & me, 415 SkiplistPath<TValue, TSpec> & path) //extend path if height is increased 416 { 417 typedef Map<TValue, Skiplist<TSpec> > TSkiplist; 418 419 unsigned char height = static_cast<unsigned char>(std::geometric_distribution<unsigned int>()(me.rng)); 420 if (height >= TSkiplist::MAX_HEIGHT) height = TSkiplist::MAX_HEIGHT-1; 421 422 if (height > me.data_height) 423 { 424 for (unsigned char i = me.data_height + 1; i <= height; ++i) 425 { 426 path.data_elements[i] = & me.data_border; 427 } 428 me.data_height = height; 429 } 430 431 return height; 432 } 433 434 ////////////////////////////////////////////////////////////////////////////// 435 436 template <typename TValue, typename TSpec> 437 inline unsigned char 438 _skiplistGetHeight(Map<TValue, Skiplist<TSpec> > & me, 439 SkiplistElement<TValue, TSpec> & el, 440 SkiplistPath<TValue, TSpec> & path) 441 { 442 int height = me.data_height; 443 for (; height > 0 ; --height) 444 { 445 if (path.elements[height]->data_next[height] == el) break; 446 } 447 return height; 448 } 449 450 template <typename TValue, typename TSpec> 451 inline unsigned char 452 _skiplistGetHeight(Map<TValue, Skiplist<TSpec> > & me, 453 SkiplistElement<TValue, TSpec> & el) 454 { 455 typedef SkiplistPath<TValue, TSpec> TPath; 456 457 TPath path; 458 _skiplistFind(me, el, path); 459 460 return _skiplistGetHeight(el, path); 461 } 462 463 ////////////////////////////////////////////////////////////////////////////// 464 465 //Note: always store paths to the element LEFT of the actually wanted element. 466 //this element will be the predecessor during insertion. 467 468 //Given a key: find path to the elment that is left to: 469 // - the first element that has the given key, if there is any, or 470 // - the first element that has the smallest key larger than the given key, 471 //or a path to the last element, if all keys are smaller than the given key 472 473 //Given an element: find path to the element that is left to: 474 // - the given element, or 475 // - the first element that has the smallest key larger than the key of the given element, 476 //or a path to the last element, if all keys are smaller than the key of the given element 477 478 template <typename TValue, typename TSpec, typename TKey> 479 inline bool 480 _skiplistFindGoNext(SkiplistNext<TValue, TSpec> & next, 481 unsigned char, 482 TKey const & _key) 483 { 484 return (key(next.data_element->data_value) < _key); 485 } 486 487 template <typename TValue, typename TSpec> 488 inline bool 489 _skiplistFindGoNext(SkiplistNext<TValue, TSpec> & next, 490 unsigned char, 491 SkiplistElement<TValue, TSpec> const & el) 492 { 493 return (key(next.data_element->data_value) <= key(el.data_value)) && (next.data_element != & el); 494 } 495 496 template <typename TValue, typename TSpec> 497 inline bool 498 _skiplistFindGoNext(SkiplistNext<TValue, TSpec> & next, 499 unsigned char /*height*/, 500 GoEnd) 501 { 502 return next.data_element; 503 // return next.data_element->data_next[height]; 504 } 505 506 507 template <typename TValue, typename TSpec, typename TFind> 508 inline void 509 _skiplistFind(Map<TValue, Skiplist<TSpec> > & me, 510 TFind const & find, //can be a key or a SkiplistElement or GoEnd 511 /*OUT*/ SkiplistPath<TValue, TSpec> & path) 512 { 513 typedef SkiplistElement<TValue, TSpec> TElement; 514 typedef SkiplistNext<TValue, TSpec> TNext; 515 516 TElement * here = & me.data_border; 517 518 for (int i = me.data_height; i >= 0; --i) 519 { 520 while (true) 521 { 522 TNext & next = here->data_next[i]; 523 if (!next.data_element || !_skiplistFindGoNext(next, i, find)) break; 524 here = next.data_element; 525 } 526 path.data_elements[i] = here; 527 } 528 } 529 530 531 ////////////////////////////////////////////////////////////////////////////// 532 533 /*! 534 * @fn Map#find 535 * @headerfile <seqan/map.h> 536 * @brief Find a value in a map. 537 * 538 * @signature TIterator find(map, key); 539 * 540 * @param[in] map A map. Types: Map 541 * @param[in] key A key. 542 * 543 * @return TIterator An iterator to the first value in <tt>map</tt> of the given key, if there is any. An iterator 544 * to the fist value in <tt>map</tt> with key > <tt>key</tt>, otherwise. 545 * 546 * @see Map#value 547 * @see Map#cargo 548 */ 549 550 template <typename TValue, typename TSpec, typename TFind> 551 inline typename Iterator< Map<TValue, Skiplist<TSpec> > >::Type 552 find(Map<TValue, Skiplist<TSpec> > & me, 553 TFind const & _find, //can be a TKey or a SkiplistElement or GoEnd 554 SkiplistPath<TValue, TSpec> & path) 555 { 556 typedef typename Iterator< Map<TValue, Skiplist<TSpec> > >::Type TIterator; 557 558 _skiplistFind(me, _find, path); 559 return TIterator(path.data_elements[0]->data_next[0].data_element); 560 } 561 template <typename TValue, typename TSpec, typename TFind> 562 inline typename Iterator< Map<TValue, Skiplist<TSpec> > >::Type 563 find(Map<TValue, Skiplist<TSpec> > & me, 564 TFind const & _find) //can be a TKey or a SkiplistElement or GoEnd 565 { 566 typedef SkiplistPath<TValue, TSpec> TPath; 567 TPath path; 568 return find(me, _find, path); 569 } 570 571 ////////////////////////////////////////////////////////////////////////////// 572 573 //insert elements after at the position path points to 574 //Requirements: 575 // - height <= height of the skiplist 576 // - next must be filled at least up to height 577 // - el.data_next must have space for at least height many entries 578 template <typename TValue, typename TSpec> 579 inline void 580 _skiplistInsertElement(Map<TValue, Skiplist<TSpec> > & me, 581 SkiplistElement<TValue, TSpec> & el, 582 SkiplistPath<TValue, TSpec> & path, 583 unsigned char height) 584 { 585 for (int i = height; i >= 0; --i) 586 { 587 el.data_next[i].data_element = path.data_elements[i]->data_next[i].data_element; 588 path.data_elements[i]->data_next[i].data_element = & el; 589 } 590 591 ++me.data_length; 592 } 593 594 template <typename TValue, typename TSpec> 595 inline void 596 _skiplistInsertElement(Map<TValue, Skiplist<TSpec> > & me, 597 SkiplistElement<TValue, TSpec> & el, 598 unsigned char height) 599 { 600 typedef SkiplistPath<TValue, TSpec> TPath; 601 602 TPath path; 603 _skiplistFind(me, key(el.data_value), path); 604 605 _skiplistInsertElement(me, el, path, height); 606 } 607 608 ////////////////////////////////////////////////////////////////////////////// 609 //creates entry if necessary 610 611 /*! 612 * @fn Map#value 613 * @brief Returns a value given a key. 614 * 615 * @signature TReference value(map, key); 616 * 617 * @param[in] map A map. 618 * @param[in] key A key. 619 * 620 * @return TReference The first value in <tt>map</tt> of the given key, if there is any. Otherwise, a new value 621 * that is inserted to <tt>map</tt>. 622 * 623 * @note Do not change the key of a value in the map. 624 */ 625 626 template <typename TValue, typename TSpec, typename TKey2> 627 inline typename Value< Map<TValue, Skiplist<TSpec> > >::Type & 628 value(Map<TValue, Skiplist<TSpec> > & me, 629 TKey2 const & _key) 630 { 631 typedef Map<TValue, Skiplist<TSpec> > TSkiplist; 632 typedef SkiplistPath<TValue, TSpec> TPath; 633 typedef SkiplistElement<TValue, TSpec> TElement; 634 typedef typename Iterator<TSkiplist>::Type TIterator; 635 typedef typename Value<TSkiplist>::Type TValue2; 636 637 TPath path; 638 TIterator it = find(me, _key, path); 639 if (it && (key(it) == _key)) 640 { 641 return value(it); 642 } 643 else 644 {// insert new value 645 unsigned char height = _skiplistCreateHeight(me, path); 646 TValue2 val_temp; 647 setKey(val_temp, _key); 648 TElement & el = _skiplistConstructElement(me, height, val_temp); 649 _skiplistInsertElement(me, el, path, height); 650 return el.data_value; 651 } 652 } 653 654 ////////////////////////////////////////////////////////////////////////////// 655 656 /*! 657 * @fn Map#cargo 658 * @brief Returns a cargo given a key. 659 * 660 * @signature TCargo find(map, key); 661 * 662 * @param[in,out] map A map. 663 * @param[in] key A key. 664 * 665 * @return TReturn The cargo of the first value in <tt>map</tt> of the given key, if there is any. Otherwise, the 666 * cargo of a new value that is inserted to <tt>map</tt>. 667 */ 668 669 template <typename TValue, typename TSpec, typename TKey2> 670 inline typename Cargo< Map<TValue, Skiplist<TSpec> > >::Type & 671 cargo(Map<TValue, Skiplist<TSpec> > & me, 672 TKey2 const & _key) 673 { 674 return cargo(value(me, _key)); 675 } 676 677 ////////////////////////////////////////////////////////////////////////////// 678 679 /*! 680 * @fn Map#insert 681 * @brief Insert new value into map. 682 * 683 * @signature void insert(map, value); 684 * @signature void insert(map, key, cargo); 685 * 686 * @param[in,out] map A map. 687 * @param[in] value A value that is added to <tt>map</tt>. 688 * @param[in] key A key. 689 * @param[in] cargo A cargo. 690 * 691 * If <tt>key</tt> and <tt>cargo</tt> are specified, a new value of that key and value is added. If there is already a 692 * value of that key in <tt>map</tt>, the value of this element is changed to <tt>cargo</tt>. 693 * 694 * If <tt>value</tt> is specified, and there is already a value in map of that key, than the cargo of this value is 695 * changed to cargo.cargo(value). 696 * 697 * Use Map#add instead to insert multiple values of the same key. 698 */ 699 700 template <typename TValue, typename TSpec, typename TValue2> 701 inline void 702 insert(Map<TValue, Skiplist<TSpec> > & me, 703 TValue2 const & _value) 704 { 705 value(me, key(_value)) = _value; 706 } 707 template <typename TValue, typename TSpec, typename TKey2, typename TCargo2> 708 inline void 709 insert(Map<TValue, Skiplist<TSpec> > & me, 710 TKey2 const & _key, 711 TCargo2 const & _cargo) 712 { 713 cargo(me, _key) = _cargo; 714 } 715 716 ////////////////////////////////////////////////////////////////////////////// 717 //multiple key insert 718 719 /*! 720 * @fn Map#add 721 * @brief Insert another value into a multi map. 722 * 723 * @signature void add(map, value); 724 * @signature void add(map, key, cargo); 725 * 726 * @param[in,out] map A map. Types: Skiplist 727 * @param[in] value A value that is added to <tt>map</tt>. 728 * @param[in] cargo A cargo. 729 * @param[in] key A key. 730 * 731 * If <tt>key</tt> and <tt>cargo</tt> are specified, a new value of that key and value is added. 732 */ 733 734 template <typename TValue, typename TSpec, typename TValue2> 735 inline void 736 add(Map<TValue, Skiplist<TSpec> > & me, 737 TValue2 const & _value) 738 { 739 typedef SkiplistElement<TValue, TSpec> TElement; 740 741 unsigned char height = _skiplistCreateHeight(me); 742 TElement & el = _skiplistConstructElement(me, height, _value); 743 _skiplistInsertElement(me, el, height); 744 } 745 template <typename TValue, typename TSpec, typename TKey2, typename TCargo2> 746 inline void 747 add(Map<TValue, Skiplist<TSpec> > & me, 748 TKey2 const & _key, 749 TCargo2 const & _cargo) 750 { 751 TValue temp_val; 752 setKey(temp_val, _key); 753 setCargo(temp_val, _cargo); 754 755 add(me, temp_val); 756 } 757 758 ////////////////////////////////////////////////////////////////////////////// 759 760 //extract element from Skiplist 761 template <typename TValue, typename TSpec> 762 inline void 763 _skiplistUnlinkElement(Map<TValue, Skiplist<TSpec> > & me, 764 SkiplistElement<TValue, TSpec> & el) 765 { 766 typedef SkiplistPath<TValue, TSpec> TPath; 767 768 TPath path; 769 _skiplistFind(me, el, path); 770 771 for (int i = me.data_height; i >= 0; --i) 772 { 773 if (path.data_elements[i]->data_next[i].data_element == & el) 774 { 775 path.data_elements[i]->data_next[i].data_element = el.data_next[i].data_element; 776 } 777 } 778 } 779 780 ////////////////////////////////////////////////////////////////////////////// 781 782 /*! 783 * @fn Map#erase 784 * @brief Removes a value from a map. 785 * 786 * @signature void erase(map, key); 787 * @signature void erase(map, iterator); 788 * 789 * @param[in] map A map. Types: Map 790 * @param[in] key The key of a value in <tt>map</tt>. 791 * @param[in] iterator An iterator to a value in <tt>map</tt>. 792 * 793 * Removes the first value in <tt>map</tt> of the given key, if there is any. 794 * 795 * Use @link Map#eraseAll @endlink to remove all values of the given key in a multi map. 796 */ 797 798 template <typename TValue, typename TSpec, typename TMap2> 799 inline void 800 erase(Map<TValue, Skiplist<TSpec> > & me, 801 Iter<TMap2, SkiplistIterator> const & it) 802 { 803 _skiplistUnlinkElement(me, * it.data_pointer); 804 --me.data_length; 805 } 806 807 template <typename TValue, typename TSpec, typename TToRemove> 808 inline void 809 erase(Map<TValue, Skiplist<TSpec> > & me, 810 TToRemove const & to_remove) 811 { 812 typedef Map<TValue, Skiplist<TSpec> > TMap; 813 typedef typename Iterator<TMap>::Type TIterator; 814 TIterator it = find(me, to_remove); 815 if (it && (key(it) == key(to_remove))) 816 { 817 erase(me, it); 818 } 819 } 820 821 ////////////////////////////////////////////////////////////////////////////// 822 823 /*! 824 * @fn Map#eraseAll 825 * @brief Removes a value from a map. 826 * 827 * @signature void eraseAll(map, key); 828 * 829 * @param[in,out] map A map. Types: Skiplist 830 * @param[in] key The key of a value in <tt>map</tt>. 831 * 832 * Removes all values in <tt>map</tt> of the given key, if there is any. 833 */ 834 835 template <typename TValue, typename TSpec, typename TToRemove> 836 inline void 837 eraseAll(Map<TValue, Skiplist<TSpec> > & me, 838 TToRemove const & to_remove) 839 { 840 typedef Map<TValue, Skiplist<TSpec> > TMap; 841 typedef typename Iterator<TMap>::Type TIterator; 842 TIterator it = find(me, to_remove); 843 while (it && (key(it) == key(to_remove))) 844 { 845 TIterator it_old = it; 846 ++it; 847 erase(me, it_old); 848 } 849 } 850 851 ////////////////////////////////////////////////////////////////////////////// 852 853 template <typename TValue, typename TSpec> 854 inline void 855 clear(Map<TValue, Skiplist<TSpec> > & me) 856 { 857 typedef Map<TValue, Skiplist<TSpec> > TSkiplist; 858 859 me.data_mem_begin = me.data_mem_end = 0; 860 me.data_length = 0; 861 me.data_height = 0; 862 863 for (unsigned char i = 0; i < TSkiplist::MAX_HEIGHT; ++i) 864 { 865 me.data_recycle[i] = 0; 866 valueConstruct(me.data_border.data_next + i, NonMinimalCtor()); 867 } 868 869 clear(value(me.data_allocator)); 870 } 871 872 ////////////////////////////////////////////////////////////////////////////// 873 874 template <typename TValue, typename TSpec> 875 inline typename Size< Map<TValue, Skiplist<TSpec> > >::Type 876 length(Map<TValue, Skiplist<TSpec> > const & me) 877 { 878 return me.data_length; 879 } 880 881 ////////////////////////////////////////////////////////////////////////////// 882 883 template <typename TValue, typename TSpec, typename TIteratorSpec> 884 inline typename Iterator< Map<TValue, Skiplist<TSpec> >, TIteratorSpec>::Type 885 begin(Map<TValue, Skiplist<TSpec> > & me, 886 TIteratorSpec) 887 { 888 typedef typename Iterator< Map<TValue, Skiplist<TSpec> >, TIteratorSpec>::Type TIterator; 889 return TIterator(me); 890 } 891 template <typename TValue, typename TSpec> 892 inline typename Iterator< Map<TValue, Skiplist<TSpec> > >::Type 893 begin(Map<TValue, Skiplist<TSpec> > & me) 894 { 895 typedef typename Iterator< Map<TValue, Skiplist<TSpec> > >::Type TIterator; 896 return TIterator(me); 897 } 898 899 ////////////////////////////////////////////////////////////////////////////// 900 901 template <typename TValue, typename TSpec, typename TIteratorSpec> 902 inline typename Iterator< Map<TValue, Skiplist<TSpec> >, TIteratorSpec>::Type 903 end(Map<TValue, Skiplist<TSpec> > &, 904 TIteratorSpec) 905 { 906 typedef typename Iterator< Map<TValue, Skiplist<TSpec> >, TIteratorSpec>::Type TIterator; 907 return TIterator(); 908 } 909 template <typename TValue, typename TSpec> 910 inline typename Iterator< Map<TValue, Skiplist<TSpec> > >::Type 911 end(Map<TValue, Skiplist<TSpec> > &) 912 { 913 typedef typename Iterator< Map<TValue, Skiplist<TSpec> > >::Type TIterator; 914 return TIterator(); 915 } 916 917 918 919 ////////////////////////////////////////////////////////////////////////////// 920 921 template <typename TCargo> 922 struct SkipListMapValue_ 923 { 924 template <typename TValue, typename TSpec, typename TKey2> 925 static inline TCargo & 926 mapValue_(Map<TValue, Skiplist<TSpec> > & me, 927 TKey2 const & _key) 928 { 929 return cargo(me, _key); 930 } 931 }; 932 933 template <> 934 struct SkipListMapValue_<Nothing> 935 { 936 template <typename TValue, typename TSpec, typename TKey2> 937 static inline bool 938 mapValue_(Map<TValue, Skiplist<TSpec> > & me, 939 TKey2 const & _key) 940 { 941 return hasKey(me, _key); 942 } 943 }; 944 945 template <typename TValue, typename TSpec, typename TKey2> 946 inline typename MapValue< Map<TValue, Skiplist<TSpec> > >::Type 947 mapValue(Map<TValue, Skiplist<TSpec> > & me, 948 TKey2 const & _key) 949 { 950 typedef Map<TValue, Skiplist<TSpec> > TSkiplist; 951 typedef typename Cargo<TSkiplist>::Type TCargo; 952 return SkipListMapValue_<TCargo>::mapValue_(me, _key); 953 } 954 955 ////////////////////////////////////////////////////////////////////////////// 956 957 /*! 958 * @fn Map#hasKey 959 * @brief Determines whether a map contains a value given key. 960 * 961 * @signature bool hasKey(map, key); 962 * 963 * @param[in] map A map. Types: Map 964 * @param[in] key A key. 965 * 966 * @return bool <tt>true</tt>, if there is a value in <tt>map</tt> of that key, <tt>false</tt> otherwise. 967 */ 968 969 template <typename TValue, typename TSpec, typename TKey2> 970 inline bool 971 hasKey(Map<TValue, Skiplist<TSpec> > & me, 972 TKey2 const & _key) 973 { 974 typedef Map<TValue, Skiplist<TSpec> > TSkiplist; 975 typedef typename Iterator<TSkiplist>::Type TIterator; 976 TIterator it = find(me, _key); 977 978 return (it && (key(it) == _key)); 979 } 980 981 ////////////////////////////////////////////////////////////////////////////// 982 // SkiplistIterator: Standard Iterator for Skiplist 983 ////////////////////////////////////////////////////////////////////////////// 984 985 template <typename TSkiplist> 986 class Iter< TSkiplist, SkiplistIterator> 987 { 988 public: 989 typedef typename SkiplistElement_<TSkiplist>::Type TElement; 990 typedef typename Value<TSkiplist>::Type TValue; 991 992 TElement * data_pointer; 993 994 Iter() 995 : data_pointer(0) 996 { 997 } 998 Iter(Iter const & other) 999 : data_pointer(other.data_pointer) 1000 { 1001 } 1002 Iter(TElement * ptr) 1003 : data_pointer(ptr) 1004 { 1005 } 1006 Iter(TSkiplist const & sk) 1007 : data_pointer(sk.data_border.data_next[0].data_element) 1008 { 1009 } 1010 ~Iter() 1011 { 1012 } 1013 1014 Iter const & 1015 operator = (Iter const & other) 1016 { 1017 data_pointer = other.data_pointer; 1018 return *this; 1019 } 1020 1021 // TODO(holtgrew): Why conversion to boolean? 1022 operator bool () const 1023 { 1024 // Using != 0 instead of implicit/explicit task here to suppress 1025 // performance warning C4800 in Visual Studio. 1026 return data_pointer != 0; 1027 } 1028 1029 TValue * 1030 operator -> () const 1031 { 1032 return & data_pointer->data_value; 1033 } 1034 1035 }; 1036 1037 ////////////////////////////////////////////////////////////////////////////// 1038 1039 template <typename TSkiplist> 1040 inline bool 1041 atEnd(Iter<TSkiplist, SkiplistIterator> & it) 1042 { 1043 return (!it.data_pointer); 1044 } 1045 1046 ////////////////////////////////////////////////////////////////////////////// 1047 1048 template <typename TSkiplist> 1049 inline void 1050 goNext(Iter<TSkiplist, SkiplistIterator> & it) 1051 { 1052 it.data_pointer = it.data_pointer->data_next[0].data_element; 1053 } 1054 1055 ////////////////////////////////////////////////////////////////////////////// 1056 1057 template <typename TSkiplist> 1058 inline typename Value<TSkiplist>::Type & 1059 value(Iter<TSkiplist, SkiplistIterator> & it) 1060 { 1061 return it.data_pointer->data_value; 1062 } 1063 template <typename TSkiplist> 1064 inline typename Value<TSkiplist>::Type & 1065 value(Iter<TSkiplist, SkiplistIterator> const & it) 1066 { 1067 return it.data_pointer->data_value; 1068 } 1069 1070 ////////////////////////////////////////////////////////////////////////////// 1071 1072 template <typename TSkiplist> 1073 inline typename Key<TSkiplist>::Type const & 1074 key(Iter<TSkiplist, SkiplistIterator> & it) 1075 { 1076 return key(it.data_pointer->data_value); 1077 } 1078 template <typename TSkiplist> 1079 inline typename Key<TSkiplist>::Type const & 1080 key(Iter<TSkiplist, SkiplistIterator> const & it) 1081 { 1082 return key(it.data_pointer->data_value); 1083 } 1084 1085 ////////////////////////////////////////////////////////////////////////////// 1086 1087 template <typename TSkiplist> 1088 inline typename Cargo<TSkiplist>::Type & 1089 cargo(Iter<TSkiplist, SkiplistIterator> & it) 1090 { 1091 return cargo(it.data_pointer->data_value); 1092 } 1093 template <typename TSkiplist> 1094 inline typename Cargo<TSkiplist>::Type & 1095 cargo(Iter<TSkiplist, SkiplistIterator> const & it) 1096 { 1097 return cargo(it.data_pointer->data_value); 1098 } 1099 1100 ////////////////////////////////////////////////////////////////////////////// 1101 1102 template <typename TSkiplist> 1103 inline bool 1104 operator == (Iter<TSkiplist, SkiplistIterator> const & left, 1105 Iter<TSkiplist, SkiplistIterator> const & right) 1106 { 1107 return left.data_pointer == right.data_pointer; 1108 } 1109 1110 template <typename TSkiplist> 1111 inline bool 1112 operator != (Iter<TSkiplist, SkiplistIterator> const & left, 1113 Iter<TSkiplist, SkiplistIterator> const & right) 1114 { 1115 return left.data_pointer != right.data_pointer; 1116 } 1117 1118 //////////////////////////////////////////////////////////////////////////////// 1119 1120 //____________________________________________________________________________ 1121 1122 ////////////////////////////////////////////////////////////////////////////// 1123 1124 } 1125 1126 #endif 1127 1128