MADARA  3.1.8
Transaction.h
Go to the documentation of this file.
1 
2 
3 #ifndef INCL_MADARA_RCW_TRANSACTION_H
4 #define INCL_MADARA_RCW_TRANSACTION_H
5 
13 #include <string>
14 #include <vector>
15 #include <map>
16 #include <list>
17 #include <type_traits>
18 #include <initializer_list>
21 #include "madara/utility/stdint.h"
22 #include "madara/MADARA_export.h"
27 #include "Tracker.h"
28 #include "PrefixTracker.h"
29 
30 namespace madara { namespace knowledge {
31 
36 namespace rcw
37 {
44  {
45  public:
46  typedef std::unique_ptr<BaseTracker> tracker_ptr;
47 
49  template<class T, class K, bool Const = false,
50  bool RD = true, bool WR = true,
51  bool Prefix = false, bool Init = false>
52  class Builder;
53 
54  private:
56  typedef std::vector<tracker_ptr> trackers_vec;
57 
59  mutable KnowledgeBase kb_;
60 
62  mutable trackers_vec trackers_;
63 
66  template<class B, class I, class T, class dummy = void>
68  {
69  public:
70  I init() const;
71  };
72 
75  template<class B, class I, class T>
76  class InitHandler<B, I, T,
77  typename std::enable_if<
78  supports_get_value<T>::value &&
79  supports_indexed_get_value<T>::value &&
80  supports_size<T>::value>::type>
81  {
82  typedef typename std::decay<decltype(get_value(std::declval<T>()[0]))>::type V;
83  public:
84  I init(std::initializer_list<V> list) const
85  {
86  const B &self = static_cast<const B &>(*this);
87  *self.tracked_ = list;
88  return self.init();
89  }
90  };
91 
92  public:
97 
99  void push(void)
100  {
101  ContextGuard guard(kb_);
102  for (auto &t : trackers_) {
103  t->push(kb_);
104  }
105  }
106 
108  void pull(void)
109  {
110  ContextGuard guard(kb_);
111  for (auto &t : trackers_) {
112  t->pull();
113  }
114  }
115 
118  template<class T, class K, bool Const,
119  bool RD, bool WR, bool Prefix, bool Init>
120  class Builder : private InitHandler<
121  Builder<T, K, Const, RD, WR, Prefix, Init>,
122  Builder<T, K, Const, RD, WR, Prefix, true>, T>
123  {
124  private:
125  typedef typename std::conditional<Const, const Transaction *,
126  Transaction *>::type trans_type;
127  typedef decltype(*(trans_type)nullptr) trans_ref_type;
128  const trans_type trans_;
129  const K key_;
130  T * const tracked_;
131  static const bool rd_ = RD;
132  static const bool wr_ = WR;
133  static const bool prefix_ = Prefix;
134  static const bool init_ = Init;
135 
136  Builder(trans_ref_type trans, K key, T &val)
137  : trans_(&trans), key_(key), tracked_(&val) {}
138 
139  template<bool R, bool W, bool P, bool I>
141  : trans_(o.trans_), key_(o.key_), tracked_(o.tracked_) {}
142 
147 
148  public:
151  init_type init() const
152  {
153  static_assert(!Const, "Can't use init() on build() of const Transaction");
154  return *this;
155  }
156 
159  prefix_type prefix() const { return *this; }
160 
162  ro_type ro() const { return *this; }
163 
166  ro_type readonly() const { return *this; }
167 
170  wo_type wo() const { return *this; }
171 
175  wo_type writeonly() const { return *this; }
176 
179  template<class V>
180  init_type init(V &&val) const
181  {
182  *tracked_ = std::forward<V>(val);
183  return init();
184  }
185 
187  friend class InitHandler<Builder, init_type, T>;
188 
190  void add() const
191  {
192  trans_->add(*this);
193  }
194 
195  friend class Transaction;
196  };
197 
198  template<class T, class K, bool Const, bool RD, bool WR,
199  bool Prefix, bool Init> friend class Builder;
200 
208  template<class T, class K>
210  {
211  return Builder<T, const char*>(*this, std::forward<K>(key), val);
212  }
213 
214 #ifndef DOXYGEN
215  template<class T, class S>
216  Builder<T, const char*, true> build(S &&key, T &val) const
217  {
218  return Builder<T, const char*, true>(*this, std::forward<S>(key), val);
219  }
220 #endif //DOXYGEN
221 
224  void add_tracker(tracker_ptr t) const
225  {
226  trackers_.emplace_back(std::move(t));
227  }
228 
229 #ifdef DOXYGEN
230  template<class T>
233  void add(const Builder<T, const char*> &b);
234 #else
235  template<class T, bool RD, bool WR, bool Init>
237  {
238  std::unique_ptr<PrefixTracker<T, VariableReference, RD, WR>>
240  if (b.init_) {
241  p->PrefixTracker<T, VariableReference, RD, WR>::force_push(kb_);
242  }
243  add_tracker(tracker_ptr(p.release()));
244  }
245 
246  template<class T, bool RD, bool WR, bool Init>
248  {
250  std::unique_ptr<Tracker<T, VariableReference, RD, WR>>
252  if (b.init_) {
253  p->Tracker<T, VariableReference, RD, WR>::force_push(kb_);
254  }
255  add_tracker(tracker_ptr(p.release()));
256  }
257 
258  template<class T, bool RD, bool WR>
260  {
261  std::unique_ptr<PrefixTracker<T, VariableReference, RD, WR>>
263  add_tracker(tracker_ptr(p.release()));
264  }
265 
266  template<class T, bool RD, bool WR>
268  {
270  std::unique_ptr<Tracker<T, VariableReference, RD, WR>>
272  add_tracker(tracker_ptr(p.release()));
273  }
274 #endif //DOXYGEN
275 
280  template<class T, class K>
281  void add(K &&key, T &val) const
282  {
283  build(std::forward<K>(key), val).add();
284  }
285 
291  template<class T, class K>
292  void add_init(K &&key, T &val)
293  {
294  build(std::forward<K>(key), val).init().add();
295  }
296 
301  template<class T, class K>
302  void add_prefix(K &&prefix, T &val) const
303  {
304  build(std::forward<K>(prefix), val).prefix().add();
305  }
306 
312  template<class T, class K>
313  void add_prefix_init(K &&prefix, T &val)
314  {
315  build(std::forward<K>(prefix), val).prefix().init().add();
316  }
317 
323  bool remove(const char *name) const
324  {
325  iter_type i = std::find_if(trackers_.begin(), trackers_.end(), [name](const tracker_ptr &cur) {
326  return strcmp(name, cur->get_name()) == 0;
327  });
328  if (i != trackers_.end()) {
329  swap_remove(i);
330  return 1;
331  } else {
332  return 0;
333  }
334  }
335 
341  bool remove(const std::string &name) const
342  {
343  return remove(name.c_str());
344  }
345 
351  template<class T>
352  bool remove(const T *var) const
353  {
354  iter_type i = std::find_if(trackers_.begin(), trackers_.end(), [&var](const tracker_ptr &cur) {
355  return (void *)var == cur->get_tracked();
356  });
357  if (i != trackers_.end()) {
358  swap_remove(i);
359  return 1;
360  } else {
361  return 0;
362  }
363  }
364 
365  private:
366  typedef trackers_vec::iterator iter_type;
367  void swap_remove(iter_type i) const
368  {
369  using namespace std;
370  swap(*i, trackers_.back());
371  trackers_.pop_back();
372  }
373  };
374 } } } // end namespace knowledge::rcw
375 
376 #endif // INCL_MADARA_RCW_TRANSACTION_H
Builder< T, const char * > build(K &&key, T &val)
Create a new mapping, using the Builder interface.
Definition: Transaction.h:209
init_type init() const
If used, the mapping will push the current value of the variable into the knowledge base...
Definition: Transaction.h:151
ro_type ro() const
The mapping will only read from the knowledge base, not write back.
Definition: Transaction.h:162
void add_prefix_init(K &&prefix, T &val)
Add a new prefix-based mapping for MADARA variable and ref .
Definition: Transaction.h:313
Manages a Read-Compute-Write cycle for registered variables.
Definition: Transaction.h:43
Builder object returned by build()
Definition: Transaction.h:52
void add_tracker(tracker_ptr t) const
Add a tracker object directly.
Definition: Transaction.h:224
void swap_remove(iter_type i) const
Definition: Transaction.h:367
KnowledgeBase kb_
The knowledge base to push to and pull from.
Definition: Transaction.h:59
void add() const
Finish configuring this Builder, and add the new mapping.
Definition: Transaction.h:190
STL namespace.
void add(const Builder< T, const char * > &b)
Add a mapping from a Builder object.
Builder< T, K, Const, false, true, Prefix, Init > wo_type
Definition: Transaction.h:146
void add(K &&key, T &val) const
Add a new default mapping for MADARA variable and reference .
Definition: Transaction.h:281
Optimized reference to a variable within the knowledge base.
std::conditional< Const, const Transaction *, Transaction * >::type trans_type
Definition: Transaction.h:126
Builder< T, K, Const, RD, WR, Prefix, true > init_type
Definition: Transaction.h:143
A thread-safe guard for a context or knowledge base.
Definition: ContextGuard.h:23
wo_type writeonly() const
The mapping will only write to the knowledge base.
Definition: Transaction.h:175
wo_type wo() const
The mapping will only write to the knowledge base.
Definition: Transaction.h:170
void add_prefix(K &&prefix, T &val) const
Add a new prefix-based mapping for MADARA variable and ref .
Definition: Transaction.h:302
std::unique_ptr< BaseTracker > tracker_ptr
Definition: Transaction.h:46
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:44
Transaction(KnowledgeBase kb)
The constructor.
Definition: Transaction.h:96
trackers_vec trackers_
Stores all registered trackers.
Definition: Transaction.h:62
Helper type to enable initialization using initializer_list Fallback implementation for types which d...
Definition: Transaction.h:67
Builder< T, K, Const, RD, WR, true, Init > prefix_type
Definition: Transaction.h:144
Tracker which puts variable values into a single KnowledgeRecord.
Definition: Tracker.h:34
static constexpr struct madara::knowledge::tags::string_t string
prefix_type prefix() const
If used, the name given in build() will be used as a prefix, as apropriate for the variable type...
Definition: Transaction.h:159
Tracker that puts values into a multiple prefixed KnowledgeRecords.
Definition: PrefixTracker.h:35
void add_init(K &&key, T &val)
Add a new mapping for MADARA variable and reference .
Definition: Transaction.h:292
trackers_vec::iterator iter_type
Definition: Transaction.h:366
Provides functions and classes for the distributed knowledge base.
Builder(const Builder< T, K, Const, R, W, P, I > &o)
Definition: Transaction.h:140
init_type init(V &&val) const
As init(), but first set the variable to .
Definition: Transaction.h:180
void pull(void)
Call to update values of registered variables from the knowledge base.
Definition: Transaction.h:108
Copyright (c) 2015 Carnegie Mellon University.
ro_type readonly() const
The mapping will only read from the knowledge base, not write back Synonym for.
Definition: Transaction.h:166
VariableReference get_ref(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings(false))
Atomically returns a reference to the variable.
Builder< T, K, Const, true, false, Prefix, Init > ro_type
Definition: Transaction.h:145
void push(void)
Call to push all values of registered variables into the knowledge base.
Definition: Transaction.h:99
std::vector< tracker_ptr > trackers_vec
Type of a vector which stores trackers.
Definition: Transaction.h:52