Stxxl  1.3.2
sort_helper.h
1 /***************************************************************************
2  * include/stxxl/bits/algo/sort_helper.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2002-2003 Roman Dementiev <[email protected]>
7  * Copyright (C) 2009, 2010 Andreas Beckmann <[email protected]>
8  *
9  * Distributed under the Boost Software License, Version 1.0.
10  * (See accompanying file LICENSE_1_0.txt or copy at
11  * http://www.boost.org/LICENSE_1_0.txt)
12  **************************************************************************/
13 
14 #ifndef STXXL_SORT_HELPER_HEADER
15 #define STXXL_SORT_HELPER_HEADER
16 
17 #include <algorithm>
18 #include <functional>
19 #include <stxxl/bits/algo/run_cursor.h>
20 #include <stxxl/bits/verbose.h>
21 
22 
23 __STXXL_BEGIN_NAMESPACE
24 
26 namespace sort_helper
27 {
28  template <typename StrictWeakOrdering>
29  inline void verify_sentinel_strict_weak_ordering(StrictWeakOrdering cmp)
30  {
31  assert(!cmp(cmp.min_value(), cmp.min_value()));
32  assert(cmp(cmp.min_value(), cmp.max_value()));
33  assert(!cmp(cmp.max_value(), cmp.min_value()));
34  assert(!cmp(cmp.max_value(), cmp.max_value()));
35  STXXL_UNUSED(cmp);
36  }
37 
38  template <typename BlockTp_, typename ValTp_ = typename BlockTp_::value_type>
39  struct trigger_entry
40  {
41  typedef BlockTp_ block_type;
42  typedef typename block_type::bid_type bid_type;
43  typedef ValTp_ value_type;
44 
45  bid_type bid;
46  value_type value;
47 
48  operator bid_type ()
49  {
50  return bid;
51  }
52  };
53 
54  template <typename TriggerEntryTp_, typename ValueCmp_>
55  struct trigger_entry_cmp : public std::binary_function<TriggerEntryTp_, TriggerEntryTp_, bool>
56  {
57  typedef TriggerEntryTp_ trigger_entry_type;
58  ValueCmp_ cmp;
59  trigger_entry_cmp(ValueCmp_ c) : cmp(c) { }
60  trigger_entry_cmp(const trigger_entry_cmp & a) : cmp(a.cmp) { }
61  bool operator () (const trigger_entry_type & a, const trigger_entry_type & b) const
62  {
63  return cmp(a.value, b.value);
64  }
65  };
66 
67  template <typename block_type,
68  typename prefetcher_type,
69  typename value_cmp>
70  struct run_cursor2_cmp : public std::binary_function<run_cursor2<block_type, prefetcher_type>, run_cursor2<block_type, prefetcher_type>, bool>
71  {
72  typedef run_cursor2<block_type, prefetcher_type> cursor_type;
73  value_cmp cmp;
74 
75  run_cursor2_cmp(value_cmp c) : cmp(c) { }
76  run_cursor2_cmp(const run_cursor2_cmp & a) : cmp(a.cmp) { }
77  inline bool operator () (const cursor_type & a, const cursor_type & b) const
78  {
79  if (UNLIKELY(b.empty()))
80  return true;
81  // sentinel emulation
82  if (UNLIKELY(a.empty()))
83  return false;
84  // sentinel emulation
85 
86  return (cmp(a.current(), b.current()));
87  }
88  };
89 
90  // this function is used by parallel mergers
91  template <typename SequenceVector, typename ValueType, typename Comparator>
92  inline
93  unsigned_type count_elements_less_equal(const SequenceVector & seqs, const ValueType & bound, Comparator cmp)
94  {
95  typedef typename SequenceVector::size_type seqs_size_type;
96  typedef typename SequenceVector::value_type::first_type iterator;
97  unsigned_type count = 0;
98 
99  for (seqs_size_type i = 0; i < seqs.size(); ++i)
100  {
101  iterator position = std::upper_bound(seqs[i].first, seqs[i].second, bound, cmp);
102  STXXL_VERBOSE1("less equal than " << position - seqs[i].first);
103  count += position - seqs[i].first;
104  }
105  STXXL_VERBOSE1("finished loop");
106  return count;
107  }
108 
109  // this function is used by parallel mergers
110  template <typename SequenceVector, typename BufferPtrVector, typename Prefetcher>
111  inline
112  void refill_or_remove_empty_sequences(SequenceVector & seqs,
113  BufferPtrVector & buffers,
114  Prefetcher & prefetcher)
115  {
116  typedef typename SequenceVector::size_type seqs_size_type;
117 
118  for (seqs_size_type i = 0; i < seqs.size(); ++i)
119  {
120  if (seqs[i].first == seqs[i].second) // run empty
121  {
122  if (prefetcher.block_consumed(buffers[i]))
123  {
124  seqs[i].first = buffers[i]->begin(); // reset iterator
125  seqs[i].second = buffers[i]->end();
126  STXXL_VERBOSE1("block ran empty " << i);
127  }
128  else
129  {
130  seqs.erase(seqs.begin() + i); // remove this sequence
131  buffers.erase(buffers.begin() + i);
132  STXXL_VERBOSE1("seq removed " << i);
133  --i; // don't skip the next sequence
134  }
135  }
136  }
137  }
138 }
139 
140 __STXXL_END_NAMESPACE
141 
142 #endif // !STXXL_SORT_HELPER_HEADER
143 // vim: et:ts=4:sw=4