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 &gt; <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