Derecho  0.9
Distributed systems toolkit for RDMA
predicates.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <functional>
5 #include <list>
6 #include <mutex>
7 #include <utility>
8 
9 
10 namespace sst {
11 
12 template <class DerivedSST>
13 class SST;
14 
16 enum class PredicateType {
18  ONE_TIME,
21  RECURRENT,
25 };
26 
27 template <class DerivedSST>
28 class Predicates {
29  using pred = std::function<bool(const DerivedSST&)>;
30  using trig = std::function<void(DerivedSST&)>;
31  using pred_list = std::list<std::unique_ptr<std::pair<pred, std::shared_ptr<trig>>>>;
39  std::list<bool> transition_predicate_states;
40  // SST needs to read these predicate lists directly
41  friend class SST<DerivedSST>;
42 
43  std::mutex predicate_mutex;
44 
45 public:
46  class pred_handle {
47  bool valid;
48  typename pred_list::iterator iter;
50  friend class Predicates;
51 
52  public:
53  pred_handle() : valid(false), type(PredicateType::ONE_TIME) {}
54  pred_handle(typename pred_list::iterator iter, PredicateType type)
55  : valid{true}, iter{iter}, type{type} {}
56  pred_handle(pred_handle&) = delete;
58  : pred_handle(std::move(other.iter), other.type) {
59  other.valid = false;
60  }
61  pred_handle& operator=(pred_handle&) = delete;
63  iter = std::move(other.iter);
64  type = other.type;
65  valid = true;
66  other.valid = false;
67  return *this;
68  }
69  bool is_valid() const {
70  return valid && (*iter);
71  }
72  };
73 
75  pred_handle insert(pred predicate, trig trigger,
77 
80  pred_handle insert(pred predicate, const std::list<trig>& triggers,
82  return insert(predicate, [triggers](DerivedSST& t) {
83  for(const auto& trigger : triggers)
84  trigger(t);
85  },
86  type);
87  }
88 
90  void remove(pred_handle& pred);
91 
93  void clear();
94 };
95 
106 template <class DerivedSST>
107 auto Predicates<DerivedSST>::insert(pred predicate, trig trigger, PredicateType type) -> pred_handle {
108  std::lock_guard<std::mutex> lock(predicate_mutex);
109  if(type == PredicateType::ONE_TIME) {
110  one_time_predicates.push_back(std::make_unique<std::pair<pred, std::shared_ptr<trig>>>(
111  predicate, std::make_shared<trig>(trigger)));
112  return pred_handle(--one_time_predicates.end(), type);
113  } else if(type == PredicateType::RECURRENT) {
114  recurrent_predicates.push_back(std::make_unique<std::pair<pred, std::shared_ptr<trig>>>(
115  predicate, std::make_shared<trig>(trigger)));
116  return pred_handle(--recurrent_predicates.end(), type);
117  } else {
118  transition_predicates.push_back(std::make_unique<std::pair<pred, std::shared_ptr<trig>>>(
119  predicate, std::make_shared<trig>(trigger)));
120  transition_predicate_states.push_back(false);
121  return pred_handle(--transition_predicates.end(), type);
122  }
123 }
124 
125 template <class DerivedSST>
126 void Predicates<DerivedSST>::remove(pred_handle& handle) {
127  std::lock_guard<std::mutex> lock(predicate_mutex);
128  if(!handle.is_valid()) {
129  return;
130  }
131  handle.iter->reset();
132  handle.valid = false;
133 }
134 
135 template <class DerivedSST>
137  std::lock_guard<std::mutex> lock(predicate_mutex);
138  using ptr_to_pred = std::unique_ptr<std::pair<pred, std::shared_ptr<trig>>>;
139  std::for_each(one_time_predicates.begin(), one_time_predicates.end(),
140  [](ptr_to_pred& ptr) { ptr.reset(); });
141  std::for_each(recurrent_predicates.begin(), recurrent_predicates.end(),
142  [](ptr_to_pred& ptr) { ptr.reset(); });
143  std::for_each(transition_predicates.begin(), transition_predicates.end(),
144  [](ptr_to_pred& ptr) { ptr.reset(); });
145 }
146 
147 } /* namespace sst */
One-time predicates only fire once; they are deleted once they become true.
std::function< bool(const DerechoSST &)> pred
Definition: predicates.hpp:29
pred_handle insert(pred predicate, trig trigger, PredicateType type=PredicateType::ONE_TIME)
Inserts a single (predicate, trigger) pair to the appropriate predicate list.
Definition: predicates.hpp:107
pred_handle(typename pred_list::iterator iter, PredicateType type)
Definition: predicates.hpp:54
STL namespace.
pred_list transition_predicates
Predicate list for transition predicates.
Definition: predicates.hpp:37
void remove(pred_handle &pred)
Removes a (predicate, trigger) pair previously registered with insert().
Definition: predicates.hpp:126
pred_list::iterator iter
Definition: predicates.hpp:48
PredicateType
Enumeration defining the kinds of predicates an SST can handle.
Definition: predicates.hpp:16
std::mutex predicate_mutex
Definition: predicates.hpp:43
pred_list recurrent_predicates
Predicate list for recurrent predicates.
Definition: predicates.hpp:35
Transition predicates persist as long as the SST instance, but only fire their triggers when they tra...
pred_handle insert(pred predicate, const std::list< trig > &triggers, PredicateType type=PredicateType::ONE_TIME)
Inserts a predicate with a list of triggers (which will be run in sequence) to the appropriate predic...
Definition: predicates.hpp:80
std::list< bool > transition_predicate_states
Contains one entry for every predicate in transition_predicates, in parallel.
Definition: predicates.hpp:39
std::list< std::unique_ptr< std::pair< pred, std::shared_ptr< trig > >> > pred_list
Definition: predicates.hpp:31
pred_handle(pred_handle &&other)
Definition: predicates.hpp:57
std::function< void(DerechoSST &)> trig
Definition: predicates.hpp:30
Recurrent predicates persist as long as the SST instance and fire their triggers every time they are ...
pred_list one_time_predicates
Predicate list for one-time predicates.
Definition: predicates.hpp:33
void clear()
Deletes all predicates, including evolvers and their triggers.
Definition: predicates.hpp:136
pred_handle & operator=(pred_handle &&other)
Definition: predicates.hpp:62