Stxxl  1.4.0
stream/test_stream.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines