Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * containers/test_ext_merger2.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright © 2008, 2009 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00007 * 00008 * Distributed under the Boost Software License, Version 1.0. 00009 * (See accompanying file LICENSE_1_0.txt or copy at 00010 * http://www.boost.org/LICENSE_1_0.txt) 00011 **************************************************************************/ 00012 00013 #include <limits> 00014 #include <iterator> 00015 #include <stxxl/priority_queue> 00016 00017 typedef int my_type; 00018 typedef stxxl::typed_block<4096, my_type> block_type; 00019 00020 00021 struct dummy_merger 00022 { 00023 int current, delta; 00024 dummy_merger() : current(0), delta(1) { } 00025 void operator () (int current_, int delta_) 00026 { 00027 current = current_; 00028 delta = delta_; 00029 } 00030 template <class OutputIterator> 00031 void multi_merge(OutputIterator b, OutputIterator e) 00032 { 00033 while (b != e) 00034 { 00035 *b = current; 00036 ++b; 00037 current += delta; 00038 } 00039 } 00040 }; 00041 00042 struct my_cmp : public std::greater<my_type> 00043 { 00044 my_type min_value() const 00045 { 00046 return (std::numeric_limits<my_type>::max)(); 00047 } 00048 }; 00049 00050 my_type * make_sequence(dummy_merger & dummy, int l) 00051 { 00052 my_type * seq = new my_type[l + 1]; // + sentinel 00053 dummy.multi_merge(seq, seq + l); 00054 seq[l] = my_cmp().min_value(); // sentinel 00055 return seq; 00056 } 00057 00058 int main() 00059 { 00060 stxxl::config::get_instance(); 00061 const int B = block_type::size; 00062 dummy_merger dummy; 00063 00064 if (1) { 00065 const unsigned volume = 3 * 1024 * 1024; // in KiB 00066 const unsigned mem_for_queue = 256 * 1024 * 1024; 00067 typedef stxxl::PRIORITY_QUEUE_GENERATOR<my_type, my_cmp, mem_for_queue, volume / sizeof(my_type)>::result pq_type; 00068 pq_type pq(mem_for_queue, mem_for_queue); 00069 pq.push(42); 00070 assert(pq.top() == 42); 00071 pq.pop(); 00072 pq.push(2); 00073 pq.push(0); 00074 pq.push(3); 00075 pq.push(1); 00076 my_type x0, x1, x2, x3; 00077 x0 = pq.top(); 00078 pq.pop(); 00079 x1 = pq.top(); 00080 pq.pop(); 00081 x2 = pq.top(); 00082 pq.pop(); 00083 x3 = pq.top(); 00084 pq.pop(); 00085 STXXL_MSG("Order: " << x0 << " " << x1 << " " << x2 << " " << x3); 00086 assert(pq.empty()); 00087 } 00088 00089 if (1) { // ext_merger test 00090 stxxl::read_write_pool<block_type> pool(1, 2); 00091 stxxl::priority_queue_local::ext_merger<block_type, my_cmp, 5> merger(&pool); 00092 dummy(1, 0); 00093 merger.insert_segment(dummy, B * 2); 00094 dummy(2, 0); 00095 merger.insert_segment(dummy, B * 2); 00096 dummy(B, 1); 00097 merger.insert_segment(dummy, B * 4); 00098 dummy(B, 2); 00099 merger.insert_segment(dummy, B * 4); 00100 dummy(B, 4); 00101 merger.insert_segment(dummy, B * 4); 00102 00103 std::vector<my_type> output(B * 3); 00104 00105 // zero length merge 00106 merger.multi_merge(output.begin(), output.begin()); 00107 merger.multi_merge(output.begin(), output.begin()); 00108 merger.multi_merge(output.begin(), output.begin()); 00109 00110 while (merger.size() > 0) { 00111 int l = std::min<stxxl::uint64>(merger.size(), output.size()); 00112 merger.multi_merge(output.begin(), output.begin() + l); 00113 STXXL_MSG("merged " << l << " elements: (" << *output.begin() << ", ..., " << *(output.begin() + l - 1) << ")"); 00114 } 00115 00116 // zero length merge on empty data structure 00117 merger.multi_merge(output.begin(), output.begin()); 00118 merger.multi_merge(output.begin(), output.begin()); 00119 merger.multi_merge(output.begin(), output.begin()); 00120 } // ext_merger test 00121 00122 if (1) { // loser_tree test 00123 stxxl::priority_queue_local::loser_tree<my_type, my_cmp, 8> loser; 00124 dummy(1, 0); 00125 my_type * seq0 = make_sequence(dummy, 2 * B); 00126 dummy(2, 0); 00127 my_type * seq1 = make_sequence(dummy, 2 * B); 00128 dummy(B, 1); 00129 my_type * seq2 = make_sequence(dummy, 4 * B); 00130 dummy(B, 2); 00131 my_type * seq3 = make_sequence(dummy, 4 * B); 00132 dummy(2 * B, 1); 00133 my_type * seq4 = make_sequence(dummy, 4 * B); 00134 dummy(B, 4); 00135 my_type * seq5 = make_sequence(dummy, 4 * B); 00136 dummy(B, 8); 00137 my_type * seq6 = make_sequence(dummy, 4 * B); 00138 dummy(2 * B, 2); 00139 my_type * seq7 = make_sequence(dummy, 4 * B); 00140 00141 loser.init(); 00142 loser.insert_segment(seq0, 2 * B); 00143 loser.insert_segment(seq1, 2 * B); 00144 loser.insert_segment(seq2, 4 * B); 00145 loser.insert_segment(seq3, 4 * B); 00146 loser.insert_segment(seq4, 4 * B); 00147 if (0) { 00148 loser.insert_segment(seq5, 4 * B); 00149 loser.insert_segment(seq6, 4 * B); 00150 loser.insert_segment(seq7, 4 * B); 00151 } else { 00152 delete[] seq5; 00153 delete[] seq6; 00154 delete[] seq7; 00155 } 00156 00157 my_type * out = new my_type[2 * B]; 00158 00159 // zero length merge 00160 loser.multi_merge(out, out); 00161 loser.multi_merge(out, out); 00162 loser.multi_merge(out, out); 00163 00164 while (loser.size() > 0) { 00165 int l = std::min<stxxl::uint64>(loser.size(), B + B / 2 + 1); 00166 loser.multi_merge(out, out + l); 00167 STXXL_MSG("merged " << l << " elements: (" << out[0] << ", ..., " << out[l - 1] << ")"); 00168 } 00169 00170 // zero length merge on empty data structure 00171 loser.multi_merge(out, out); 00172 loser.multi_merge(out, out); 00173 loser.multi_merge(out, out); 00174 00175 delete[] out; 00176 } // loser_tree test 00177 } 00178 00179 // vim: et:ts=4:sw=4