Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * stream/test_stream.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2003 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00007 * Copyright (C) 2007 Andreas Beckmann <beckmann@mpi-inf.mpg.de> 00008 * Copyright (C) 2009, 2010 Johannes Singler <singler@kit.edu> 00009 * 00010 * Distributed under the Boost Software License, Version 1.0. 00011 * (See accompanying file LICENSE_1_0.txt or copy at 00012 * http://www.boost.org/LICENSE_1_0.txt) 00013 **************************************************************************/ 00014 00015 //! \example stream/test_stream.cpp 00016 //! This is an example of how to use some basic algorithms from the 00017 //! stream package. The example sorts characters of a string producing an 00018 //! array of sorted tuples (character, index position). 00019 00020 #include <limits> 00021 #include <vector> 00022 #include <stxxl/stream> 00023 #include <stxxl/vector> 00024 00025 00026 #define USE_FORMRUNS_N_MERGE // comment if you want to use one 'sort' algorithm 00027 // without producing intermediate sorted runs. 00028 00029 #define USE_EXTERNAL_ARRAY // comment if you want to use internal vectors as 00030 // input/output of the algorithm 00031 00032 #define block_size (8 * 1024) 00033 00034 typedef stxxl::tuple<char, int> tuple_type; 00035 00036 namespace std 00037 { 00038 std::ostream & operator << (std::ostream & os, const tuple_type & t) 00039 { 00040 os << "<" << t.first << "," << t.second << ">"; 00041 return os; 00042 } 00043 } 00044 00045 #ifdef USE_EXTERNAL_ARRAY 00046 typedef stxxl::VECTOR_GENERATOR<char>::result input_array_type; 00047 typedef stxxl::VECTOR_GENERATOR<tuple_type>::result output_array_type; 00048 #else 00049 typedef std::vector<char> input_array_type; 00050 typedef std::vector<tuple_type> output_array_type; 00051 #endif 00052 00053 using stxxl::stream::streamify; 00054 using stxxl::stream::streamify_traits; 00055 using stxxl::stream::make_tuple; 00056 using stxxl::tuple; 00057 00058 00059 const char * phrase = "Hasta la vista, baby"; 00060 00061 00062 template <class Container_, class It_> 00063 void fill_input_array(Container_ & container, It_ p) 00064 { 00065 while (*p) 00066 { 00067 container.push_back(*p); 00068 ++p; 00069 } 00070 } 00071 00072 template <class ValTp> 00073 struct counter 00074 { 00075 typedef ValTp value_type; 00076 00077 value_type cnt; 00078 counter() : cnt(0) { } 00079 00080 value_type operator () () 00081 { 00082 value_type ret = cnt; 00083 ++cnt; 00084 return ret; 00085 } 00086 }; 00087 00088 typedef counter<int> counter_type; 00089 00090 struct cmp_type : std::binary_function<tuple_type, tuple_type, bool> 00091 { 00092 typedef tuple_type value_type; 00093 bool operator () (const value_type & a, const value_type & b) const 00094 { 00095 return a.first < b.first; 00096 } 00097 00098 value_type min_value() const 00099 { 00100 return value_type((std::numeric_limits<char>::min)(), 0); 00101 } 00102 value_type max_value() const 00103 { 00104 return value_type((std::numeric_limits<char>::max)(), 0); 00105 } 00106 }; 00107 00108 struct cmp_int : std::binary_function<int, int, bool> 00109 { 00110 typedef int value_type; 00111 bool operator () (const value_type & a, const value_type & b) const 00112 { 00113 return a > b; 00114 } 00115 00116 value_type max_value() const 00117 { 00118 return (((std::numeric_limits<value_type>::min))()); 00119 } 00120 value_type min_value() const 00121 { 00122 return (((std::numeric_limits<value_type>::max))()); 00123 } 00124 }; 00125 00126 template <typename T> 00127 struct identity : std::unary_function<T, T> 00128 { 00129 typedef T value_type; 00130 00131 const T & operator () (const T & t) 00132 { 00133 return t; 00134 } 00135 }; 00136 00137 int main() 00138 { 00139 input_array_type input; 00140 output_array_type output; 00141 00142 stxxl::stats * s = stxxl::stats::get_instance(); 00143 00144 std::cout << *s; 00145 00146 fill_input_array(input, phrase); 00147 00148 output.resize(input.size()); 00149 00150 // HERE streaming part begins (streamifying) 00151 // create input stream 00152 #ifdef BOOST_MSVC 00153 typedef streamify_traits<input_array_type::iterator>::stream_type input_stream_type; 00154 #else 00155 typedef __typeof__(streamify(input.begin(), input.end())) input_stream_type; 00156 #endif 00157 00158 input_stream_type input_stream = streamify(input.begin(), input.end()); 00159 00160 00161 // create counter stream 00162 #ifdef BOOST_MSVC 00163 typedef stxxl::stream::generator2stream<counter_type> counter_stream_type; 00164 #else 00165 typedef __typeof__(streamify(counter_type())) counter_stream_type; 00166 #endif 00167 counter_stream_type counter_stream = streamify(counter_type()); 00168 00169 // create tuple stream 00170 typedef make_tuple<input_stream_type, counter_stream_type> tuple_stream_type; 00171 tuple_stream_type tuple_stream(input_stream, counter_stream); 00172 00173 const stxxl::unsigned_type sorter_memory = 128 * 1024; 00174 #ifdef USE_FORMRUNS_N_MERGE 00175 // sort tuples by character 00176 // 1. form runs 00177 typedef stxxl::stream::runs_creator<tuple_stream_type, cmp_type, block_size> runs_creator_stream_type; 00178 runs_creator_stream_type runs_creator_stream(tuple_stream, cmp_type(), sorter_memory); 00179 // 2. merge runs 00180 typedef stxxl::stream::runs_merger<runs_creator_stream_type::sorted_runs_type, cmp_type> sorted_stream_type; 00181 sorted_stream_type sorted_stream(runs_creator_stream.result(), cmp_type(), sorter_memory); 00182 #else 00183 // sort tuples by character 00184 // (combination of the previous two steps in one algorithm: form runs and merge) 00185 typedef stxxl::stream::sort<tuple_stream_type, cmp_type, block_size> sorted_stream_type; 00186 sorted_stream_type sorted_stream(tuple_stream, cmp_type(), sorter_memory); 00187 #endif 00188 00189 typedef stxxl::stream::transform<identity<stxxl::tuple<char, int> >, sorted_stream_type> transformed_stream_type; 00190 identity<stxxl::tuple<char, int> > id; 00191 transformed_stream_type transformed_stream(id, sorted_stream); 00192 00193 // HERE streaming part ends (materializing) 00194 output_array_type::iterator o = stxxl::stream::materialize(transformed_stream, output.begin(), output.end()); 00195 // or materialize(sorted_stream,output.begin()); 00196 assert(o == output.end()); 00197 00198 00199 STXXL_MSG("input string (character,position) :"); 00200 for (unsigned i = 0; i < input.size(); ++i) 00201 { 00202 STXXL_MSG("('" << input[i] << "'," << i << ")"); 00203 } 00204 STXXL_MSG("sorted tuples (character,position):"); 00205 for (unsigned i = 0; i < input.size(); ++i) 00206 { 00207 STXXL_MSG("('" << output[i].first << "'," << output[i].second << ")"); 00208 } 00209 00210 std::cout << *s; 00211 00212 std::vector<int> InternalArray(1024 * 1024); 00213 std::sort(InternalArray.begin(), InternalArray.end(), cmp_int()); 00214 //convenience function based on streaming 00215 stxxl::sort<1024 * 1024>(InternalArray.begin(), InternalArray.end(), 00216 cmp_int(), 1024 * 1024 * 31, stxxl::RC()); 00217 00218 return 0; 00219 }