TCPSPSuite
leveltree.hpp
1 #ifndef LEVELTREE_H
2 #define LEVELTREE_H
3 
4 #include <assert.h> // for assert
5 #include <boost/container/detail/std_fwd.hpp> // for pair
6 #include <boost/icl/discrete_interval.hpp> // for discrete_interval
7 #include <boost/icl/interval_map.hpp> // for interval_map
8 #include <boost/icl/interval_set.hpp> // for interval_set
9 #include <ostream> // for basic_ostream
10 #include <tuple> // for tuple
11 #include <vector> // for vector
12 #include "../instance/job.hpp" // for Job, Job::JobId
13 #include "generated_config.hpp" // for ENABLE_ASSERTIONS
14 #include "../util/log.hpp" // for Log
15 #include "jobset.hpp"
16 
17 namespace level_tree {
18 
19 class LinearLevelAssigner {
20 public:
21  LinearLevelAssigner(double min, double max, unsigned int levels);
22  unsigned int get_level(double amount) const;
23 
24  bool operator==(const LinearLevelAssigner & rhs) const;
25 
26  unsigned int level_count() const;
27 
28 private:
29  double min_val;
30  double level_size;
31  unsigned int levels;
32 };
33 
34 } // namespace level_tree
35 
36 template<class Key, class LevelAssigner>
37 class LevelTree {
38 public:
39  using JobId = Job::JobId;
40  using Interval = typename boost::icl::discrete_interval<Key>::type;
41  using LevelProfile = std::vector<std::tuple<const Interval, unsigned int, double>>;
42  using ContentData = std::vector<std::pair<const Interval, const JobSet>>;
43 
44  LevelTree(LevelAssigner level_assigner, Interval horizon);
45 
46  class Intervals {
47  public:
48  // TODO move them into a single template, only one operator is different!
49  Intervals operator-(const Intervals &rhs) const;
50  Intervals operator+(const Intervals &rhs) const;
51  Intervals operator&(const Intervals &rhs) const;
52  Intervals operator!() const;
53 
54  Intervals extend(Key extend_left, Key extend_right) const;
55  Intervals move_left(Key amount) const;
56 
57  void push_back(Interval interval);
58  const std::vector<Interval> & get() const;
59 
60  Key coverage() const;
61  bool empty() const;
62 
63  bool overlaps(const Interval & interval) const;
64 
65  // String output
66  // Needs to be *defined* here :(
67  template<class _CharT, class _Traits>
68  friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& stream, const typename LevelTree<Key, LevelAssigner>::Intervals & intervals) {
69  stream << "[ ";
70 
71  bool first = true;
72  for (const auto & interval : intervals.get()) {
73  if (!first) {
74  stream << ", ";
75  }
76  stream << interval;
77  first = false;
78  }
79 
80  stream << " ]";
81 
82  return stream;
83  }
84 
85 
86  private:
87  std::vector<Interval> content; // assumed to be ordered!
88 
89  template<class binop>
90  Intervals operator_base(binop op, const Intervals & rhs) const;
91  };
92 
93  static Interval make_interval(Key start, Key end)
94  {
95 #ifdef ENABLE_ASSERTIONS
96  assert(end > start);
97 #endif
98  return Interval(start, end);
99  }
100 
101  // TODO make this a move insert
102  void insert(const Interval &interval, JobSet payload);
103  void remove(const Interval &interval, const JobSet &payload);
104 
105  void insert(const Interval &interval, JobId job, double amount);
106  void remove(const Interval &interval, JobId job, double amount);
107 
108  //void move(const Interval &old_interval, const Interval &new_interval, JobId job, double amount);
109 
110  unsigned int level_at(Key point);
111 
112  // TODO this requires copying…
113  Intervals get_level(unsigned int level);
114  LevelProfile get_profile(const Interval &query);
115  LevelProfile get_profile();
116  ContentData get_content();
117 
118  // operators
119  bool operator==(const LevelTree<Key, LevelAssigner> & rhs);
120 
121  void dbg_verify();
122 
123 
124  // String output
125  // Needs to be *defined* here :(
126  template<class _CharT, class _Traits>
127  friend std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& stream, const typename LevelTree<Key, LevelAssigner>::Interval & interval);
128 
129 private:
130  void update_levels(const LevelProfile &oldp, const LevelProfile &newp);
131 
132  std::vector<boost::icl::interval_set<Key>> levels;
133  boost::icl::interval_map<Key, JobSet> content;
134 
135  LevelAssigner level_assigner;
136  // TODO should be const…
137  Interval horizon;
138 
139  // Interval comparison
140  bool strictly_before(const Interval &lhs, const Interval &rhs);
141  bool strictly_after(const Interval &lhs, const Interval &rhs);
142  bool contains(const Interval &lhs, const Interval &rhs);
143 
144  // TODO FIXME move to unit-test?
145  void dbg_verify_level_containment();
146  void dbg_verify_level_assignment();
147 
148  Log l;
149 };
150 
151 #endif