MADARA  3.1.8
PrefixTracker.h
Go to the documentation of this file.
1 
2 
3 #ifndef INCL_MADARA_RCW_PREFIX_TRACKER_H
4 #define INCL_MADARA_RCW_PREFIX_TRACKER_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 "BaseTracker.h"
28 
29 namespace madara { namespace knowledge { namespace rcw
30 {
34  template<class T, class R, bool RD = true, bool WR = true, class dummy = void>
36  {
37  static_assert(sizeof(T) < 0, "Type unsupported for adding to Transaction with prefix");
38  };
39 
41  template<class T, class R>
42  class PrefixTracker<T, R, false, false, void>
43  : public BaseTracker
44  {
45  private:
46  static_assert(sizeof(T) < 0, "Cannot create prefix tracker that can neither read nor write");
47  };
48 
52  template<class T, bool RD, bool WR>
53  class PrefixTracker<T, VariableReference, RD, WR, typename std::enable_if<
54  supports_get_value<T>::value &&
55  supports_indexed_get_value<T>::value &&
56  supports_size<T>::value &&
57  supports_is_dirty<T>::value &&
58  supports_is_all_dirty<T>::value &&
59  supports_is_size_dirty<T>::value &&
60  supports_indexed_is_dirty<T>::value>::type >
61  : public BaseTracker
62  {
63  private:
64  T *tracked_;
67 
69  std::vector<VariableReference> elems_;
70 
71  typedef typename std::decay<decltype(get_value(std::declval<T>()[0]))>::type V;
72 
73  static const bool can_read = RD;
74  static const bool can_write = WR;
75 
76  PrefixTracker(T *tracked, const std::string &prefix, KnowledgeBase &kb)
77  : BaseTracker(kb.get_ref(prefix + ".size")),
78  tracked_(tracked), prefix_(prefix), kb_(kb), elems_()
79  {
80  update_elems();
81  }
82 
84  void update_elems()
85  {
86  const size_t n = tracked_->size();
87  if (elems_.size() == n)
88  return;
89  if (elems_.size() > n) {
90  for (size_t i = n; i < elems_.size(); ++i) {
91  get_mut(elems_[i]).clear_value();
92  }
93  elems_.resize(n);
94  return;
95  }
96  std::ostringstream name;
97  elems_.reserve(n);
98  name << prefix_ << ".";
99  const auto pos = name.tellp();
100  for (size_t i = elems_.size(); i < n; ++i) {
101  name << i;
102  elems_.push_back(kb_.get_ref(name.str()));
103  name.seekp(pos);
104  }
105  }
106 
107  virtual void pull()
108  {
109  const size_t n = get().to_integer();
110  tracked_->resize(n);
111  update_elems();
112  for (size_t i = 0; i < n; ++i) {
113  if (can_read) {
114  V val = knowledge_cast<V>(get(elems_[i]));
115  set_value(*tracked_, i, val);
116  } else {
117  set_value(*tracked_, i, V());
118  }
119  }
120  clear_dirty(*tracked_);
121  }
122 
123  virtual void push(KnowledgeBase &kb)
124  {
125  if (can_write) {
126  const size_t n = tracked_->size();
127  if (is_all_dirty(*tracked_)) {
128  return force_push(kb);
129  }
130  if (is_size_dirty(*tracked_)) {
131  set(kb, n);
132  post_set(kb);
133  }
134 
135  update_elems();
136  for (size_t i = 0; i < n; ++i) {
137  if (is_dirty(*tracked_, i)) {
138  set(kb, elems_[i], knowledge_cast(get_value(*tracked_, i)));
139  post_set(kb, elems_[i]);
140  }
141  }
142  }
143  }
144 
145  virtual void force_push(KnowledgeBase &kb)
146  {
147  if (can_write) {
148  const size_t n = tracked_->size();
149  set(kb, n);
150  post_set(kb);
151 
152  update_elems();
153  for (size_t i = 0; i < n; ++i) {
154  set(kb, elems_[i], knowledge_cast(tracked_->at(i)));
155  post_set(kb, elems_[i]);
156  }
157  }
158  }
159 
160  virtual const char *get_name() const
161  {
162  return prefix_.c_str();
163  }
164 
165  virtual const void *get_tracked() const
166  {
167  return (void*)tracked_;
168  }
169 
170  friend class Transaction;
171  };
172 } } } // end namespace madara::knowledge::rcw
173 
174 #endif // INCL_MADARA_RCW_PREFIX_TRACKER_H
bool is_size_dirty(const Tracked< std::vector< T >> &t)
Return size changed dirty flag of Tracked vector.
Definition: Tracked.h:836
Manages a Read-Compute-Write cycle for registered variables.
Definition: Transaction.h:43
Base type for Trackers.
Definition: BaseTracker.h:62
STL namespace.
Optimized reference to a variable within the knowledge base.
bool is_dirty(const Tracked< T > &t)
Returns dirty flag of Tracked types.
Definition: Tracked.h:533
O knowledge_cast(const KnowledgeRecord &in)
By default, call constructor of target class; for other semantics, define specializations.
bool is_all_dirty(const Tracked< std::vector< T >> &t)
Return global dirty flag of Tracked vector.
Definition: Tracked.h:829
void clear_dirty(Tracked< T > &t)
Clears dirty flag of Tracked types.
Definition: Tracked.h:540
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:44
static constexpr struct madara::knowledge::tags::string_t string
Tracker that puts values into a multiple prefixed KnowledgeRecords.
Definition: PrefixTracker.h:35
const T & get_value(const T &t)
Fallback definition of get_value; simply passes through the value.
Definition: BaseTracker.h:33
Provides functions and classes for the distributed knowledge base.
void set_value(T &t, const T &v)
Fallback definition of set_value; simply passes through the value.
Definition: BaseTracker.h:40
Copyright (c) 2015 Carnegie Mellon University.