18#ifndef FUNNEL_H_INCLUDED__
19#define FUNNEL_H_INCLUDED__
40 for(
order_t i=k-1; i; h++, i/=order );
54 for( ; h; h--, k*=order );
78 { i = rhs.i;
return *
this; }
80 {
return i == rhs.i; }
82 {
return i != rhs.i; }
84 { i =
static_cast<order_t>(order*(i-1)+ch+2); }
86 { i =
static_cast<order_t>((i-2)/order+1); }
96 static const int alpha = 16;
98 template<
class diff_type>
100 {
return static_cast<order_t>(std::sqrt(
static_cast<double>(N)/alpha)); }
101 template<
class diff_type>
103 { assert(
false );
return static_cast<order_t>(std::sqrt(
static_cast<double>(N)/alpha)); }
105 {
return static_cast<size_t>(alpha*(order+1)*(order+1)); }
109 {
return static_cast<size_t>(alpha*k*k); }
112template<
class FwIt>
struct nop_refill {
template<
class Merger>
inline bool operator()(
const Merger*, FwIt, FwIt)
116template<
class,
int,
class,
class,
class,
class>
119template<
class RanIt,
int Order=2,
class Splitter = default_splitter<Order>,
class Pred = std::less<
typename std::iterator_traits<RanIt>::value_type>,
class Refiller = nop_refill<RanIt>,
class Alloc = std::allocator<
typename std::iterator_traits<RanIt>::value_type> >
122 friend class special_<RanIt,Order,Splitter,Pred,Refiller,Alloc>;
128 typedef typename std::iterator_traits<RanIt>::value_type
value_type;
132 template<
class NewRefiller>
137 typedef typename allocator::pointer TPtr;
138 typedef typename allocator::size_type size_type;
140 typedef typename nallocator::pointer NPtr;
145 typedef typename allocator::pointer
TPtr;
147 typedef typename nallocator::pointer
NPtr;
156 inline void destroy(
allocator alloc, nallocator nalloc);
158 typedef std::pair<RanIt,RanIt> stream_t;
160 typedef typename sallocator::pointer SPtr;
178 {
return pair->first; }
180 {
return pair->second; }
189 {
return static_cast<order_t>(ptr-rhs.ptr); }
193 { ++ptr;
return *
this; }
201 {
return ptr == rhs.ptr; }
203 {
return ptr != rhs.ptr; }
207 { *last_stream++ = std::make_pair(
begin,
end); }
220 {
return empty_buffers(root,
begin,
end); }
221 template<
class OutIt>
223 {
return empty_buffers(root,
begin); }
227 template<
class OutIt>
232 static inline FwIt empty_buffers(NPtr n, FwIt
begin, FwIt
end);
233 template<
class OutIt>
234 static inline OutIt empty_buffers(NPtr n, OutIt
begin);
236 static void compute_buffer_sizes(size_type *b, size_type *e);
248 template<
class OutIt>
254 inline FwIt fill_root(FwIt
begin, FwIt
end)
256 template<
class OutIt>
257 inline OutIt fill_root(OutIt
begin)
259 void fill(NPtr n,
typename Node::Edge&
output, bfs_index<order> index)
260 { special_<RanIt,order,Splitter,Pred,Refiller,Alloc>::fill(
this, n,
output, index); }
261 void fill_leaf(
typename Node::Edge&
output, bfs_index<order> index)
262 { special_<RanIt,order,Splitter,Pred,Refiller,Alloc>::fill_leaf(
this,
output, index); }
269 SPtr input_streams, last_stream;
283template<
int Order,
class Splitter,
class Pred,
class Refiller,
class Alloc>
284class merge_tree<typename Alloc::pointer, Order, Splitter, Pred, Refiller, Alloc>
286 typedef typename Alloc::pointer RanIt;
287 friend class special_<typename Alloc::pointer,Order,Splitter,Pred,Refiller,Alloc>;
293 typedef typename std::iterator_traits<typename Alloc::pointer>::value_type
value_type;
302 typedef typename allocator::pointer TPtr;
303 typedef typename allocator::size_type size_type;
304 typedef typename allocator::template rebind<Node>::other nallocator;
305 typedef typename nallocator::pointer NPtr;
310 typedef typename allocator::pointer
TPtr;
311 typedef typename allocator::template rebind<Node>::other
nallocator;
312 typedef typename nallocator::pointer
NPtr;
320 inline Edge** construct(
order_t k,
height_t height,
size_t *buf_size, Edge** edge_list,
allocator alloc, nallocator nalloc);
321 inline void destroy(
allocator alloc, nallocator nalloc);
323 typedef typename Node::Edge* stream_t;
324 typedef typename allocator::template rebind<stream_t>::other sallocator;
325 typedef typename sallocator::pointer SPtr;
341 inline stream(stream_t edge) : edge(edge) { }
342 inline typename allocator::pointer&
begin()
343 {
return edge->head; }
344 inline typename allocator::pointer&
end()
345 {
return edge->tail; }
347 class stream_iterator
354 {
return static_cast<order_t>(ptr-rhs.ptr); }
356 {
return stream(*ptr); }
358 { ++ptr;
return *
this; }
361 stream_iterator ret = stream_iterator(ptr);
366 {
return ptr == rhs.ptr; }
368 {
return ptr != rhs.ptr; }
372 { (*last_stream)->head =
begin, (*last_stream)->tail =
end, ++last_stream; }
374 {
return input_streams; }
375 inline stream_iterator
end()
376 {
return last_stream; }
385 {
return empty_buffers(root,
begin,
end); }
386 template<
class OutIt>
388 {
return empty_buffers(root,
begin); }
392 template<
class OutIt>
396 static inline FwIt empty_buffers(NPtr n, FwIt
begin, FwIt
end);
397 template<
class OutIt>
398 static inline OutIt empty_buffers(NPtr n, OutIt
begin);
401 static void compute_buffer_sizes(size_type *b, size_type *e);
403 static inline void go_down(
typename Node::Edge& e, Pred comp);
404 static inline void go_down_cold(
typename Node::Edge& e, Pred comp);
406 static void warmup(NPtr n,
typename Node::Edge&
output, Pred comp);
408 template<
class OutIt>
409 static inline OutIt copy(
typename Node::Edge& de, OutIt
begin, Pred comp);
411 static inline FwIt copy(
typename Node::Edge& de, FwIt
begin, FwIt
end, Pred comp, std::forward_iterator_tag);
413 static inline RIt copy(
typename Node::Edge& de, RIt
begin, RIt
end, Pred comp, std::random_access_iterator_tag);
415 template<
class OutIt>
416 static inline OutIt fill(NPtr n, OutIt
begin, Pred comp)
419 static inline FwIt fill(NPtr n, FwIt
begin, FwIt
end, Pred comp)
426 SPtr input_streams, last_stream;
void child(basic_order_t ch)
bfs_index< order > operator=(const bfs_index< order > &rhs)
bool operator!=(const bfs_index< order > &rhs) const
basic_order_t child_index() const
bool operator==(const bfs_index< order > &rhs) const
static order_t prefered_order_input(diff_type N)
static height_t split(height_t h)
static order_t prefered_order_output(diff_type N)
static size_t out_buffer_size(order_t k)
static size_t switch_to_cache_aware()
stream_iterator(SPtr ptr)
bool operator==(const stream_iterator &rhs)
stream_iterator & operator++(int)
stream_iterator & operator++()
order_t operator-(const stream_iterator &rhs)
bool operator!=(const stream_iterator &rhs)
bool operator!=(const stream_iterator &rhs)
bool operator==(const stream_iterator &rhs)
order_t operator-(const stream_iterator &rhs)
stream_iterator & operator++(int)
stream_iterator & operator++()
stream_iterator(SPtr ptr)
allocator::pointer & begin()
allocator::pointer & end()
void add_stream(typename Alloc::pointer begin, typename Alloc::pointer end)
static order_t min_order()
const Refiller & get_refiller() const
void set_refiller(const Refiller &r)
FwIt operator()(FwIt begin, FwIt end)
OutIt operator()(OutIt begin)
FwIt empty(FwIt begin, FwIt end)
std::iterator_traits< typenameAlloc::pointer >::value_type value_type
merge_tree(order_t k, const allocator &alloc)
const Refiller & get_refiller() const
It operator()(It begin, It end)
merge_tree(order_t k, const allocator &alloc)
FwIt empty(FwIt begin, FwIt end)
void add_stream(RanIt begin, RanIt end)
static order_t min_order()
void set_refiller(const Refiller &r)
std::iterator_traits< RanIt >::value_type value_type
order_t pow_of_order< 16 >(height_t h)
order_t pow_of_order< 8 >(height_t h)
unsigned short basic_order_t
order_t pow_of_order< 2 >(height_t h)
order_t pow_of_order< 4 >(height_t h)
order_t pow_of_order(height_t h)
allocator::template rebind< Node >::other::pointer child
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)
merge_tree< iterator, order, splitter, predicate, NewRefiller, allocator > other
nallocator::pointer child
allocator::template rebind< Node >::other nallocator
void destroy(allocator alloc, nallocator nalloc)
Edge ** construct(order_t k, height_t height, size_t *buf_size, Edge **edge_list, allocator alloc, nallocator nalloc)
bool operator()(const Merger *, FwIt, FwIt)