22template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
23void 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);
45template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
46void merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::Node::construct(
order_t k,
height_t height,
size_t *buf_size,
allocator alloc, nallocator nalloc)
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);
80template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
83 begin = alloc.allocate(*buf_size);
91 child = nalloc.allocate(1);
94 nalloc.construct(child, Node());
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);
119template<
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);
127template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
130 if( child !=
NPtr() )
132 child->destroy(alloc,nalloc);
133 nalloc.destroy(child);
134 nalloc.deallocate(child,1);
146template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
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)));
158template<
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);
216template<
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);
229template<
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;
245template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
255 go_down_cold(root->edges[i],index);
262template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
272 go_down_cold(root->edges[i],index);
276 return fill_root(
begin);
279template<
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 )
293template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
295OutIt merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::empty_buffers(NPtr n, OutIt
begin)
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);
306template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
307void merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::go_down(
typename Node::Edge& e, bfs_index<order> index)
309 assert( e.tail == e.head );
311 if( e.child == NPtr() )
314 fill(e.child,e,index);
315 e.tail = e.head, e.head = e.begin;
319template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
320void merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::go_down_cold(
typename Node::Edge& e, bfs_index<order>& index)
322 e.tail = e.end, e.head = e.begin;
324 warmup(e.child, e, index);
325 else if( leaf_index <= index && input_streams+
order*(index-leaf_index) < last_stream )
327 e.tail = e.head, e.head = e.begin;
331template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
332void merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::warmup(NPtr n,
typename Node::Edge&
output, bfs_index<order> index)
337 go_down_cold(n->edges[i],index);
342template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
344FwIt merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::copy_root(
typename Node::Edge& de, bfs_index<order> index, FwIt
begin, FwIt
end, std::forward_iterator_tag)
350 if( de.tail == de.head )
353 if( de.head == de.tail )
361template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
363RIt merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::copy_root(
typename Node::Edge& de, bfs_index<order> index, RIt
begin, RIt
end, std::random_access_iterator_tag)
369 if( de.tail == de.head )
372 if( de.head == de.tail )
380template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
382OutIt merge_tree<RanIt,order,Splitter,Pred,Refiller,Alloc>::copy_root(
typename Node::Edge& de, bfs_index<order> index, OutIt
begin)
386 for( ; de.tail!=de.head; ++
begin, ++de.head )
390 while( de.head != de.tail );
394template<
class RanIt,
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
395typename 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)
399 if( e-b < de.tail-de.head )
401 for( ; b!=e; ++b, ++de.head )
407 for( ; de.tail!=de.head; ++b, ++de.head )
410 if( de.head == de.tail )
421template<
class RanIt,
class Splitter,
class Pred,
class Refiller,
class Alloc>
422class 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;; )
554 n->edges[0].head = l;
555 n->edges[1].head = r;
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;
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;
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() )
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) ) \
787template<
class RanIt,
class Splitter,
class Pred,
class Refiller,
class Alloc>
788class 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];
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];
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];
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];
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;
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];
1482template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1483void merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::Node::Edge::fill_dflt(TPtr b, TPtr e,
allocator alloc)
1490 alloc.construct(p,dflt);
1496 for( --p; p!=b; --p )
1500 alloc.deallocate(b,e-b);
1505template<
int Order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1506typename 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 )
1524 edges[i].child = NPtr();
1525 edges[i].begin = edges[i].end = TPtr();
1534 edges[i].destroy(alloc, nalloc);
1535 edges[i].destroy(alloc, nalloc);
1541template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1542typename 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;
1553 child = nalloc.allocate(1);
1556 nalloc.construct(child,
Node());
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();
1587template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1588void merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::Node::destroy(
allocator alloc, nallocator nalloc)
1590 for(
int i=0; i!=
order; ++i )
1591 edges[i].destroy(alloc, nalloc);
1595template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1598 if( child != NPtr() )
1600 child->destroy(alloc,nalloc);
1601 nalloc.destroy(child);
1602 nalloc.deallocate(child,1);
1604 if(
begin != TPtr() )
1613template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1614void merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::compute_buffer_sizes(size_type *b, size_type *e)
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)));
1625template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1626void merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::construct(
order_t k)
1629 throw std::invalid_argument(
"Merge tree too small");
1632 throw std::invalid_argument(
"Merge tree too high");
1633 bfs_index<order> bfs;
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);
1682template<
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);
1693template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1697 last_stream = input_streams;
1700template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
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);
1712template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1713template<
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);
1724template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1726FwIt merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::empty_buffers(NPtr n, FwIt
begin, FwIt
end)
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 )
1738template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1739template<
class OutIt>
1740OutIt merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::empty_buffers(NPtr n, OutIt
begin)
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);
1751template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1752void merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::go_down(
typename Node::Edge& e, Pred comp)
1754 assert( e.tail == e.head );
1755 assert( e.child != NPtr() );
1756 e.tail = fill(e.child, e.begin, e.tail, comp);
1760template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1761void merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::go_down_cold(
typename Node::Edge& e, Pred comp)
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;
1769template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1770void merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::warmup(NPtr n,
typename Node::Edge&
output, Pred comp)
1772 for(
int i=0; i!=
order; ++i )
1773 if( n->edges[i].child != NPtr() )
1774 go_down_cold(n->edges[i], comp);
1778template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1780FwIt merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::copy(
typename Node::Edge& de, FwIt
begin, FwIt
end, Pred comp, std::forward_iterator_tag)
1786 if( de.tail == de.head && de.child != NPtr() )
1789 if( de.head == de.tail )
1797template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1799RIt merge_tree<typename Alloc::pointer,order,Splitter,Pred,Refiller,Alloc>::copy(
typename Node::Edge& de, RIt
begin, RIt
end, Pred comp, std::random_access_iterator_tag)
1825 for( ; de.tail!=de.head; ++
begin, ++de.head )
1827 if( de.child != NPtr() )
1830 if( de.head == de.tail )
1840template<
int order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
1841template<
class OutIt>
1846 for( ; de.tail!=de.head; ++
begin, ++de.head )
1848 if( de.child != NPtr() )
1853 while( de.head != de.tail );
1861template<
class Splitter,
class Pred,
class Refiller,
class Alloc>
1862class 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) ) \
1994template<
class Splitter,
class Pred,
class Refiller,
class Alloc>
1995class 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];
2004 if( stream[i]->child != NPtr() )
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];
int compare(const void *arg, const void *obj)
void child(basic_order_t ch)
It operator()(It begin, It end)
std::iterator_traits< RanIt >::value_type value_type
#define MOVE_SMALL_PTR(i, a)
unsigned short basic_order_t
void construct(order_t k, height_t height, size_t *buf_size, allocator alloc, nallocator nalloc)
allocator::template rebind< Node >::other nallocator
void destroy(allocator alloc, nallocator nalloc)