Stxxl  1.4.0
include/stxxl/bits/algo/sort_helper.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  *  include/stxxl/bits/algo/sort_helper.h
00003  *
00004  *  Part of the STXXL. See http://stxxl.sourceforge.net
00005  *
00006  *  Copyright (C) 2002-2003 Roman Dementiev <dementiev@mpi-sb.mpg.de>
00007  *  Copyright (C) 2009, 2010 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
00008  *
00009  *  Distributed under the Boost Software License, Version 1.0.
00010  *  (See accompanying file LICENSE_1_0.txt or copy at
00011  *  http://www.boost.org/LICENSE_1_0.txt)
00012  **************************************************************************/
00013 
00014 #ifndef STXXL_SORT_HELPER_HEADER
00015 #define STXXL_SORT_HELPER_HEADER
00016 
00017 #include <algorithm>
00018 #include <functional>
00019 #include <stxxl/bits/algo/run_cursor.h>
00020 #include <stxxl/bits/verbose.h>
00021 
00022 
00023 __STXXL_BEGIN_NAMESPACE
00024 
00025 //! \internal
00026 namespace sort_helper
00027 {
00028     template <typename StrictWeakOrdering>
00029     inline void verify_sentinel_strict_weak_ordering(StrictWeakOrdering cmp)
00030     {
00031         assert(!cmp(cmp.min_value(), cmp.min_value()));
00032         assert(cmp(cmp.min_value(), cmp.max_value()));
00033         assert(!cmp(cmp.max_value(), cmp.min_value()));
00034         assert(!cmp(cmp.max_value(), cmp.max_value()));
00035         STXXL_UNUSED(cmp);
00036     }
00037 
00038     template <typename BlockTp_, typename ValTp_ = typename BlockTp_::value_type>
00039     struct trigger_entry
00040     {
00041         typedef BlockTp_ block_type;
00042         typedef typename block_type::bid_type bid_type;
00043         typedef ValTp_ value_type;
00044 
00045         bid_type bid;
00046         value_type value;
00047 
00048         operator bid_type ()
00049         {
00050             return bid;
00051         }
00052     };
00053 
00054     template <typename TriggerEntryTp_, typename ValueCmp_>
00055     struct trigger_entry_cmp : public std::binary_function<TriggerEntryTp_, TriggerEntryTp_, bool>
00056     {
00057         typedef TriggerEntryTp_ trigger_entry_type;
00058         ValueCmp_ cmp;
00059         trigger_entry_cmp(ValueCmp_ c) : cmp(c) { }
00060         trigger_entry_cmp(const trigger_entry_cmp & a) : cmp(a.cmp) { }
00061         bool operator () (const trigger_entry_type & a, const trigger_entry_type & b) const
00062         {
00063             return cmp(a.value, b.value);
00064         }
00065     };
00066 
00067     template <typename block_type,
00068               typename prefetcher_type,
00069               typename value_cmp>
00070     struct run_cursor2_cmp : public std::binary_function<run_cursor2<block_type, prefetcher_type>, run_cursor2<block_type, prefetcher_type>, bool>
00071     {
00072         typedef run_cursor2<block_type, prefetcher_type> cursor_type;
00073         value_cmp cmp;
00074 
00075         run_cursor2_cmp(value_cmp c) : cmp(c) { }
00076         run_cursor2_cmp(const run_cursor2_cmp & a) : cmp(a.cmp) { }
00077         inline bool operator () (const cursor_type & a, const cursor_type & b) const
00078         {
00079             if (UNLIKELY(b.empty()))
00080                 return true;
00081             // sentinel emulation
00082             if (UNLIKELY(a.empty()))
00083                 return false;
00084             // sentinel emulation
00085 
00086             return (cmp(a.current(), b.current()));
00087         }
00088     };
00089 
00090     // this function is used by parallel mergers
00091     template <typename SequenceVector, typename ValueType, typename Comparator>
00092     inline
00093     unsigned_type count_elements_less_equal(const SequenceVector & seqs, const ValueType & bound, Comparator cmp)
00094     {
00095         typedef typename SequenceVector::size_type seqs_size_type;
00096         typedef typename SequenceVector::value_type::first_type iterator;
00097         unsigned_type count = 0;
00098 
00099         for (seqs_size_type i = 0; i < seqs.size(); ++i)
00100         {
00101             iterator position = std::upper_bound(seqs[i].first, seqs[i].second, bound, cmp);
00102             STXXL_VERBOSE1("less equal than " << position - seqs[i].first);
00103             count += position - seqs[i].first;
00104         }
00105         STXXL_VERBOSE1("finished loop");
00106         return count;
00107     }
00108 
00109     // this function is used by parallel mergers
00110     template <typename SequenceVector, typename BufferPtrVector, typename Prefetcher>
00111     inline
00112     void refill_or_remove_empty_sequences(SequenceVector & seqs,
00113                                           BufferPtrVector & buffers,
00114                                           Prefetcher & prefetcher)
00115     {
00116         typedef typename SequenceVector::size_type seqs_size_type;
00117 
00118         for (seqs_size_type i = 0; i < seqs.size(); ++i)
00119         {
00120             if (seqs[i].first == seqs[i].second)                // run empty
00121             {
00122                 if (prefetcher.block_consumed(buffers[i]))
00123                 {
00124                     seqs[i].first = buffers[i]->begin();        // reset iterator
00125                     seqs[i].second = buffers[i]->end();
00126                     STXXL_VERBOSE1("block ran empty " << i);
00127                 }
00128                 else
00129                 {
00130                     seqs.erase(seqs.begin() + i);               // remove this sequence
00131                     buffers.erase(buffers.begin() + i);
00132                     STXXL_VERBOSE1("seq removed " << i);
00133                     --i;                                        // don't skip the next sequence
00134                 }
00135             }
00136         }
00137     }
00138 }
00139 
00140 __STXXL_END_NAMESPACE
00141 
00142 #endif // !STXXL_SORT_HELPER_HEADER
00143 // vim: et:ts=4:sw=4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines