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 // SEQAN_NO_GENERATED_FORWARDS: no forwards are generated for this file
34 
35 #ifndef SEQAN_HEADER_SUMLIST_SKIP_H
36 #define SEQAN_HEADER_SUMLIST_SKIP_H
37 
38 namespace seqan
39 {
40 
41 //////////////////////////////////////////////////////////////////////////////
42 // Skipsumlist_
43 //////////////////////////////////////////////////////////////////////////////
44 
45 //Spec for Map
46 template <unsigned int DIM, typename TSpec = Default>
47 struct Skipsumlist_;
48 
49 //////////////////////////////////////////////////////////////////////////////
50 // Map<Skipsumlist_>
51 //////////////////////////////////////////////////////////////////////////////
52 
53 
54 
55 /*
56 template <typename TValue, unsigned int DIM, typename TSpec>
57 struct SkipListBlockSize_<Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > >
58 {
59     typedef SumList<DIM, TValue, MiniSumList< > > TMiniSumList;
60     typedef Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > TMap;
61     enum
62     {
63         VALUE = sizeof(TMiniSumList) + TMap::MAX_HEIGHT * sizeof(
64     };
65 };
66 */
67 
68 //////////////////////////////////////////////////////////////////////////////
69 
70 template <typename TValue, unsigned int DIM, typename TSpec>
71 class SkiplistNext<TValue, Skipsumlist_<DIM, TSpec> >
72 {
73 public:
74     typedef Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > TMap;
75     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
76     typedef SumListValues<DIM, TValue> TValues;
77 
78     TElement * data_element;
79     TValues values;
80 
SkiplistNext()81     SkiplistNext()
82         : values(MinimalCtor())
83     {}
SkiplistNext(NonMinimalCtor)84     SkiplistNext(NonMinimalCtor)
85         : data_element(0)
86     {}
SkiplistNext(SkiplistNext const & other)87     SkiplistNext(SkiplistNext const & other)
88         : data_element(other.data_element)
89         , values(other.values)
90     {}
~SkiplistNext()91     ~SkiplistNext()
92     {}
93     SkiplistNext const & operator = (SkiplistNext const & other)
94     {
95         data_element = other.data_element;
96         values = other.values;
97         return *this;
98     }
99 };
100 
101 //////////////////////////////////////////////////////////////////////////////
102 
103 
104 template <typename TValue, unsigned int DIM, typename TSpec>
105 class SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> >
106 {
107 public:
108     typedef Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > TSkiplist;
109     typedef SkiplistNext<TValue, Skipsumlist_<DIM, TSpec> > TNext;
110     typedef SumList<DIM, TValue, MiniSumList< > > TMiniSumList;
111 
112     enum
113     {
114         MAX_HEIGHT = TSkiplist::MAX_HEIGHT
115     };
116 
117     TMiniSumList minilist;
118     TNext data_next[MAX_HEIGHT]; //note: only parts of this array available
119 };
120 
121 //////////////////////////////////////////////////////////////////////////////
122 
123 template <typename TValue, unsigned int DIM, typename TSpec>
124 class SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> >
125 {
126 public:
127     typedef Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > TSkiplist;
128     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
129     typedef SumListValues<DIM, TValue> TValues;
130 
131     enum
132     {
133         MAX_HEIGHT = TSkiplist::MAX_HEIGHT
134     };
135 
136     TElement * data_elements[MAX_HEIGHT];
137     TValues sums[MAX_HEIGHT];
138 
SkiplistPath()139     SkiplistPath() {}
SkiplistPath(TSkiplist & sl)140     SkiplistPath(TSkiplist & sl)
141     {
142         for (unsigned int i = 0; i <= sl.data_height; ++i)
143         {
144             data_elements[i] = & (sl.data_border);
145         }
146     }
147 };
148 
149 
150 //____________________________________________________________________________
151 
152 //make path to a kind of iterator
153 
154 template <typename TValue, unsigned int DIM, typename TSpec>
atEnd(SkiplistPath<TValue,Skipsumlist_<DIM,TSpec>> & path)155 bool atEnd(SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > & path)
156 {
157     return (!path.data_elements[0]);
158 }
159 
160 template <typename TValue, unsigned int DIM, typename TSpec, typename TSkiplist>
goNext(SkiplistPath<TValue,Skipsumlist_<DIM,TSpec>> & path,TSkiplist const & skiplist)161 void goNext(SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > & path,
162             TSkiplist const & skiplist)
163 {
164     typedef SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > TPath;
165     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
166 
167     TElement * next = path.data_elements[0]->data_next[0].data_element;
168     for (unsigned int i = 0; i <= skiplist.data_height; ++i)
169     {
170         if (!path.data_elements[i]) break;
171         if (path.data_elements[i]->data_next[i].data_element != next) break;
172 
173         path.sums[i] += path.data_elements[i]->data_next[i].values;
174         path.data_elements[i] = next;
175     }
176 }
177 
178 //////////////////////////////////////////////////////////////////////////////
179 
180 //if true, go right
181 //if false, go down
182 
183 //find a value
184 template <typename TNext, typename THere, typename TValues, typename TValue>
185 inline bool
_skipsumlistFindGoNext(TNext const & _next,THere const &,unsigned char,TValues const & _sum,unsigned int _dim,TValue const & _value)186 _skipsumlistFindGoNext(TNext const & _next,
187                        THere const & /*_here*/,
188                        unsigned char /*_height*/,
189                        TValues const & _sum,
190                        unsigned int _dim,
191                        TValue const & _value)
192 {
193     return (static_cast<TValue>((_sum[_dim] + _next.values[_dim])) <= _value); // SEARCH SEMANTICS
194 }
195 //find an element, given (sum, element_pointer)-pair
196 template <typename TNext, typename THere, typename TValues, typename TValue, typename TElementPtr>
197 inline bool
_skipsumlistFindGoNext(TNext const & _next,THere const & _here,unsigned char,TValues const & _sum,unsigned int _dim,Pair<TValue,TElementPtr> const & pair)198 _skipsumlistFindGoNext(TNext const & _next,
199                        THere const & _here,
200                        unsigned char /*_height*/,
201                        TValues const & _sum,
202                        unsigned int _dim,
203                        Pair<TValue, TElementPtr> const & pair)
204 {
205     return (_sum[_dim] + _next.values[_dim] <= pair.i1) && (pair.i2 != _here);
206 }
207 //find the end of the skiplist
208 template <typename TNext, typename THere, typename TValues>
209 inline bool
_skipsumlistFindGoNext(TNext const & _next,THere const &,unsigned char,TValues const &,unsigned int,GoEnd)210 _skipsumlistFindGoNext(TNext const & _next,
211                        THere const & /*_here*/,
212                        unsigned char /*_height*/,
213                        TValues const & /*_sum*/,
214                        unsigned int /*_dim*/,
215                        GoEnd)
216 {
217     return _next.data_element != 0;
218 }
219 
220 
221 template <typename TValue, unsigned int DIM, typename TSpec, typename TFind>
222 inline void
_skipsumlistFind(Map<TValue,Skiplist<Skipsumlist_<DIM,TSpec>>> & me,TFind const & find,unsigned int dim,SkiplistPath<TValue,Skipsumlist_<DIM,TSpec>> & path)223 _skipsumlistFind(Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > & me,
224                  TFind const & find,
225                  unsigned int dim,
226                  /*OUT*/ SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > & path)
227 {
228     typedef Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > TMap;
229     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
230     typedef SkiplistNext<TValue, Skipsumlist_<DIM, TSpec> > TNext;
231     typedef SumListValues<DIM, TValue> TValues;
232 
233     typedef typename Size<TMap>::Type TSize;
234 
235     TElement * here = & me.data_border;
236 
237     TValues sum;
238 
239     for (int i = me.data_height; i >= 0; --i)
240     {
241         while (true)
242         {
243             TNext & next = here->data_next[i];
244             if (!next.data_element) break;
245 
246             if (!_skipsumlistFindGoNext(next, here, i, sum, dim, find)) break;
247 
248             here = next.data_element;
249             sum += next.values;
250         }
251         path.data_elements[i] = here;
252         path.sums[i] = sum;
253     }
254 }
255 template <typename TValue, unsigned int DIM, typename TSpec, typename TFind>
256 inline void
_skipsumlistFind(Map<TValue,Skiplist<Skipsumlist_<DIM,TSpec>>> const & me,TFind const & find,unsigned int dim,SkiplistPath<TValue,Skipsumlist_<DIM,TSpec>> & path)257 _skipsumlistFind(Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > const & me,
258                  TFind const & find,
259                  unsigned int dim,
260                  /*OUT*/ SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > & path)
261 {//destroy const
262     typedef Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > TMap;
263     _skipsumlistFind(const_cast<TMap &>(me), find, dim, path);
264 }
265 
266 
267 template <typename TValue, unsigned int DIM, typename TSpec>
268 inline void
assign(Map<TValue,Skiplist<Skipsumlist_<DIM,TSpec>>> & target,Map<TValue,Skiplist<Skipsumlist_<DIM,TSpec>>> const & source_)269 assign(Map<TValue, Skiplist< Skipsumlist_<DIM, TSpec> > > & target,
270        Map<TValue, Skiplist< Skipsumlist_<DIM, TSpec> > > const & source_)
271 {
272     typedef Map<TValue, Skiplist< Skipsumlist_<DIM, TSpec> > > TSkiplist;
273     typedef SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > TPath;
274     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
275     //typedef typename Iterator<TSkiplist>::Type TIterator;
276     //typedef typename Value<TSkiplist>::Type TValue2;
277 
278     TSkiplist & source = const_cast<TSkiplist &>(source_); //oh, I'm so damned lazy :-P
279 
280     //first clear target
281     clear(target);
282 
283     //init path variable that is used as iterator-like construct to build up target
284     //and copy link values outgoing from target border
285     TPath target_path(target);
286     target.data_height = source.data_height;
287     for (unsigned int i = 0; i <= target.data_height; ++i)
288     {
289         target_path.data_elements[i] = & target.data_border;
290         target.data_border.data_next[i].values = source.data_border.data_next[i].values;
291     }
292 
293     //copy the first minilist
294     target.data_border.minilist = source.data_border.minilist;
295 
296     TPath source_path(source);
297     //copy rest of the values
298     while (true)
299     {
300         goNext(source_path, source);
301 
302         if (atEnd(source_path)) break;
303 
304         //determine height of current tower
305         unsigned char height;
306         for (height = 1; height < TSkiplist::MAX_HEIGHT; ++height)
307         {
308             if (source_path.data_elements[height] != source_path.data_elements[0]) break;
309         }
310         --height;
311 
312         //create new element in target and copy minilist
313         TElement & el = _skiplistAllocateElement(target, height);
314         el.minilist = source_path.data_elements[0]->minilist;
315 
316         //insert element in target
317         for (int i = 0; i <= height; ++i)
318         {
319             el.data_next[i].data_element = 0;
320             el.data_next[i].values = source_path.data_elements[i]->data_next[i].values;
321             target_path.data_elements[i]->data_next[i].data_element = & el;
322             target_path.data_elements[i] = & el;
323         }
324 
325     }
326 
327     //set length
328     target.data_length = length(source);
329 }
330 
331 //////////////////////////////////////////////////////////////////////////////
332 
333 template <typename TValue, unsigned int DIM, typename TSpec>
334 inline void
clear(Map<TValue,Skiplist<Skipsumlist_<DIM,TSpec>>> & me)335 clear(Map<TValue, Skiplist< Skipsumlist_<DIM, TSpec> > > & me)
336 {
337     typedef Map<TValue, Skiplist< Skipsumlist_<DIM, TSpec> > > TSkiplist;
338 
339     me.data_mem_begin = me.data_mem_end = 0;
340     me.data_length = 0;
341     me.data_height = 0;
342 
343     for (unsigned char i = 0; i < TSkiplist::MAX_HEIGHT; ++i)
344     {
345         me.data_recycle[i] = 0;
346         valueConstruct(me.data_border.data_next + i, NonMinimalCtor());
347     }
348     clear(me.data_border.minilist); //thats new
349 
350     clear(value(me.data_allocator));
351 }
352 
353 //////////////////////////////////////////////////////////////////////////////
354 //////////////////////////////////////////////////////////////////////////////
355 // SumList<Skipsumlist_>
356 //////////////////////////////////////////////////////////////////////////////
357 
358 template <unsigned int DIM, typename TValue, typename TSpec>
359 class SumList<DIM, TValue, SkipSumList<TSpec> >
360 {
361 public:
362     typedef Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > TMap;
363     typedef typename Size<SumList>::Type TSize;
364     typedef SumListValues<DIM, TValue> TValues;
365 
366     TMap map;
367     TSize length;
368     TValues sum;
369 
SumList()370     SumList()
371         : length(0)
372     {}
SumList(SumList const & other)373     SumList(SumList const & other)
374         : length(0)
375     {
376         assign(*this, other);
377     }
~SumList()378     ~SumList()
379     {}
380     SumList const & operator = (SumList const & other)
381     {
382         assign(*this, other);
383         return *this;
384     }
385 };
386 
387 //////////////////////////////////////////////////////////////////////////////
388 
389 
390 template <unsigned int DIM, typename TValue, typename TSpec>
391 inline void
assign(SumList<DIM,TValue,SkipSumList<TSpec>> & target,SumList<DIM,TValue,SkipSumList<TSpec>> const & source)392 assign(SumList<DIM, TValue, SkipSumList<TSpec> > & target,
393        SumList<DIM, TValue, SkipSumList<TSpec> > const & source)
394 {
395     target.map = source.map;
396     target.length = source.length;
397     target.sum = source.sum;
398 }
399 
400 
401 //////////////////////////////////////////////////////////////////////////////
402 
403 template <unsigned int DIM, typename TValue, typename TSpec>
404 inline typename Size< SumList<DIM, TValue, SkipSumList<TSpec> > >::Type
length(SumList<DIM,TValue,SkipSumList<TSpec>> const & me)405 length(SumList<DIM, TValue, SkipSumList<TSpec> > const & me)
406 {
407     return me.length;
408 }
409 
410 //////////////////////////////////////////////////////////////////////////////
411 
412 template <unsigned int DIM, typename TValue, typename TSpec>
413 inline typename Value< SumList<DIM, TValue, SkipSumList<TSpec> > >::Type
getSum(SumList<DIM,TValue,SkipSumList<TSpec>> const & me,unsigned int dim)414 getSum(SumList<DIM, TValue, SkipSumList<TSpec> > const & me,
415        unsigned int dim)
416 {
417     return me.sum[dim];
418 }
419 
420 //////////////////////////////////////////////////////////////////////////////
421 
422 template <unsigned int DIM, typename TValue, typename TSpec>
423 inline void
clear(SumList<DIM,TValue,SkipSumList<TSpec>> & me)424 clear(SumList<DIM, TValue, SkipSumList<TSpec> > & me)
425 {
426     clear(me.map);
427     me.length = 0;
428     clear(me.sum);
429 }
430 
431 //////////////////////////////////////////////////////////////////////////////
432 
433 template <unsigned int DIM, typename TValue, typename TSpec>
434 inline typename Iterator< SumList<DIM, TValue, SkipSumList<TSpec> > >::Type
begin(SumList<DIM,TValue,SkipSumList<TSpec>> & me)435 begin(SumList<DIM, TValue, SkipSumList<TSpec> > & me)
436 {
437     typedef SumList<DIM, TValue, SkipSumList<TSpec> >  TMe;
438     typedef typename Iterator<TMe>::Type TIterator;
439     return TIterator(me);
440 }
441 template <unsigned int DIM, typename TValue, typename TSpec>
442 inline typename Iterator< SumList<DIM, TValue, SkipSumList<TSpec> > const>::Type
begin(SumList<DIM,TValue,SkipSumList<TSpec>> const & me)443 begin(SumList<DIM, TValue, SkipSumList<TSpec> > const & me)
444 {
445     typedef SumList<DIM, TValue, SkipSumList<TSpec> > const TMe;
446     typedef typename Iterator<TMe>::Type TIterator;
447     return TIterator(me);
448 }
449 
450 //////////////////////////////////////////////////////////////////////////////
451 
452 template <unsigned int DIM, typename TValue, typename TSpec>
453 inline typename Iterator< SumList<DIM, TValue, SkipSumList<TSpec> > >::Type
end(SumList<DIM,TValue,SkipSumList<TSpec>> & me)454 end(SumList<DIM, TValue, SkipSumList<TSpec> > & me)
455 {
456     typedef SumList<DIM, TValue, SkipSumList<TSpec> >  TMe;
457     typedef typename Iterator<TMe>::Type TIterator;
458     return TIterator(me, GoEnd());
459 }
460 template <unsigned int DIM, typename TValue, typename TSpec>
461 inline typename Iterator< SumList<DIM, TValue, SkipSumList<TSpec> > const>::Type
end(SumList<DIM,TValue,SkipSumList<TSpec>> const & me)462 end(SumList<DIM, TValue, SkipSumList<TSpec> > const & me)
463 {
464     typedef SumList<DIM, TValue, SkipSumList<TSpec> > const TMe;
465     typedef typename Iterator<TMe>::Type TIterator;
466     return TIterator(me, GoEnd());
467 }
468 
469 //////////////////////////////////////////////////////////////////////////////
470 
471 //NOTE: the first argument is Sumlist, not Map!
472 template <typename TValue, unsigned int DIM, typename TSpec, typename TSpec2>
473 inline unsigned char
_skiplistCreateHeight(SumList<DIM,TValue,SkipSumList<TSpec>> & me,SkiplistPath<TValue,TSpec2> & path)474 _skiplistCreateHeight(SumList<DIM, TValue, SkipSumList<TSpec> > & me,
475                       SkiplistPath<TValue, TSpec2 > & path) //extend path if height is increased
476 {
477     typedef Map<TValue, Skiplist<Skipsumlist_<DIM, TSpec> > > TSkiplist;
478 
479     unsigned char height = geomRand<unsigned char>();
480     if (height >= TSkiplist::MAX_HEIGHT) height = TSkiplist::MAX_HEIGHT-1;
481 
482     if (height > me.map.data_height)
483     {
484         for (unsigned char i = me.map.data_height + 1; i <= height; ++i)
485         {
486             path.data_elements[i] = & me.map.data_border;
487             //path.sums[i] = me.sum;
488             me.map.data_border.data_next[i].values = me.sum;
489         }
490         me.map.data_height = height;
491     }
492 
493     return height;
494 }
495 
496 //////////////////////////////////////////////////////////////////////////////
497 
498 template <unsigned int DIM, typename TValue, typename TSpec, typename TValues>
499 inline void
appendValues(SumList<DIM,TValue,SkipSumList<TSpec>> & me,TValues const & vals)500 appendValues(SumList<DIM, TValue, SkipSumList<TSpec> > & me,
501              TValues const & vals)
502 {
503     typedef SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > TPath;
504     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
505     typedef Pair<TValue, TElement *> TPair;
506     typedef SumList<DIM, TValue, MiniSumList< > > TMiniSumList;
507 
508     //find end of skip list
509     TPath path;
510     _skipsumlistFind(me.map, GoEnd(), 0, path);
511 
512     if (!appendValues(path.data_elements[0]->minilist, vals))
513     {//not enough space in the current last element: append new
514         //create new element
515         unsigned char height = _skiplistCreateHeight(me, path);
516         TElement & el = _skiplistAllocateElement(me.map, height); //see map_skiplist.
517         valueConstruct(& (el.minilist));
518 
519         //append value into minilist of the new element
520         appendValues(el.minilist, vals);
521 
522         //link new element el into skiplist, adjust link weights
523         for (int i = height; i >= 0; --i)
524         {
525             path.data_elements[i]->data_next[i].data_element = & el;
526 
527             el.data_next[i].data_element = 0;
528             el.data_next[i].values = vals;
529         }
530         for (int i = me.map.data_height; i > height ; --i)
531         {
532             path.data_elements[i]->data_next[i].values += vals;
533         }
534 
535         //adjust map properties
536         ++me.map.data_length;
537     }
538     else
539     {
540         //update skiplist path sums
541         for (int i = me.map.data_height; i >= 0 ; --i)
542         {
543             path.data_elements[i]->data_next[i].values += vals;
544         }
545     }
546 
547     //update sumlist variables
548     me.sum += vals;
549     ++me.length;
550 }
551 template <unsigned int DIM, typename TValue, typename TSpec>
552 inline void
appendValues(SumList<DIM,TValue,SkipSumList<TSpec>> & me,TValue * p_vals)553 appendValues(SumList<DIM, TValue, SkipSumList<TSpec> > & me,
554              TValue * p_vals)
555 {
556     SumListValues<DIM, TValue> vals(p_vals);
557     appendValues(me, vals);
558 }
559 template <unsigned int DIM, typename TValue, typename TSpec>
560 inline void
appendValues(SumList<DIM,TValue,SkipSumList<TSpec>> & me,TValue const * p_vals)561 appendValues(SumList<DIM, TValue, SkipSumList<TSpec> > & me,
562              TValue const * p_vals)
563 {
564     SumListValues<DIM, TValue> vals(p_vals);
565     appendValues(me, vals);
566 }
567 
568 
569 //////////////////////////////////////////////////////////////////////////////
570 // Iterator for SkipSumList
571 //////////////////////////////////////////////////////////////////////////////
572 
573 //Helpers for SkipSumListIterator
574 
575 template <typename TSumList>
576 struct SumlistSkipListElement_
577 {//dummy implementation
578     typedef SkiplistElement<int, void> Type;
579 };
580 template <unsigned int DIM, typename TValue, typename TSpec>
581 struct SumlistSkipListElement_< SumList<DIM, TValue, SkipSumList<TSpec> > >
582 {
583     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > Type;
584 };
585 template <unsigned int DIM, typename TValue, typename TSpec>
586 struct SumlistSkipListElement_< SumList<DIM, TValue, SkipSumList<TSpec> > const >
587 {
588     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > const Type;
589 };
590 
591 //////////////////////////////////////////////////////////////////////////////
592 
593 /*
594 template <typename TSumList>
595 struct SumListSkiplistMinilist_
596 {//dummy implementation
597     typedef SumList<1, int, MiniSumList< > > Type;
598 };
599 
600 template <unsigned int DIM, typename TValue, typename TSpec>
601 struct SumListSkiplistMinilist_< SumList<DIM, TValue, SkipSumList<TSpec> > >
602 {
603     typedef SumList<DIM, TValue, MiniSumList< > > Type;
604 };
605 template <unsigned int DIM, typename TValue, typename TSpec>
606 struct SumListSkiplistMinilist_< SumList<DIM, TValue, SkipSumList<TSpec> > const >
607 {
608     typedef SumList<DIM, TValue, MiniSumList< > > const Type;
609 };
610 */
611 
612 //////////////////////////////////////////////////////////////////////////////
613 
614 struct SkipSumListIterator;
615 
616 template <typename TSumList>
617 class Iter<TSumList, SkipSumListIterator>
618 {
619 public:
620     typedef typename Value<TSumList>::Type TValue;
621     typedef SumList<DIMENSION<TSumList>::VALUE, TValue, MiniSumList< > > TMiniSumList_;
622     typedef typename CopyConst_<TSumList, TMiniSumList_>::Type TMiniSumList;
623 //    typedef typename SumListSkiplistMinilist_<TSumList>::Type TMiniSumList;
624     typedef typename Iterator<TMiniSumList>::Type TMiniSumListIterator;
625     typedef typename SumlistSkipListElement_<TSumList>::Type TElement;
626 
627     TSumList * container;
628     mutable TMiniSumListIterator iter;
629     mutable TElement * element;
630 
631     Iter()
632     {
633     }
634     Iter(TSumList & cont)
635         : container(& cont)
636     {
637         goBegin(*this);
638     }
639     Iter(TSumList & cont, GoEnd)
640         : container(& cont)
641         , element(0)
642     {
643     }
644     Iter(Iter const & other)
645         : container(other.container)
646         , iter(other.iter)
647         , element(other.element)
648     {
649     }
650 
651     ~Iter()
652     {
653     }
654     inline Iter const &
655     operator = (Iter const & other)
656     {
657         container = other.container;
658         iter = other.iter;
659         element = other.element;
660         return *this;
661     }
662 };
663 
664 
665 //////////////////////////////////////////////////////////////////////////////
666 
667 template <unsigned int DIM, typename TValue, typename TSpec, typename TIteratorSpec>
668 struct Iterator< SumList<DIM, TValue, SkipSumList<TSpec> >, TIteratorSpec>
669 {
670     typedef SumList<DIM, TValue, SkipSumList<TSpec> > TSumList_;
671     typedef Iter<TSumList_, SkipSumListIterator> Type;
672 };
673 template <unsigned int DIM, typename TValue, typename TSpec, typename TIteratorSpec>
674 struct Iterator< SumList<DIM, TValue, SkipSumList<TSpec> > const, TIteratorSpec>
675 {
676     typedef SumList<DIM, TValue, SkipSumList<TSpec> > const TSumList_;
677     typedef Iter<TSumList_, SkipSumListIterator> Type;
678 };
679 
680 //////////////////////////////////////////////////////////////////////////////
681 
682 template <typename TSumList>
683 inline void
684 goNext(Iter<TSumList, SkipSumListIterator> & it)
685 {
686     goNext(it.iter);
687     if (atEnd(it.iter))
688     {
689         it.element = it.element->data_next[0].data_element;
690         if (it.element)
691         {
692             it.iter.container_ = & it.element->minilist;
693             it.iter.next_ = it.iter.here_ = it.element->minilist.data_;
694             scanValues(it.iter.next_, it.iter.values_);
695         }
696     }
697 }
698 
699 //////////////////////////////////////////////////////////////////////////////
700 
701 //nicht ganz sauber, aber sollte funzen
702 template <typename TSumList>
703 inline void
704 goPrevious(Iter<TSumList, SkipSumListIterator> & it)
705 {
706     searchSumList(it, getSum(it, 0) - 1, 0);
707 }
708 
709 //////////////////////////////////////////////////////////////////////////////
710 
711 template <typename TSumList>
712 inline void
713 goBegin(Iter<TSumList, SkipSumListIterator> & it)
714 {
715     it.element = & (it.container->map.data_border);
716     it.iter = begin(it.element->minilist);
717 }
718 
719 //////////////////////////////////////////////////////////////////////////////
720 
721 template <typename TSumList>
722 inline void
723 goEnd(Iter<TSumList, SkipSumListIterator> & it)
724 {
725     it.element = 0;
726     it.iter.sums_ = it.container->sum;
727 }
728 
729 //////////////////////////////////////////////////////////////////////////////
730 
731 template <unsigned int DIM, typename TValue, typename TSpec>
732 inline void
733 goBeforeEnd(Iter<SumList<DIM, TValue, SkipSumList<TSpec> >, SkipSumListIterator > & it)
734 {
735     typedef SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > TPath;
736     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
737     typedef SumList<DIM, TValue, MiniSumList< > > TMiniSumList;
738 
739     //find end of skip list
740     TPath path;
741     _skipsumlistFind(it.container->map, GoEnd(), 0, path);
742 
743     it.element = path.data_elements[0];
744 
745     //set minilist iterator to end of last minilist
746     it.iter.container_ = & it.element->minilist;
747     goBeforeEnd(it.iter);
748 }
749 
750 //////////////////////////////////////////////////////////////////////////////
751 
752 template <typename TSumList>
753 inline bool
754 atBegin(Iter<TSumList, SkipSumListIterator> & it)
755 {
756     return (it.iter == begin(it.element->minilist));
757 }
758 
759 //////////////////////////////////////////////////////////////////////////////
760 
761 template <typename TSumList>
762 inline bool
763 atEnd(Iter<TSumList, SkipSumListIterator> & it)
764 {
765     return (!it.element);
766 }
767 
768 //////////////////////////////////////////////////////////////////////////////
769 
770 template <typename TSumList>
771 inline typename Value<TSumList>::Type
772 getValue(Iter<TSumList, SkipSumListIterator > & it,
773          int dim)
774 {
775     return it.iter.values_[dim];
776 }
777 template <typename TSumList>
778 inline typename Value<TSumList>::Type
779 getValue(Iter<TSumList, SkipSumListIterator > const & it,
780          int dim)
781 {
782     return it.iter.values_[dim];
783 }
784 
785 //////////////////////////////////////////////////////////////////////////////
786 
787 template <typename TSumList>
788 inline typename Values<TSumList>::Type
789 getValues(Iter<TSumList, SkipSumListIterator > & it)
790 {
791     return it.iter.values_;
792 }
793 template <typename TSumList>
794 inline typename Values<TSumList>::Type
795 getValues(Iter<TSumList, SkipSumListIterator > const & it)
796 {
797     return it.iter.values_;
798 }
799 
800 //////////////////////////////////////////////////////////////////////////////
801 
802 template <typename TSumList>
803 inline typename Value<TSumList>::Type
804 getSum(Iter<TSumList, SkipSumListIterator > & it,
805        int dim)
806 {
807     return it.iter.sums_[dim];
808 }
809 template <typename TSumList>
810 inline typename Value<TSumList>::Type
811 getSum(Iter<TSumList, SkipSumListIterator > const & it,
812        int dim)
813 {
814     return it.iter.sums_[dim];
815 }
816 
817 //////////////////////////////////////////////////////////////////////////////
818 //split the mini list at it and insert a new mini list in skiplist
819 //path must be a path to it.element
820 //path and it are adjusted to the new element if necessary
821 template <unsigned int DIM, typename TValue, typename TSpec, typename TPath>
822 inline void
823 _splitMiniList(Iter<SumList<DIM, TValue, SkipSumList<TSpec> >, SkipSumListIterator > & it,
824                TPath & path)
825 {
826     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
827     typedef SumListValues<DIM, TValue> TValues;
828 
829     //height for new element, adjust path if necessary (if the height of the complete skiplist increases)
830     unsigned char height = _skiplistCreateHeight(* it.container, path);
831 
832     //the current element
833     TElement & el1 = *(it.element);
834 
835     //create new element
836     TElement & el2 = _skiplistAllocateElement(it.container->map, height); //see map_skiplist.h
837     valueConstruct(& (el2.minilist));
838 
839     //move half of the values in el1 to el2
840     splitSumList(el1.minilist, el2.minilist);
841 
842     if (!length(el2))
843     {//el1 was not full enough to create a split: remove el2 from skiplist and exit
844      //(this should not happen, since _splitMiniList is only called it el1 is full)
845         _skiplistDeallocateElement(it.container->map, el2, height);
846         return;
847     }
848 
849     //must adjust the iterator "it"?
850     int it_bytepos = it.iter.here_.data_ptr - el1.minilist.data_;
851     bool it_was_moved = (it_bytepos >= el1.minilist.data_size); //true if "it" points to el2
852 
853     //insert new element el2 into skiplist
854     for (int i = height; i >= 0; --i)
855     {
856         TElement * predecessor;
857         if (path.data_elements[i] == & el1)
858         {//el2 is linked behind el1
859             predecessor = & el1;
860 
861             //adjust values
862             el2.data_next[i].values = predecessor->data_next[i].values;
863             el2.data_next[i].values -= predecessor->minilist.data_sum;
864             predecessor->data_next[i].values = predecessor->minilist.data_sum;
865 
866             if (it_was_moved)
867             {//adjust path
868                 path.data_elements[i] = & el2;
869                 path.sums[i] += predecessor->minilist.data_sum;
870             }
871         }
872         else
873         {//el2 is linked behind another element
874             predecessor = path.data_elements[i];
875 
876             //adjust values
877             TValues pred_values = path.sums[0];
878             pred_values -= path.sums[i];
879             pred_values += el1.minilist.data_sum;
880 
881             el2.data_next[i].values = predecessor->data_next[i].values;
882             el2.data_next[i].values -= pred_values;
883             predecessor->data_next[i].values = pred_values;
884 
885             if (it_was_moved)
886             {//adjust path
887                 path.data_elements[i] = & el2;
888                 path.sums[i] += pred_values;
889             }
890         }
891 
892         //link el2 into skiplist
893         el2.data_next[i].data_element = predecessor->data_next[i].data_element;
894         predecessor->data_next[i].data_element = & el2;
895     }
896 
897     //adjust map properties
898     ++it.container->map.data_length;
899 
900     //adjust it.iter if it was moved
901     if (it_was_moved)
902     {
903         int here_length = it.iter.next_.data_ptr - it.iter.here_.data_ptr; //difference between next_ and here_
904         it.iter.here_.data_ptr = el2.minilist.data_ + it_bytepos - el1.minilist.data_size; //redirect here_
905         it.iter.next_.data_ptr = it.iter.here_.data_ptr + here_length; //redirect next_
906         it.element = & el2;
907         it.iter.container_ = & el2.minilist;
908     }
909 }
910 
911 //////////////////////////////////////////////////////////////////////////////
912 
913 template <unsigned int DIM, typename TValue, typename TSpec, typename TValue2>
914 inline void
915 assignValue(Iter<SumList<DIM, TValue, SkipSumList<TSpec> >, SkipSumListIterator > & it,
916             int dim,
917             TValue2 val)
918 {
919     typedef SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > TPath;
920     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
921     typedef Pair<TValue, TElement *> TPair;
922 
923     TValue val_old = getValue(it, dim);
924 
925     TPath path;
926     _skipsumlistFind(it.container->map, TPair(getSum(it, 0), it.element), 0, path);
927 
928     if (!assignValue(it.iter, dim, val))
929     {//split
930         _splitMiniList(it, path);
931         assignValue(it.iter, dim, val);
932     }
933 
934     //update skiplist path sums
935     for (int i = it.container->map.data_height; i >= 0 ; --i)
936     {
937         if (path.data_elements[i]->data_next[i].data_element == it.element)
938         {// adjust link outgoing from it.element
939             it.element->data_next[i].values[dim] += (val - val_old);
940         }
941         else
942         {// adjust link that jumps over it.element
943             path.data_elements[i]->data_next[i].values[dim] += (val - val_old);
944         }
945     }
946     it.container->sum[dim] += (val - val_old);
947 }
948 
949 //////////////////////////////////////////////////////////////////////////////
950 
951 template <unsigned int DIM, typename TValue, typename TSpec, typename TValues>
952 inline void
953 insertValues(Iter<SumList<DIM, TValue, SkipSumList<TSpec> >, SkipSumListIterator > & it,
954              TValues const & vals)
955 {
956     typedef SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > TPath;
957     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
958     typedef Pair<TValue, TElement *> TPair;
959 
960     TPath path;
961     _skipsumlistFind(it.container->map, TPair(getSum(it, 0), it.element), 0, path);
962 
963     if (!insertValues(it.iter, vals))
964     {//split
965         _splitMiniList(it, path);
966         insertValues(it.iter, vals);
967     }
968 
969     //update skiplist path sums
970     for (int i = it.container->map.data_height; i >= 0 ; --i)
971     {
972         path.data_elements[i]->data_next[i].values += vals;
973     }
974 
975     //update sumlist variables
976     it.container->sum += vals;
977     ++it.container->length;
978 }
979 template <unsigned int DIM, typename TValue, typename TSpec>
980 inline void
981 insertValues(Iter<SumList<DIM, TValue, SkipSumList<TSpec> >, SkipSumListIterator > & it,
982              TValue * p_vals)
983 {
984     SumListValues<DIM, TValue > vals(p_vals);
985     insertValues(it, vals);
986 }
987 template <unsigned int DIM, typename TValue, typename TSpec>
988 inline void
989 insertValues(Iter<SumList<DIM, TValue, SkipSumList<TSpec> >, SkipSumListIterator > & it,
990              TValue const * p_vals)
991 {
992     SumListValues<DIM, TValue > vals(p_vals);
993     insertValues(it, vals);
994 }
995 
996 //////////////////////////////////////////////////////////////////////////////
997 
998 template <unsigned int DIM, typename TValue, typename TSpec>
999 inline void
1000 removeValues(Iter<SumList<DIM, TValue, SkipSumList<TSpec> >, SkipSumListIterator > & it)
1001 {
1002     typedef SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > TPath;
1003     typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
1004     typedef Pair<TValue, TElement *> TPair;
1005 
1006     TPath path;
1007     _skipsumlistFind(it.container->map, TPair(getSum(it, 0), it.element), 0, path);
1008 
1009     //update skiplist path sums
1010     for (int i = it.container->map.data_height; i >= 0 ; --i)
1011     {
1012         path.data_elements[i]->data_next[i].values -= it.iter.values_;
1013     }
1014 
1015     //update sumlist variables
1016     it.container->sum -= it.iter.values_;
1017     --it.container->length;
1018 
1019     //remove values
1020     removeValues(it.iter);
1021 
1022     if (atEnd(it.iter))
1023     {//move to next element
1024         it.element = it.element->data_next[0].data_element;
1025         if (it.element)
1026         {
1027             it.iter.container_ = & it.element->minilist;
1028             it.iter.here_ = it.iter.next_ = it.iter.container_->data_;
1029             scanValues(it.iter.next_, it.iter.values_);
1030         }
1031     }
1032 }
1033 
1034 //////////////////////////////////////////////////////////////////////////////
1035 
1036 //template <unsigned int DIM, typename TValue, typename TSpec, typename TValue2>
1037 //inline void
1038 //searchSumList(Iter<SumList<DIM, TValue, SkipSumList<TSpec> >, SkipSumListIterator > & it,
1039 //              TValue2 const & val,
1040 //              int dim)
1041 template <unsigned int DIM, typename TValue, typename TSpec, typename TSumList, typename TValue2>
1042 inline void
1043 _searchSumlistSkip(Iter<TSumList, SkipSumListIterator > & it,
1044                     TValue2 const & val,
1045                     int dim)
1046 {
1047     typedef SkiplistPath<TValue, Skipsumlist_<DIM, TSpec> > TPath;
1048 //    typedef SkiplistElement<TValue, Skipsumlist_<DIM, TSpec> > TElement;
1049 //    typedef Pair<TValue, TElement *> TPair;
1050 //    typedef SumList<DIM, TValue, MiniSumList< > > TMiniSumList;
1051 
1052     TPath path;
1053 
1054   // The assumpiton here is that val is signed and getSum() fits into it.
1055     if (val >= static_cast<TValue2>(getSum(*it.container, dim)))
1056     {
1057         goEnd(it);
1058         return;
1059     }
1060 
1061     _skipsumlistFind(it.container->map, val, dim, path);
1062 
1063     it.element = path.data_elements[0];
1064     it.iter.container_ = & it.element->minilist;
1065     searchSumList(it.iter, val - path.sums[0][dim], dim);
1066     it.iter.sums_ += path.sums[0];
1067 }
1068 
1069 template <unsigned int DIM, typename TValue, typename TSpec, typename TValue2>
1070 inline void
1071 searchSumList(Iter<SumList<DIM, TValue, SkipSumList<TSpec> >, SkipSumListIterator > & it,
1072               TValue2 const & val,
1073               int dim)
1074 {
1075     _searchSumlistSkip<DIM, TValue, TSpec>(it, val, dim);
1076 }
1077 template <unsigned int DIM, typename TValue, typename TSpec, typename TValue2>
1078 inline void
1079 searchSumList(Iter<SumList<DIM, TValue, SkipSumList<TSpec> > const, SkipSumListIterator > & it,
1080               TValue2 const & val,
1081               int dim)
1082 {
1083     _searchSumlistSkip<DIM, TValue, TSpec>(it, val, dim);
1084 }
1085 //template <unsigned int DIM, typename TValue, typename TSpec, typename TValue2>
1086 //inline void
1087 //searchSumList(Iter<SumList<DIM, TValue, SkipSumList<TSpec> > const, SkipSumListIterator > & it,
1088 //              TValue2 const & val,
1089 //              int dim)
1090 //{
1091 //    _searchSumlistSkip<DIM, TValue, TSpec>(it, val, dim);
1092 //}
1093 
1094 //////////////////////////////////////////////////////////////////////////////
1095 
1096 template <typename TSumList, typename TSumList2>
1097 inline bool
1098 operator == (Iter<TSumList, SkipSumListIterator> const & left,
1099              Iter<TSumList2, SkipSumListIterator> const & right)
1100 {
1101     return ((left.element == 0) && (right.element == 0)) || ((left.element == right.element) && (left.iter == right.iter));
1102 }
1103 
1104 template <typename TSumList, typename TSumList2>
1105 inline bool
1106 operator != (Iter<TSumList, SkipSumListIterator> const & left,
1107              Iter<TSumList2, SkipSumListIterator> const & right)
1108 {
1109     return !(left == right);
1110 }
1111 
1112 
1113 //////////////////////////////////////////////////////////////////////////////
1114 
1115 
1116 
1117 //____________________________________________________________________________
1118 
1119 
1120 //////////////////////////////////////////////////////////////////////////////
1121 
1122 }// namespace seqan
1123 
1124 #endif //#ifndef SEQAN_HEADER_...
1125