MADARA  3.2.3
CompositeArrayReference.cpp
Go to the documentation of this file.
1 
2 #ifndef _MADARA_NO_KARL_
3 
7 #include "VariableExpander.h"
8 
9 
10 #include <string>
11 #include <sstream>
12 
14  const std::string & key, ComponentNode * index,
16 : CompositeUnaryNode (context.get_logger (), index),
17  context_ (context),
18  key_ (key),
19  key_expansion_necessary_ (false)
20 {
21  VariableExpander expander;
22  ref_ = expander.expand (key, "CompositeArrayReference", context, logger_,
24 }
25 
28 {
30  {
32  "Variable %s requires variable expansion\n",
33  key_.c_str ());
34 
35  unsigned int count = 0;
36 
37  // add the first token into a string builder
38  std::stringstream builder;
39  std::vector< std::string>::const_iterator token = tokens_.begin ();
40  builder << *token;
41 
42  // move the token to the next in the list.
43  for (++token, ++count; token != tokens_.end (); ++token, ++count)
44  {
45  if (*token != "")
46  {
47  // is the current token a variable to lookup?
48  if (count < pivot_list_.size ()
49  && pivot_list_[count] == "}")
50  {
51  builder << context_.get_record (*token)->to_string ();
52  }
53  else
54  {
55  builder << *token;
56  }
57  }
58  }
59 
60  return builder.str ();
61  }
62  // if there was no need to expand the key, just return
63  // the key
64  else
65  return key_;
66 }
67 
68 
69 void
71 {
72  visitor.visit (*this);
73 }
74 
77 {
78  size_t index = right_->item ().to_integer ();
79 
80  if (ref_.is_valid())
81  {
82  return ref_.get_record_unsafe()->retrieve_index (index);
83  }
84  else
85  return context_.get (expand_key ()).retrieve_index (index);
86 }
87 
93 {
94  // a variable is one of very few nodes that can change over time and
95  // cannot be pruned
96  can_change = true;
97 
99 
100  if (key == "nan")
101  {
103  "CompositeArrayReference::prune: "
104  "KARL COMPILE ERROR:"
105  "Reserved word 'nan' used as an array reference.\n",
106  key_.c_str ());
107 
108  //return new LeafNode (context_.get_logger (), NAN);
109  throw KarlException ("madara::expression::ComponentNode: "
110  "KARL COMPILE ERROR: "
111  "Reserved word 'nan' used as an array reference.");
112  }
113  else if (key == "inf")
114  {
116  "CompositeArrayReference::prune: "
117  "KARL COMPILE ERROR:"
118  "Reserved word 'inf' used as an array reference.\n",
119  key_.c_str ());
120 
121  //return new LeafNode (context_.get_logger (), NAN);
122  throw KarlException ("madara::expression::ComponentNode: "
123  "KARL COMPILE ERROR: "
124  "Reserved word 'inf' used as an array reference.");
125  }
126 
127  // we could call item(), but since it is virtual, it incurs unnecessary
128  // overhead.
129  if (ref_.is_valid())
130  return *ref_.get_record_unsafe();
131  else
132  return context_.get (expand_key ());
133 }
134 
140 {
141  size_t index = right_->evaluate (settings).to_integer ();
142 
143  if (ref_.is_valid())
144  {
145  return ref_.get_record_unsafe()->retrieve_index (index);
146  }
147  else
148  return context_.get (expand_key ()).retrieve_index (index);
149 }
150 
151 const std::string &
153 {
154  return key_;
155 }
156 
157 
162 {
163  size_t index = size_t (right_->evaluate (settings).to_integer ());
164 
165  if (ref_.is_valid())
166  {
167  auto record = ref_.get_record_unsafe();
168 
169  // notice that we assume the context is locked
170  // check if we have the appropriate write quality
171  if (!settings.always_overwrite && record->write_quality < record->quality)
172  return context_.retrieve_index (expand_key (), index, settings);
173 
174  // cheaper to read than write, so check to see if
175  // we actually need to update quality and status
176  if (record->write_quality != record->quality)
177  record->quality = record->write_quality;
178 
179  knowledge::KnowledgeRecord result (record->dec_index (index));
180 
182 
183  return result;
184  }
185  else
186  {
188  context_.retrieve_index (expand_key (), index, settings) - knowledge::KnowledgeRecord (1));
189 
190  if (result.type () == knowledge::KnowledgeRecord::INTEGER)
191  context_.set_index (expand_key (), index, result.to_integer (), settings);
192  else if (result.type () == knowledge::KnowledgeRecord::DOUBLE)
193  context_.set_index (expand_key (), index, result.to_double (), settings);
194 
195  return result;
196  }
197 }
198 
203 {
204  size_t index = size_t (right_->evaluate (settings).to_integer ());
205 
206  if (ref_.is_valid())
207  {
208  auto record = ref_.get_record_unsafe();
209 
210  // notice that we assume the context is locked
211  // check if we have the appropriate write quality
212  if (!settings.always_overwrite && record->write_quality < record->quality)
213  return context_.retrieve_index (expand_key (), index, settings);
214 
215  // cheaper to read than write, so check to see if
216  // we actually need to update quality and status
217  if (record->write_quality != record->quality)
218  record->quality = record->write_quality;
219 
220  knowledge::KnowledgeRecord result (record->inc_index (index));
221 
223 
224  return result;
225  }
226  else
227  {
229  context_.retrieve_index (expand_key (), index, settings)
231 
232  if (result.type () == knowledge::KnowledgeRecord::INTEGER)
233  context_.set_index (expand_key (), index, result.to_integer (), settings);
234  else if (result.type () == knowledge::KnowledgeRecord::DOUBLE)
235  context_.set_index (expand_key (), index, result.to_double (), settings);
236 
237  return result;
238  }
239 }
240 
241 int
245 {
246  int return_value = 0;
247 
249  return_value = set (value.to_integer (), settings);
250  else if (value.type () == knowledge::KnowledgeRecord::DOUBLE)
251  return_value = set (value.to_double (), settings);
252 
253  return return_value;
254 }
255 
256 int
259 {
260  size_t index = size_t (right_->evaluate (settings).to_integer ());
261 
262  if (ref_.is_valid())
263  {
264  auto record = ref_.get_record_unsafe();
265 
266  // notice that we assume the context is locked
267  // check if we have the appropriate write quality
268  if (!settings.always_overwrite && record->write_quality < record->quality)
269  return -2;
270 
271  // cheaper to read than write, so check to see if
272  // we actually need to update quality and status
273  if (record->write_quality != record->quality)
274  record->quality = record->write_quality;
275 
276  record->set_index (index, value);
277 
279 
280  return 0;
281  }
282  else
283  return context_.set_index (expand_key (), index, value, settings);
284 }
285 
286 int
289 {
290  size_t index = size_t (right_->evaluate (settings).to_integer ());
291 
292  if (ref_.is_valid())
293  {
294  auto record = ref_.get_record_unsafe();
295 
296  // notice that we assume the context is locked
297  // check if we have the appropriate write quality
298  if (!settings.always_overwrite && record->write_quality < record->quality)
299  return -2;
300 
301  // cheaper to read than write, so check to see if
302  // we actually need to update quality and status
303  if (record->write_quality != record->quality)
304  record->quality = record->write_quality;
305 
306  record->set_index (index, value);
307 
309 
310  return 0;
311  }
312  else
313  return context_.set_index (expand_key (), index, value, settings);
314 }
315 
316 #endif // _MADARA_NO_KARL_
This class encapsulates an entry in a KnowledgeBase.
virtual madara::knowledge::KnowledgeRecord prune(bool &can_change)
Prune the tree of unnecessary nodes.
int32_t type(void) const
returns the size of the value
int set(const madara::knowledge::KnowledgeRecord::Integer &value, const madara::knowledge::KnowledgeUpdateSettings &settings=knowledge::KnowledgeUpdateSettings())
Sets the value stored in the node.
ComponentNode * right_
Right expression.
uint32_t quality
priority of the update
madara::knowledge::KnowledgeRecord KnowledgeRecord
void mark_and_signal(VariableReference ref, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
method for marking a record modified and signaling changes
double to_double(void) const
converts the value to a float/double.
KnowledgeRecord * get_record_unsafe(void) const
Returns a pointer to the variable&#39;s KnowledgeRecord Do not use this pointer unless you&#39;ve locked the ...
knowledge::KnowledgeRecord inc(const madara::knowledge::KnowledgeUpdateSettings &settings=knowledge::KnowledgeUpdateSettings())
Sets the value stored in the node.
virtual madara::knowledge::KnowledgeRecord item(void) const
Returns the value of the node.
logger::Logger * logger_
handle the context
Definition: ComponentNode.h:97
const std::string & key(void) const
Return the variable key.
This class stores variables and their values for use by any entity needing state information in a thr...
virtual madara::knowledge::KnowledgeRecord evaluate(const madara::knowledge::KnowledgeUpdateSettings &settings)=0
Evaluates the expression tree.
madara::knowledge::VariableReference expand(const std::string &key, const std::string &print_prefix, madara::knowledge::ThreadSafeContext &context, madara::logger::Logger *cur_logger, bool &key_expansion_necessary, std::vector< std::string > &splitters, std::vector< std::string > &tokens, std::vector< std::string > &pivot_list)
Expands a key into either a VariableReference or tokens.
int set_index(const std::string &key, size_t index, T &&value, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of an array index to a value.
bool is_valid(void) const
Checks to see if the variable reference has been initialized.
virtual void accept(Visitor &visitor) const
Define the accept() operation used for the Visitor pattern.
virtual madara::knowledge::KnowledgeRecord item(void) const
Return the item stored in the node.
static struct madara::knowledge::tags::string_t string
#define madara_logger_ptr_log(logger, level,...)
Fast version of the madara::logger::log method for Logger pointers.
Definition: Logger.h:32
An abstract base class defines a simple abstract implementation of an expression tree node...
Definition: ComponentNode.h:36
Abstract base class for all visitors to all classes that derive from ComponentNode.
Definition: Visitor.h:91
Integer to_integer(void) const
converts the value to an integer.
An exception for unrecoverable KaRL compilation issues.
Definition: KarlException.h:18
virtual madara::knowledge::KnowledgeRecord evaluate(const madara::knowledge::KnowledgeUpdateSettings &settings)
Evaluates the node and its children.
CompositeArrayReference(const std::string &key, ComponentNode *index, madara::knowledge::ThreadSafeContext &context)
Constructor.
knowledge::KnowledgeRecord dec(const madara::knowledge::KnowledgeUpdateSettings &settings=knowledge::KnowledgeUpdateSettings())
Sets the value stored in the node.
bool always_overwrite
Toggle for always overwriting records, regardless of quality, clock values, etc.
madara::knowledge::ThreadSafeContext & context_
KnowledgeRecord * get_record(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Retrieves a knowledge record from the key.
Settings for applying knowledge updates.
Encapsulates a single expression tree.
virtual void visit(const LeafNode &node)=0
Visit a LeafNode.
madara::knowledge::KnowledgeRecord get(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically returns the value of a variable.
KnowledgeRecord retrieve_index(size_t index) const
retrieves the value at an array index.
KnowledgeRecord retrieve_index(const std::string &key, size_t index, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Retrieves a value at a specified index within a knowledge array.
std::string key_
Key for retrieving value of this variable.
std::string to_string(const std::string &delimiter=", ") const
converts the value to a string.
madara::knowledge::VariableReference ref_
std::string expand_key(void) const
Expands the key (if necessary).