ug4
bucket_sorter.hpp
Go to the documentation of this file.
1 // Felix Salfelder, 2016-2017, 2021
2 //
3 // This program is free software; you can redistribute it and/or modify it
4 // under the terms of the GNU General Public License as published by the
5 // Free Software Foundation; either version 3, or (at your option) any
6 // later version.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA.
16 //
17 //
18 // // contains code from boost/graph
19 // //=======================================================================
20 // // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
21 // // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
22 // //
23 // // Distributed under the Boost Software License, Version 1.0. (See
24 // // accompanying file LICENSE_1_0.txt or copy at
25 // // http://www.boost.org/LICENSE_1_0.txt)
26 // //=======================================================================
27 #ifndef TREEDEC_BUCKET_SORTER_HPP
28 #define TREEDEC_BUCKET_SORTER_HPP
29 
30 // avoid including the the other one
31 #define BOOST_GRAPH_DETAIL_BUCKET_SORTER_HPP
32 
33 #include <vector>
34 #include <cassert>
35 //#include <boost/limits.hpp>
36 #include "trace.h"
37 
38 // the __FreeBSD__ condition is a wild guess.
39 #if defined(BOOST_CLANG) && (1 == BOOST_CLANG) && defined(__FreeBSD__)
40 #define ITERATOR_CONSTRUCTOR_WORKAROUND
41 #endif
42 
43 namespace boost {
44 
45  template <class BucketType, class ValueType, class Bucket,
46  class ValueIndexMap>
47  class bucket_sorter {
48  public:
49  typedef BucketType bucket_type;
50  typedef ValueType value_type;
51  typedef Bucket Bucket_type;
52  typedef ValueIndexMap value_index_map;
53  typedef typename std::vector<value_type>::size_type size_type;
54 
55  bucket_sorter(size_type _length, bucket_type _max_bucket,
56  const Bucket& _bucket = Bucket(),
57  const ValueIndexMap& _id = ValueIndexMap())
58  : next(_length+_max_bucket, invalid_value()),
59  prev(_length+_max_bucket, invalid_value()),
60  head(next.begin() + _length),
61  tail(prev.begin() + _length),
62  id_to_value(_length),
63  bucket(_bucket), id(_id) {
64  // trace2("created bs", _length, _max_bucket);
65  assert(head==next.begin()+_length);
66  assert(!next.size() || head[0]==invalid_value());
67 
68 
69  auto l = _length;
70  auto h = head;
71  for(; l < _length + _max_bucket; ++l){
72  *h = l;
73  ++h;
74  }
75  }
77  }
78 
79  void remove(const value_type& x) {
80  size_type i = get(id, x);
81  assert(i<size());
82 #if 0
83  std::cerr << "rm " << i << "\n";
84  std::cerr << "rm " << x << " " << i << " " << bucket[x] << "\n";
85  std::cerr << "rm " << head[bucket[x]] << "\n";
86  std::cerr << "rm " << prev[i] << " " << next[i] << "\n";
87 #endif
88  auto next_node = next[i];
89  auto prev_node = prev[i];
90  assert(prev_node!=i);
91 
92  prev[next_node] = prev_node;
93  next[prev_node] = next_node;
94 
95  } // remove
96 
97  void push_back(const value_type& x) {
98  assert(x<next.size());
99  id_to_value[get(id, x)] = x;
100  (*this)[bucket[x]].push_back(x);
101  }
102  void push_front(const value_type& x) {
103  // dont know how to do this right now, but i mean it.
104  // assert( !is_in_bucket(x) );
105  assert(x<next.size());
106  id_to_value[get(id, x)] = x;
107  (*this)[bucket[x]].push_front(x);
108  }
109  void push(const value_type& x) {
110  return push_front(x);
111  }
112 
113  // update_back?
114  void update_front(const value_type& x) {
115  // dont know how to do this right now, but i mean it.
116  // assert( is_in_bucket(x) );
117  remove(x);
118  (*this)[bucket[x]].push(x);
119  }
120  void update(const value_type& x) {
121  return update_front(x);
122  }
123  void update_back(const value_type& x) { itested();
124  // dont know how to do this right now, but i mean it.
125  // assert( is_in_bucket(x) );
126  remove(x);
127  (*this)[bucket[x]].push_back(x);
128  }
129 
130  // private:
131  // with KCC, the nested stack class is having access problems
132  // despite the friend decl.
134  return (std::numeric_limits<size_type>::max)();
135  }
136 
137  typedef typename std::vector<size_type>::iterator Iter;
138  typedef typename std::vector<size_type>::const_iterator ConstIter;
139  typedef typename std::vector<value_type>::iterator IndexValueMap;
140  typedef typename std::vector<value_type>::const_iterator ConstIndexValueMap;
141 
142  public:
143 
144  template<class Iter_, class IndexValueMap_>
145  class stack_ {
146  public:
149  public:
151  // bug? feature?
153  public:
155  : s(s_), b(t) {}
157  : s(p.s), b(p.b) {}
159  : s(p.s), b(p.b) {untested();}
161  public:
163  assert(&s==&o.s); // how to compile time check?!
164  // or just fallback to pointer?
165  b = o.b;
166  return *this;
167  }
169  assert(&s==&o.s); // how to compile time check?!
170  // or just fallback to pointer?
171  b = o.b;
172  return *this;
173  }
175  assert(b<s.size());
176  return s.value[b];
177  }
179  assert(b!=invalid_value());
180  assert(b!=s.next[b]);
181  b = s.next[b];
182  return *this;
183  }
184  bool operator!=(const_iterator const& o){
185  return o.b!=b;
186  }
187  bool operator==(const_iterator const& o)
188  { return o.b==b; }
189  private:
190  stack_ const& s;
192  };
193  public:
194  stack_(const stack_& p)
195  : bucket_id(p.bucket_id),
196  head(p.head),
197  next(p.next),
198  prev(p.prev),
199  tail(p.tail),
200  value(p.value),
201  id(p.id)
202  {untested();
203  }
204 
205  stack_& operator=(const stack_& p) {
206  bucket_id = p.bucket_id;
207  head = p.head;
208  next = p.next;
209  prev = p.prev;
210  tail = p.tail;
211  value = p.value;
212  id = p.id;
213  return *this;
214  }
215  // stack_(const stack_&&){untested();}
216  public:
217  stack_(bucket_type _bucket_id, Iter_ h, Iter_ n, Iter_ p, Iter_ t, IndexValueMap_ v,
218  const ValueIndexMap& _id)
219 #ifdef ITERATOR_CONSTRUCTOR_WORKAROUND
220  : bucket_id(_bucket_id), head(), next(), prev(), value(v), id(_id) { itested();
221  head = h;
222  next = n;
223  prev = p;
224 #else
225  : bucket_id(_bucket_id), head(h), next(n), prev(p), tail(t), value(v), id(_id) { // }
226 #endif
227  }
228 
229  // Avoid using default arg for ValueIndexMap so that the default
230  // constructor of the ValueIndexMap is not required if not used.
231  stack_(bucket_type _bucket_id, Iter_ h, Iter_ n, Iter_ p, Iter_ t, IndexValueMap_ v)
232 #ifdef ITERATOR_CONSTRUCTOR_WORKAROUND
233  : bucket_id(_bucket_id), head(), next(), prev(), value(v) { untested();
234  head = h;
235  next = n;
236  prev = p;
237 #else
238  : bucket_id(_bucket_id), head(h), next(n), prev(p), tail(t), value(v) { untested();
239 #endif
240  }
241 
242  void push_front(const value_type& x) {
243  const size_type new_head = get(id, x);
244  assert(new_head < size());
245  const size_type current = head[bucket_id];
246  if(new_head == current){ untested();
247 // assert(false);
248  }
249  if ( current != invalid_value() ){
250  assert(current!=new_head);
251  prev[current] = new_head;
252  }else{ untested();
253  tail[bucket_id] = new_head;
254  }
255 
256  prev[new_head] = bucket_id + (head - next);
257  next[new_head] = current;
258  head[bucket_id] = new_head;
259  }
260  void push_back(const value_type& x) {
261  const size_type new_tail = get(id, x);
262  assert(new_tail < size());
263  const size_type current = tail[bucket_id];
264 
265  if(new_tail == current){ untested();
266 // assert(false);
267  }
268  if ( current != invalid_value() ){
269  assert(current!=new_tail);
270  next[current] = new_tail;
271  }else{
272  head[bucket_id] = new_tail;
273  }
274 
275  prev[new_tail] = current;
276  next[new_tail] = bucket_id + (head - next);
277  tail[bucket_id] = new_tail;
278  }
279  void push(const value_type& x) {
280  return push_front(x);
281  }
282  void pop() {
283  assert(!empty());
284  assert(bucket_id<size());
285  size_type current = head[bucket_id];
286  size_type next_node = next[current];
287  head[bucket_id] = next_node;
288  // prev[bucket_id] = bucket_id + (head - prev);
289  if ( next_node != invalid_value() ){
290 // assert(next_node != prev[current]);
291  prev[next_node] = bucket_id + (head - next);
292  }else{ untested();
293  unreachable();
294  }
295  // assert(next_node != prev[current]);
296  }
297  value_type const& top() const { return value[ head[bucket_id] ]; }
298  value_type& top() { return value[ head[bucket_id] ]; }
299  value_type const& front() const { return value[ head[bucket_id] ]; }
300  value_type& front() { return value[ head[bucket_id] ]; }
301  bool empty() const {
302  return begin() == end();
303  }
304  public: // iterator access
306  return const_iterator(head[bucket_id], *this);
307  }
308  // BUG: template override in degree.hpp does not match (why?)
310  return const_iterator(head[bucket_id], *this);
311  }
313  return const_iterator(size()+bucket_id, *this);
314  }
315  public: // debug
316  size_t size()const{return head-next;}
317  private:
319  Iter_ head;
320  Iter_ next;
321  Iter_ prev;
322  Iter_ tail;
323  IndexValueMap_ value;
324  ValueIndexMap id;
325  }; // stack
326 
329 
331  assert(i < next.size());
332  return const_stack(i, head, next.begin(), prev.begin(), tail,
333  id_to_value.begin(), id);
334  }
336  assert(i < next.size());
337  return stack(i, head, next.begin(), prev.begin(), tail,
338  id_to_value.begin(), id);
339  }
340  // number of buckets.
341  size_t size() const{ return next.size() - (head-next.begin()); }
342  protected:
343  std::vector<size_type> next;
344  std::vector<size_type> prev;
345  typename std::vector<size_type>::iterator head;
346  typename std::vector<size_type>::iterator tail;
347  std::vector<value_type> id_to_value;
348  Bucket bucket;
349  ValueIndexMap id;
350  }; // stack_
351 
352 }
353 
354 #endif
355 
356 // vim:ts=8:sw=2:et
parameterString p
Definition: bucket_sorter.hpp:150
bool operator==(const_iterator const &o)
Definition: bucket_sorter.hpp:187
const_iterator(const const_iterator &p)
Definition: bucket_sorter.hpp:156
const_iterator & operator++()
Definition: bucket_sorter.hpp:178
const_iterator()
Definition: bucket_sorter.hpp:152
bool operator!=(const_iterator const &o)
Definition: bucket_sorter.hpp:184
size_type b
Definition: bucket_sorter.hpp:191
const_iterator & operator=(const const_iterator &o)
Definition: bucket_sorter.hpp:162
value_type operator*() const
Definition: bucket_sorter.hpp:174
const_iterator & operator=(const const_iterator &&o)
Definition: bucket_sorter.hpp:168
const_iterator(const const_iterator &&p)
Definition: bucket_sorter.hpp:158
stack_ const & s
Definition: bucket_sorter.hpp:190
~const_iterator()
Definition: bucket_sorter.hpp:160
const_iterator(size_type t, stack_ const &s_)
Definition: bucket_sorter.hpp:154
Definition: bucket_sorter.hpp:145
const_iterator end() const
Definition: bucket_sorter.hpp:312
IndexValueMap_ value
Definition: bucket_sorter.hpp:323
const_iterator rbegin() const
Definition: bucket_sorter.hpp:309
stack_(bucket_type _bucket_id, Iter_ h, Iter_ n, Iter_ p, Iter_ t, IndexValueMap_ v, const ValueIndexMap &_id)
Definition: bucket_sorter.hpp:217
void push_back(const value_type &x)
Definition: bucket_sorter.hpp:260
bool empty() const
Definition: bucket_sorter.hpp:301
const_iterator begin() const
Definition: bucket_sorter.hpp:305
value_type & front()
Definition: bucket_sorter.hpp:300
bucket_type bucket_id
Definition: bucket_sorter.hpp:318
void push(const value_type &x)
Definition: bucket_sorter.hpp:279
size_t size() const
Definition: bucket_sorter.hpp:316
stack_(const stack_ &p)
Definition: bucket_sorter.hpp:194
ValueIndexMap id
Definition: bucket_sorter.hpp:324
bucket_sorter base
Definition: bucket_sorter.hpp:147
bucket_sorter::value_type value_type
Definition: bucket_sorter.hpp:148
value_type & top()
Definition: bucket_sorter.hpp:298
Iter_ next
Definition: bucket_sorter.hpp:320
Iter_ head
Definition: bucket_sorter.hpp:319
void pop()
Definition: bucket_sorter.hpp:282
stack_ & operator=(const stack_ &p)
Definition: bucket_sorter.hpp:205
value_type const & front() const
Definition: bucket_sorter.hpp:299
value_type const & top() const
Definition: bucket_sorter.hpp:297
Iter_ prev
Definition: bucket_sorter.hpp:321
void push_front(const value_type &x)
Definition: bucket_sorter.hpp:242
Iter_ tail
Definition: bucket_sorter.hpp:322
stack_(bucket_type _bucket_id, Iter_ h, Iter_ n, Iter_ p, Iter_ t, IndexValueMap_ v)
Definition: bucket_sorter.hpp:231
Definition: bucket_sorter.hpp:47
std::vector< size_type >::const_iterator ConstIter
Definition: bucket_sorter.hpp:138
void update_back(const value_type &x)
Definition: bucket_sorter.hpp:123
bucket_sorter()
Definition: bucket_sorter.hpp:76
stack_< Iter, IndexValueMap > stack
Definition: bucket_sorter.hpp:327
BucketType bucket_type
Definition: bucket_sorter.hpp:49
std::vector< value_type >::iterator IndexValueMap
Definition: bucket_sorter.hpp:139
ValueType value_type
Definition: bucket_sorter.hpp:50
std::vector< value_type >::const_iterator ConstIndexValueMap
Definition: bucket_sorter.hpp:140
void push(const value_type &x)
Definition: bucket_sorter.hpp:109
std::vector< size_type > prev
Definition: bucket_sorter.hpp:344
std::vector< size_type > next
Definition: bucket_sorter.hpp:343
bucket_sorter(size_type _length, bucket_type _max_bucket, const Bucket &_bucket=Bucket(), const ValueIndexMap &_id=ValueIndexMap())
Definition: bucket_sorter.hpp:55
void push_back(const value_type &x)
Definition: bucket_sorter.hpp:97
ValueIndexMap id
Definition: bucket_sorter.hpp:349
std::vector< value_type >::size_type size_type
Definition: bucket_sorter.hpp:53
const_stack operator[](const bucket_type &i) const
Definition: bucket_sorter.hpp:330
size_t size() const
Definition: bucket_sorter.hpp:341
void remove(const value_type &x)
Definition: bucket_sorter.hpp:79
Bucket Bucket_type
Definition: bucket_sorter.hpp:51
void push_front(const value_type &x)
Definition: bucket_sorter.hpp:102
stack_< ConstIter, ConstIndexValueMap > const_stack
Definition: bucket_sorter.hpp:328
std::vector< value_type > id_to_value
Definition: bucket_sorter.hpp:347
stack operator[](const bucket_type &i)
Definition: bucket_sorter.hpp:335
std::vector< size_type >::iterator Iter
Definition: bucket_sorter.hpp:137
ValueIndexMap value_index_map
Definition: bucket_sorter.hpp:52
static size_type invalid_value()
Definition: bucket_sorter.hpp:133
void update(const value_type &x)
Definition: bucket_sorter.hpp:120
std::vector< size_type >::iterator tail
Definition: bucket_sorter.hpp:346
Bucket bucket
Definition: bucket_sorter.hpp:348
void update_front(const value_type &x)
Definition: bucket_sorter.hpp:114
std::vector< size_type >::iterator head
Definition: bucket_sorter.hpp:345
#define untested()
Definition: lua_table_handle.cpp:15
Definition: boost_serialization_routines.h:49
SM_edge_weight_map< typename T::value_type, ug::BidirectionalMatrix< T > > get(edge_weight_t, ug::BidirectionalMatrix< T > const &g)
Definition: bidirectional_boost.h:157
#define unreachable()
Definition: trace.h:13
#define itested()
Definition: trace.h:9