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