22 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
23 void merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::Node::Edge::fill_dflt(TPtr b, TPtr e, allocator alloc)
30 alloc.construct(p,dflt);
40 alloc.deallocate(b,e-b);
45 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
48 order_t lk = pow_of_order<order>(height-1);
52 for( ; i!=
order && lk < k; ++i, k-=lk )
54 edges[i].construct(lk, height-1, buf_size, alloc, nalloc);
59 edges[i].construct(k, height-1, buf_size, alloc, nalloc);
62 for( ; i!=
order; ++i )
64 edges[i].child =
NPtr();
65 edges[i].begin = edges[i].end =
TPtr();
73 edges[i].
destroy(alloc, nalloc);
74 edges[i].destroy(alloc, nalloc);
80 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
83 begin = alloc.allocate(*buf_size);
91 child = nalloc.allocate(1);
95 child->construct(k,height,buf_size+1,alloc,nalloc);
99 child->destroy(alloc, nalloc);
100 nalloc.destroy(
child);
106 nalloc.deallocate(
child, 1);
114 alloc.deallocate(
begin,*buf_size);
119 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
122 for(
int i=0; i!=
order; ++i )
123 edges[i].
destroy(alloc, nalloc);
127 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
132 child->destroy(alloc,nalloc);
133 nalloc.destroy(
child);
134 nalloc.deallocate(
child,1);
146 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
149 height_t sp = Splitter::split(static_cast<height_t>(e-b));
152 compute_buffer_sizes(b, b+sp);
153 compute_buffer_sizes(b+sp, e);
155 b[sp] = Splitter::out_buffer_size(pow_of_order<order>(static_cast<height_t>(e-b-sp)));
158 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
162 throw std::invalid_argument(
"Merge tree too small");
165 throw std::invalid_argument(
"Merge tree too high");
167 for(
height_t l=1; l!=logc<order>(k); ++l )
171 compute_buffer_sizes(buffer_sizes,buffer_sizes+height);
173 root = nalloc.allocate(1);
176 nalloc.construct(root,
Node());
177 root->construct(k,height,buffer_sizes+1,alloc,nalloc);
182 last_stream = input_streams = salloc.allocate(K);
183 SPtr p = input_streams;
186 stream_t dflt = stream_t(RanIt(),RanIt());
187 for( ; p!=last_stream+K; ++p )
188 salloc.construct(p,dflt);
192 if( p != input_streams )
194 for( --p; p!=input_streams; --p )
198 salloc.deallocate(input_streams,K);
204 root->destroy(alloc, nalloc);
205 nalloc.destroy(root);
211 nalloc.deallocate(root,1);
216 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
221 for( SPtr s=input_streams; s!=input_streams+K; ++s )
223 salloc.deallocate(input_streams, K);
224 root->destroy(alloc, nalloc);
225 nalloc.destroy(root);
226 nalloc.deallocate(root,1);
229 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
235 for( SPtr s=input_streams; s!=last_stream; ++s )
238 salloc.construct(s,dflt);
242 last_stream = input_streams;
245 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
255 go_down_cold(root->edges[i],index);
259 return fill_root(begin, end);
262 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
263 template<
class OutIt>
272 go_down_cold(root->edges[i],index);
276 return fill_root(begin);
279 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
283 for(
int i=0; i!=
order; ++i )
285 for( ; n->edges[i].head!=n->edges[i].tail && begin!=
end; ++n->edges[i].head, ++
begin )
286 *begin = *n->edges[i].head;
287 if( n->edges[i].child )
288 begin = empty_buffers(n->edges[i].child, begin, end);
293 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
294 template<
class OutIt>
297 for(
int i=0; i!=
order; ++i )
299 begin = std::copy(n->edges[i].head, n->edges[i].tail, begin);
300 if( n->edges[i].child )
301 begin = empty_buffers(n->edges[i].child, begin);
306 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
311 if( e.
child == NPtr() )
314 fill(e.
child,e,index);
319 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
324 warmup(e.
child, e, index);
325 else if( leaf_index <= index && input_streams+
order*(index-leaf_index) < last_stream )
331 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
337 go_down_cold(n->edges[i],index);
339 fill(n,output,index);
342 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
361 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
380 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
381 template<
class OutIt>
394 template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
395 typename merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::TPtr
merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::copy(
typename Node::Edge& de,
bfs_index<order> index, TPtr b, TPtr e)
401 for( ; b!=e; ++b, ++de.
head )
421 template<
class RanIt,
class Splitter,
class Pred,
class Refiller,
class Alloc>
422 class special_<RanIt,2,Splitter,Pred,Refiller,Alloc>
424 friend class merge_tree<RanIt,2,Splitter,Pred,Refiller,Alloc>;
429 typedef typename merge_tree<RanIt,2,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
433 if( that->root->edges[0].head != that->root->edges[0].tail )
434 if( that->root->edges[1].head != that->root->edges[1].tail )
435 for( TPtr l=that->root->edges[0].head, r=that->root->edges[1].head;; )
439 that->root->edges[0].head = l;
440 that->root->edges[1].head = r;
443 if( that->comp(*l,*r) )
445 *begin = *l, ++l, ++
begin;
446 if( l == that->root->edges[0].tail )
448 typename Node::Edge& de = that->root->edges[0];
449 that->root->edges[0].head = l; that->root->edges[1].head = r;
451 that->go_down(de,index);
453 if( de.head == de.tail )
455 l = that->root->edges[0].head;
460 *begin = *r, ++r, ++
begin;
461 if( r == that->root->edges[1].tail )
463 typename Node::Edge& de = that->root->edges[1];
464 that->root->edges[0].head = l; that->root->edges[1].head = r;
466 that->go_down(de,index);
468 if( de.head == de.tail )
470 r = that->root->edges[1].head;
477 return that->copy_root(that->root->edges[0], index, begin, end,
typename std::iterator_traits<FwIt>::iterator_category());
479 else if( that->root->edges[1].head != that->root->edges[1].tail )
482 return that->copy_root(that->root->edges[1], index, begin, end,
typename std::iterator_traits<FwIt>::iterator_category());
488 template<
class OutIt>
491 typedef typename merge_tree<RanIt,2,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
495 if( that->root->edges[0].head != that->root->edges[0].tail )
496 if( that->root->edges[1].head != that->root->edges[1].tail )
497 for( TPtr l=that->root->edges[0].head, r=that->root->edges[1].head;; )
498 if( that->comp(*l,*r) )
500 *begin = *l, ++l, ++
begin;
501 if( l == that->root->edges[0].tail )
503 typename Node::Edge& de = that->root->edges[0];
504 that->root->edges[0].head = l; that->root->edges[1].head = r;
506 that->go_down(de,index);
508 if( de.head == de.tail )
510 l = that->root->edges[0].head;
515 *begin = *r, ++r, ++
begin;
516 if( r == that->root->edges[1].tail )
518 typename Node::Edge& de = that->root->edges[1];
519 that->root->edges[0].head = l; that->root->edges[1].head = r;
521 that->go_down(de,index);
523 if( de.head == de.tail )
525 r = that->root->edges[1].head;
531 return that->copy_root(that->root->edges[0], index, begin);
533 else if( that->root->edges[1].head != that->root->edges[1].tail )
536 return that->copy_root(that->root->edges[1], index, begin);
542 static void fill(
merge_tree<RanIt,2,Splitter,Pred,Refiller,Alloc>* that,
typename merge_tree<RanIt,2,Splitter,Pred,Refiller,Alloc>::NPtr n,
typename merge_tree<RanIt,2,Splitter,Pred,Refiller,Alloc>::Node::Edge& output,
bfs_index<2> index)
544 typedef typename merge_tree<RanIt,2,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
546 for( TPtr p = output.
head;; )
547 if( n->edges[0].head != n->edges[0].tail )
548 if( n->edges[1].head != n->edges[1].tail )
549 for( TPtr l=n->edges[0].head, r=n->edges[1].head;; )
551 if( p == output.
tail )
554 n->edges[0].head = l;
555 n->edges[1].head = r;
558 #ifdef USE_COND_MOVS_ 565 mov edi, dword ptr [ebx] ; edges[0] key in edi
566 mov edx, dword ptr [ecx] ; edges[1] key in edx
568 cmovl edx, edi ; small key in edx
569 cmovl edi, dword ptr [ebx+4] ; small pointer in edi
570 cmovge edi, dword ptr [ecx+4] ; small pointer in edi
571 mov dword ptr [eax], edx ; output small key
572 mov dword ptr [eax+4], edi ; output small pointer
574 mov edi, ebx ; cond-inc edges[0]
578 mov edi, ecx ; cond-inc edges[1]
589 asm(
"movl\t(%1), %%edi\n\t" 590 "movl\t(%2), %%edx\n\t" 591 "cmpl\t%%edx, %%edi\n\t" 592 "cmovll\t%%edi, %%edx\n\t" 593 "cmovll\t4(%1), %%edi\n\t" 594 "cmovgel\t4(%2), %%edi\n\t" 595 "movl\t%%edx, (%0)\n\t" 596 "movl\t%%edi, 4(%0)\n\t" 598 "movl\t%1, %%edi\n\t" 599 "addl\t$8, %%edi\n\t" 600 "testb\t%%dl, %%dl\n\t" 601 "cmovnzl\t%%edi, %1\n\t" 602 "movl\t%2, %%edi\n\t" 603 "addl\t$8, %%edi\n\t" 604 "testb\t%%dl, %%dl\n\t" 605 "cmovzl\t%%edi, %2\n\t" 607 :
"=r"(p),
"=r"(l),
"=r"(r) :
"0"(p),
"1"(l),
"2"(r) :
"edx",
"edi");
609 register TPtr nh = l+1;
610 bool b = that->comp(*l,*r);
618 if( l == n->edges[0].tail )
620 typename Node::Edge& de = n->edges[0];
621 n->edges[0].head = l; n->edges[1].head = r;
623 that->go_down(de,index);
624 if( de.head == de.tail )
626 l = n->edges[0].head;
628 if( r == n->edges[1].tail )
630 typename Node::Edge& de = n->edges[1];
631 n->edges[0].head = l; n->edges[1].head = r;
633 that->go_down(de,index);
634 if( de.head == de.tail )
636 r = n->edges[1].head;
638 #else // USE_COND_MOVS_ 639 if( that->comp(*l,*r) )
642 if( l == n->edges[0].tail )
644 typename Node::Edge& de = n->edges[0];
645 n->edges[0].head = l; n->edges[1].head = r;
647 that->go_down(de,index);
649 if( de.head == de.tail )
651 l = n->edges[0].head;
657 if( r == n->edges[1].tail )
659 typename Node::Edge& de = n->edges[1];
660 n->edges[0].head = l; n->edges[1].head = r;
662 that->go_down(de,index);
664 if( de.head == de.tail )
666 r = n->edges[1].head;
669 #endif // USE_COND_MOVS_ 674 output.
head = that->copy(n->edges[0], index, p, output.
tail);
677 else if( n->edges[1].head != n->edges[1].tail )
680 output.
head = that->copy(n->edges[1], index, p, output.
tail);
687 static void fill_leaf(
merge_tree<RanIt,2,Splitter,Pred,Refiller,Alloc>* that,
typename merge_tree<RanIt,2,Splitter,Pred,Refiller,Alloc>::Node::Edge& output,
bfs_index<2> index)
689 typedef typename merge_tree<RanIt,2,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
691 stream_iterator left = that->input_streams+2*(index-that->leaf_index);
692 stream_iterator right = left;
696 RanIt l=(*left).begin(), r=(*right).begin();
697 for( TPtr p = output.
head;; )
698 if( l != (*left).end() )
699 if( r != (*right).end() )
702 if( p == output.
tail )
706 (*right).begin() = r;
710 if( that->comp(*l,*r) )
713 if( l == (*left).end() )
719 if( r == (*right).end() )
725 assert( r == (*right).end() );
726 if( output.
tail-p < (*left).end()-l )
727 for( ; p!=output.
tail; ++p, ++l )
730 for( ; (*left).end()!=l; ++p, ++l )
734 (*right).begin() = r;
738 else if( r != (*right).end() )
740 assert( l == (*left).end() );
741 if( output.
tail-p < (*right).end()-r )
742 for( ; p!=output.
tail; ++p, ++r )
745 for( ; (*right).end()!=r; ++p, ++r )
749 (*right).begin() = r;
762 #define MOVE_SMALL(i,n) *begin = *head[i], ++head[i], ++begin; \ 763 if( head[i] == tail[i] ) \ 765 stream[i]->head = head[i]; \ 766 index.child(static_cast<basic_order_t>(stream[i]-n->edges)); \ 767 that->go_down(*stream[i],index); \ 769 head[i] = stream[i]->head; tail[i] = stream[i]->tail; \ 770 if( head[i] == tail[i] ) \ 773 head[i] = head[active]; \ 774 tail[i] = tail[active]; \ 775 stream[i] = stream[active]; \ 779 #define MOVE_SMALL_(i,n) *begin = *head[i], ++head[i], ++begin; \ 780 if( head[i] == tail[i] ) \ 781 if( go_down(that, i, active-1, index, head, tail, n->edges, stream) ) \ 787 template<
class RanIt,
class Splitter,
class Pred,
class Refiller,
class Alloc>
788 class special_<RanIt,4,Splitter,Pred,Refiller,Alloc>
790 friend class merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>;
793 static bool go_down(
merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc> *that,
order_t i,
order_t active,
bfs_index<4> index, TPtr *
head, TPtr *
tail,
typename merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>::Node::Edge* edges,
typename merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>::Node::Edge** stream)
795 stream[i]->
head = head[i];
796 index.
child(static_cast<basic_order_t>(stream[i]-edges));
797 that->go_down(*stream[i],index);
798 head[i] = stream[i]->
head; tail[i] = stream[i]->
tail;
799 if( head[i] == tail[i] )
801 head[i] = head[active];
802 tail[i] = tail[active];
803 stream[i] = stream[active];
813 typedef typename merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
815 Pred& comp = that->comp;
817 TPtr head[4], tail[4];
820 for( Edge *p=that->root->edges; p!=that->root->edges+4; ++p )
821 if( p->head != p->tail )
824 head[active] = p->
head, tail[active] = p->tail;
835 stream[0]->head = head[0]; stream[1]->head = head[1]; stream[2]->head = head[2]; stream[3]->head = head[3];
838 if( comp(*head[0],*head[3]) )
840 if( comp(*head[0],*head[2]) )
842 if( comp(*head[0],*head[1]) )
853 if( comp(*head[1],*head[2]) )
865 if( comp(*head[1],*head[3]) )
867 if( comp(*head[1],*head[2]) )
878 if( comp(*head[2],*head[3]) )
894 stream[0]->head = head[0]; stream[1]->head = head[1]; stream[2]->head = head[2];
897 if( comp(*head[0],*head[2]) )
899 if( comp(*head[0],*head[1]) )
910 if( comp(*head[1],*head[2]) )
925 stream[0]->head = head[0]; stream[1]->head = head[1];
928 if( comp(*head[0],*head[1]) )
938 stream[0]->head = head[0];
939 index.
child(static_cast<basic_order_t>(stream[0]-that->root->edges));
940 begin = that->copy_root(*stream[0], index, begin, end,
typename std::iterator_traits<FwIt>::iterator_category());
949 template<
class OutIt>
952 typedef typename merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
954 Pred& comp = that->comp;
956 TPtr head[4], tail[4];
959 for( Edge *p=that->root->edges; p!=that->root->edges+4; ++p )
960 if( p->head != p->tail )
963 head[active] = p->head, tail[active] = p->tail;
971 if( comp(*head[0],*head[3]) )
973 if( comp(*head[0],*head[2]) )
975 if( comp(*head[0],*head[1]) )
986 if( comp(*head[1],*head[2]) )
998 if( comp(*head[1],*head[3]) )
1000 if( comp(*head[1],*head[2]) )
1011 if( comp(*head[2],*head[3]) )
1023 if( comp(*head[0],*head[2]) )
1025 if( comp(*head[0],*head[1]) )
1036 if( comp(*head[1],*head[2]) )
1047 if( comp(*head[0],*head[1]) )
1056 stream[0]->head = head[0];
1057 index.
child(static_cast<basic_order_t>(stream[0]-that->root->edges));
1058 begin = that->copy_root(*stream[0], index, begin);
1067 static void fill(
merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>* that,
typename merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>::NPtr n,
typename merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>::Node::Edge& output,
bfs_index<4> index)
1069 typedef typename merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
1071 Pred& comp = that->comp;
1072 TPtr head[4], tail[4];
1075 for( Edge *p=n->edges; p!=n->edges+4; ++p )
1076 if( p->head != p->tail )
1079 head[active] = p->head, tail[active] = p->tail;
1083 TPtr begin = output.
head;
1089 if( begin == output.
tail )
1092 stream[0]->head = head[0]; stream[1]->head = head[1]; stream[2]->head = head[2]; stream[3]->head = head[3];
1095 if( comp(*head[0],*head[3]) )
1097 if( comp(*head[0],*head[2]) )
1099 if( comp(*head[0],*head[1]) )
1110 if( comp(*head[1],*head[2]) )
1122 if( comp(*head[1],*head[3]) )
1124 if( comp(*head[1],*head[2]) )
1135 if( comp(*head[2],*head[3]) )
1149 if( begin == output.
tail )
1152 stream[0]->head = head[0]; stream[1]->head = head[1]; stream[2]->head = head[2];
1155 if( comp(*head[0],*head[2]) )
1157 if( comp(*head[0],*head[1]) )
1168 if( comp(*head[1],*head[2]) )
1181 if( begin == output.
tail )
1184 stream[0]->head = head[0]; stream[1]->head = head[1];
1187 if( comp(*head[0],*head[1]) )
1197 stream[0]->head = head[0];
1198 index.
child(static_cast<basic_order_t>(stream[0]-n->edges));
1199 output.
head = that->copy(*stream[0], index, begin, output.
tail);
1208 static void fill_leaf(
merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>* that,
typename merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>::Node::Edge& output,
bfs_index<4> index)
1210 typedef typename merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
1211 typedef typename merge_tree<RanIt,4,Splitter,Pred,Refiller,Alloc>::SPtr SPtr;
1212 assert( that->input_streams+4*(index-that->leaf_index) < that->last_stream );
1213 assert( that->input_streams <= that->input_streams+4*(index-that->leaf_index) );
1214 Pred& comp = that->comp;
1215 RanIt head[4], tail[4];
1218 for( SPtr p=that->input_streams+4*(index-that->leaf_index); p!=that->input_streams+4*(index-that->leaf_index+1); ++p )
1219 if( p->first != p->second )
1222 head[active] = p->first, tail[active] = p->second;
1226 TPtr begin = output.
head;
1232 if( begin == output.
tail )
1235 stream[0]->first = head[0]; stream[1]->first = head[1]; stream[2]->first = head[2]; stream[3]->first = head[3];
1239 if( comp(*head[0],*head[3]) )
1241 if( comp(*head[0],*head[2]) )
1243 if( comp(*head[0],*head[1]) )
1245 *begin = *head[0], ++head[0], ++
begin;
1246 if( head[0] == tail[0] )
1248 stream[0]->first = head[0];
1251 stream[0] = stream[3];
1257 *begin = *head[1], ++head[1], ++
begin;
1258 if( head[1] == tail[1] )
1260 stream[1]->first = head[1];
1263 stream[1] = stream[3];
1270 if( comp(*head[1],*head[2]) )
1272 *begin = *head[1], ++head[1], ++
begin;
1273 if( head[1] == tail[1] )
1275 stream[1]->first = head[1];
1278 stream[1] = stream[3];
1284 *begin = *head[2], ++head[2], ++
begin;
1285 if( head[2] == tail[2] )
1287 stream[2]->first = head[2];
1290 stream[2] = stream[3];
1298 if( comp(*head[1],*head[3]) )
1300 if( comp(*head[1],*head[2]) )
1302 *begin = *head[1], ++head[1], ++
begin;
1303 if( head[1] == tail[1] )
1305 stream[1]->first = head[1];
1308 stream[1] = stream[3];
1314 *begin = *head[2], ++head[2], ++
begin;
1315 if( head[2] == tail[2] )
1317 stream[2]->first = head[2];
1320 stream[2] = stream[3];
1327 if( comp(*head[2],*head[3]) )
1329 *begin = *head[2], ++head[2], ++
begin;
1330 if( head[2] == tail[2] )
1332 stream[2]->first = head[2];
1335 stream[2] = stream[3];
1341 *begin = *head[3], ++head[3], ++
begin;
1342 if( head[3] == tail[3] )
1344 stream[3]->first = head[3];
1354 if( begin == output.
tail )
1357 stream[0]->first = head[0]; stream[1]->first = head[1]; stream[2]->first = head[2];
1361 if( comp(*head[0],*head[2]) )
1363 if( comp(*head[0],*head[1]) )
1365 *begin = *head[0], ++head[0], ++
begin;
1366 if( head[0] == tail[0] )
1368 stream[0]->first = head[0];
1371 stream[0] = stream[2];
1377 *begin = *head[1], ++head[1], ++
begin;
1378 if( head[1] == tail[1] )
1380 stream[1]->first = head[1];
1383 stream[1] = stream[2];
1390 if( comp(*head[1],*head[2]) )
1392 *begin = *head[1], ++head[1], ++
begin;
1393 if( head[1] == tail[1] )
1395 stream[1]->first = head[1];
1398 stream[1] = stream[2];
1404 *begin = *head[2], ++head[2], ++
begin;
1405 if( head[2] == tail[2] )
1407 stream[2]->first = head[2];
1416 if( begin == output.
tail )
1419 stream[0]->first = head[0]; stream[1]->first = head[1];
1423 if( comp(*head[0],*head[1]) )
1425 *begin = *head[0], ++head[0], ++
begin;
1426 if( head[0] == tail[0] )
1428 stream[0]->first = head[0];
1430 if( output.
tail-begin < stream[1]->second-head[1] )
1431 for( ; begin!=output.
tail; ++
begin, ++head[1] )
1434 for( ; stream[1]->second!=head[1]; ++
begin, ++head[1] )
1437 stream[1]->first = head[1];
1448 *begin = *head[1], ++head[1], ++
begin;
1449 if( head[1] == tail[1] )
1451 stream[1]->first = head[1];
1457 if( output.
tail-begin < stream[0]->second-head[0] )
1458 for( ; begin!=output.
tail; ++
begin, ++head[0] )
1461 for( ; stream[0]->second!=head[0]; ++
begin, ++head[0] )
1464 stream[0]->first = head[0];
1482 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1490 alloc.construct(p,dflt);
1496 for( --p; p!=b; --p )
1500 alloc.deallocate(b,e-b);
1505 template<
int Order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1506 typename merge_tree<typename Alloc::pointer,Order,Splitter,Pred,Refiller,Alloc>::Node::Edge**
merge_tree<typename Alloc::pointer,Order,Splitter,Pred,Refiller,Alloc>::Node::construct(
order_t k,
height_t height,
size_t *buf_size,
typename merge_tree<typename Alloc::pointer,Order,Splitter,Pred,Refiller,Alloc>::Node::Edge** edge_list,
allocator alloc,
nallocator nalloc)
1508 order_t lk = pow_of_order<order>(height-1);
1512 for( ; i!=
order && lk < k; ++i, k-=lk )
1514 edge_list = edges[i].
construct(lk, height-1, buf_size, edge_list, alloc, nalloc);
1519 edge_list = edges[i].
construct(k, height-1, buf_size, edge_list, alloc, nalloc);
1522 for( ; i!=
order; ++i )
1534 edges[i].
destroy(alloc, nalloc);
1535 edges[i].
destroy(alloc, nalloc);
1541 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1542 typename merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::Node::Edge**
merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::Node::Edge::construct(
order_t k,
height_t height,
size_t *buf_size, Edge** edge_list,
allocator alloc,
nallocator nalloc)
1546 begin = alloc.allocate(*buf_size);
1547 head = tail = end = begin+*buf_size;
1550 fill_dflt(begin,end,alloc);
1553 child = nalloc.allocate(1);
1557 return child->construct(k,height,buf_size+1,edge_list,alloc,nalloc);
1561 child->destroy(alloc, nalloc);
1562 nalloc.destroy(
child);
1568 nalloc.deallocate(
child, 1);
1574 alloc.deallocate(begin,*buf_size);
1581 head = tail = end = begin =
TPtr();
1587 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1590 for(
int i=0; i!=
order; ++i )
1591 edges[i].
destroy(alloc, nalloc);
1595 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1600 child->destroy(alloc,nalloc);
1601 nalloc.destroy(
child);
1602 nalloc.deallocate(
child,1);
1604 if( begin !=
TPtr() )
1606 for( TPtr p=begin; p!=
end; ++p )
1608 alloc.deallocate(begin,end-begin);
1613 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1616 height_t sp = Splitter::split(static_cast<height_t>(e-b));
1619 compute_buffer_sizes(b, b+sp);
1620 compute_buffer_sizes(b+sp, e);
1622 b[sp] = Splitter::out_buffer_size(pow_of_order<order>(static_cast<height_t>(e-b-sp)));
1625 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1629 throw std::invalid_argument(
"Merge tree too small");
1632 throw std::invalid_argument(
"Merge tree too high");
1634 for(
height_t l=1; l!=logc<order>(k); ++l )
1638 compute_buffer_sizes(buffer_sizes,buffer_sizes+height);
1640 last_stream = input_streams = salloc.allocate(k);
1641 SPtr p = input_streams;
1645 for( ; p!=last_stream+k; ++p )
1646 salloc.construct(p,dflt);
1650 root = nalloc.allocate(1);
1653 nalloc.construct(root,
Node());
1654 root->construct(k,height,buffer_sizes+1,input_streams,alloc,nalloc);
1658 root->destroy(alloc, nalloc);
1659 nalloc.destroy(root);
1665 nalloc.deallocate(root,1);
1671 if( p != input_streams )
1673 for( --p; p!=input_streams; --p )
1677 salloc.deallocate(input_streams,k);
1682 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1685 for( SPtr s=input_streams; s!=input_streams+k; ++s )
1687 salloc.deallocate(input_streams, k);
1688 root->destroy(alloc, nalloc);
1689 nalloc.destroy(root);
1690 nalloc.deallocate(root,1);
1693 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1697 last_stream = input_streams;
1700 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1701 template<
class FwIt>
1705 for(
int i=0; i!=
order; ++i )
1706 if( root->edges[i].child !=
NPtr() )
1707 go_down_cold(root->edges[i], comp);
1709 return fill(root, begin, end, comp);
1712 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1713 template<
class OutIt>
1717 for(
int i=0; i!=
order; ++i )
1718 if( root->edges[i].child !=
NPtr() )
1719 go_down_cold(root->edges[i], comp);
1721 return fill(root, begin, comp);
1724 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1725 template<
class FwIt>
1728 for(
int i=0; i!=
order; ++i )
1730 for( ; n->edges[i].head!=n->edges[i].tail && begin!=
end; ++n->edges[i].head, ++
begin )
1731 *begin = *n->edges[i].head;
1732 if( n->edges[i].child )
1733 begin = empty_buffers(n->edges[i].child, begin, end);
1738 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1739 template<
class OutIt>
1742 for(
int i=0; i!=
order; ++i )
1744 begin = std::copy(n->edges[i].head, n->edges[i].tail, begin);
1745 if( n->edges[i].child )
1746 begin = empty_buffers(n->edges[i].child, begin);
1751 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1754 assert( e.tail == e.head );
1755 assert( e.child !=
NPtr() );
1756 e.tail = fill(e.child, e.begin, e.tail, comp);
1760 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1763 assert( e.child !=
NPtr() );
1764 e.tail = e.end, e.head = e.begin;
1765 warmup(e.child, e, comp);
1766 e.tail = e.head, e.head = e.begin;
1769 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1772 for(
int i=0; i!=
order; ++i )
1773 if( n->edges[i].child !=
NPtr() )
1774 go_down_cold(n->edges[i], comp);
1775 output.head = fill(n, output.head, output.tail, comp);
1778 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1779 template<
class FwIt>
1784 for( ; de.tail!=de.head && begin!=
end; ++
begin, ++de.head )
1786 if( de.tail == de.head && de.child !=
NPtr() )
1789 if( de.head == de.tail )
1797 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1817 if( end-begin < de.tail-de.head )
1819 for( ; begin!=
end; ++
begin, ++de.head )
1825 for( ; de.tail!=de.head; ++
begin, ++de.head )
1827 if( de.child !=
NPtr() )
1830 if( de.head == de.tail )
1840 template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1841 template<
class OutIt>
1846 for( ; de.tail!=de.head; ++
begin, ++de.head )
1848 if( de.child !=
NPtr() )
1853 while( de.head != de.tail );
1861 template<
class Splitter,
class Pred,
class Refiller,
class Alloc>
1862 class special_<typename Alloc::pointer,2,Splitter,Pred,Refiller,Alloc>
1864 friend class merge_tree<typename Alloc::pointer,2,Splitter,Pred,Refiller,Alloc>;
1866 template<class FwIt>
1867 static FwIt fill(typename merge_tree<typename Alloc::pointer,2,Splitter,Pred,Refiller,Alloc>::NPtr root, FwIt begin, FwIt end, Pred comp)
1869 typedef typename merge_tree<typename Alloc::pointer,2,Splitter,Pred,Refiller,Alloc>::NPtr
NPtr;
1870 typedef typename merge_tree<typename Alloc::pointer,2,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
1873 if( root->edges[0].head != root->edges[0].tail )
1874 if( root->edges[1].head != root->edges[1].tail )
1875 for( TPtr l=root->edges[0].head, r=root->edges[1].head;; )
1879 root->edges[0].head = l;
1880 root->edges[1].head = r;
1885 *begin = *l, ++l, ++
begin;
1886 if( l == root->edges[0].tail )
1888 typename Node::Edge& de = root->edges[0];
1889 root->edges[0].head = l; root->edges[1].head = r;
1890 if( de.child != NPtr() )
1892 if( de.head == de.tail )
1894 l = root->edges[0].head;
1899 *begin = *r, ++r, ++
begin;
1900 if( r == root->edges[1].tail )
1902 typename Node::Edge& de = root->edges[1];
1903 root->edges[0].head = l; root->edges[1].head = r;
1904 if( de.child != NPtr() )
1906 if( de.head == de.tail )
1908 r = root->edges[1].head;
1914 else if( root->edges[1].head != root->edges[1].tail )
1920 template<
class OutIt>
1921 static OutIt fill(
typename merge_tree<typename Alloc::pointer,2,Splitter,Pred,Refiller,Alloc>::NPtr root, OutIt begin, Pred comp)
1923 typedef typename merge_tree<typename Alloc::pointer,2,Splitter,Pred,Refiller,Alloc>::NPtr
NPtr;
1924 typedef typename merge_tree<typename Alloc::pointer,2,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
1927 if( root->edges[0].head != root->edges[0].tail )
1928 if( root->edges[1].head != root->edges[1].tail )
1929 for( TPtr l=root->edges[0].head, r=root->edges[1].head;; )
1932 *begin = *l, ++l, ++
begin;
1933 if( l == root->edges[0].tail )
1935 typename Node::Edge& de = root->edges[0];
1936 root->edges[0].head = l; root->edges[1].head = r;
1937 if( de.child != NPtr() )
1939 if( de.head == de.tail )
1941 l = root->edges[0].head;
1946 *begin = *r, ++r, ++
begin;
1947 if( r == root->edges[1].tail )
1949 typename Node::Edge& de = root->edges[1];
1950 root->edges[0].head = l; root->edges[1].head = r;
1951 if( de.child != NPtr() )
1953 if( de.head == de.tail )
1955 r = root->edges[1].head;
1960 else if( root->edges[1].head != root->edges[1].tail )
1972 #define MOVE_SMALL_PTR(i,a) *begin = *head[i], ++head[i], ++begin; \ 1973 if( head[i] == tail[i] ) \ 1975 stream[i]->head = head[i]; \ 1976 if( stream[i]->child != NPtr() ) \ 1978 merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::go_down(*stream[i], comp); \ 1979 head[i] = stream[i]->head; tail[i] = stream[i]->tail; \ 1981 if( head[i] == tail[i] ) \ 1983 head[i] = head[a-1]; \ 1984 tail[i] = tail[a-1]; \ 1985 stream[i] = stream[a-1]; \ 1989 #define MOVE_SMALL_PTR_(i,a) *begin = *head[i], ++head[i], ++begin; \ 1990 if( head[i] == tail[i] ) \ 1991 if( go_down<i,a>(stream,head,tail,comp) ) \ 1994 template<
class Splitter,
class Pred,
class Refiller,
class Alloc>
1995 class special_<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>
1997 friend class merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>;
1999 template<int i, int a>
2000 static bool go_down(typename merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::Node::Edge** stream, typename merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::TPtr* head, typename merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::TPtr* tail, Pred comp)
2002 typedef typename merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::NPtr
NPtr;
2003 stream[i]->head = head[i];
2007 head[i] = stream[i]->head; tail[i] = stream[i]->tail;
2009 if( head[i] == tail[i] )
2011 head[i] = head[a-1];
2012 tail[i] = tail[a-1];
2013 stream[i] = stream[a-1];
2019 template<
class FwIt>
2020 static FwIt fill(
typename merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::NPtr n, FwIt begin, FwIt end, Pred comp)
2022 typedef typename merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::NPtr
NPtr;
2023 typedef typename merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
2025 TPtr head[4], tail[4];
2028 for( Edge *p=n->edges; p!=n->edges+4; ++p )
2029 if( p->head != p->tail )
2032 head[active] = p->
head, tail[active] = p->tail;
2043 stream[0]->head = head[0]; stream[1]->head = head[1]; stream[2]->head = head[2]; stream[3]->head = head[3];
2046 if( comp(*head[0],*head[3]) )
2048 if( comp(*head[0],*head[2]) )
2050 if( comp(*head[0],*head[1]) )
2061 if( comp(*head[1],*head[2]) )
2073 if( comp(*head[1],*head[3]) )
2075 if( comp(*head[1],*head[2]) )
2086 if( comp(*head[2],*head[3]) )
2102 stream[0]->head = head[0]; stream[1]->head = head[1]; stream[2]->head = head[2];
2105 if( comp(*head[0],*head[2]) )
2107 if( comp(*head[0],*head[1]) )
2118 if( comp(*head[1],*head[2]) )
2133 stream[0]->head = head[0]; stream[1]->head = head[1];
2136 if( comp(*head[0],*head[1]) )
2146 stream[0]->head = head[0];
2156 template<
class OutIt>
2157 static OutIt fill(
typename merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::NPtr n, OutIt begin, Pred comp)
2159 typedef typename merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::NPtr
NPtr;
2160 typedef typename merge_tree<typename Alloc::pointer,4,Splitter,Pred,Refiller,Alloc>::TPtr
TPtr;
2162 TPtr head[4], tail[4];
2165 for( Edge *p=n->edges; p!=n->edges+4; ++p )
2166 if( p->head != p->tail )
2169 head[active] = p->
head, tail[active] = p->tail;
2177 if( comp(*head[0],*head[3]) )
2179 if( comp(*head[0],*head[2]) )
2181 if( comp(*head[0],*head[1]) )
2192 if( comp(*head[1],*head[2]) )
2204 if( comp(*head[1],*head[3]) )
2206 if( comp(*head[1],*head[2]) )
2217 if( comp(*head[2],*head[3]) )
2229 if( comp(*head[0],*head[2]) )
2231 if( comp(*head[0],*head[1]) )
2242 if( comp(*head[1],*head[2]) )
2253 if( comp(*head[0],*head[1]) )
2262 stream[0]->head = head[0];
void destroy(allocator alloc, nallocator nalloc)
void child(basic_order_t ch)
std::iterator_traits< RanIt >::value_type value_type
unsigned short basic_order_t
void construct(order_t k, height_t height, size_t *buf_size, allocator alloc, nallocator nalloc)
#define MOVE_SMALL_PTR(i, a)
It operator()(It begin, It end)
allocator::template rebind< Node >::other::pointer child
allocator::template rebind< Node >::other nallocator
bool compare(const T &a, const T &b, std::false_type)