MADARA  3.1.8
DoubleVector2D.cpp
Go to the documentation of this file.
1 #include "DoubleVector2D.h"
3 
4 
6  const KnowledgeUpdateSettings & settings,
7  const std::string & delimiter)
8  : BaseContainer ("", settings), context_ (0), delimiter_ (delimiter)
9 {
10 }
11 
13  const std::string & name,
15  const Dimensions & dimensions,
16  bool delete_vars,
17  const KnowledgeUpdateSettings & settings,
18  const std::string & delimiter)
19  : BaseContainer (name, settings), context_ (&(knowledge.get_context ())),
20  delimiter_ (delimiter)
21 {
22  size_ = get_size_ref ();
23  resize (dimensions, delete_vars);
24 }
25 
27  const std::string & name,
29  const Dimensions & dimensions,
30  bool delete_vars,
31  const KnowledgeUpdateSettings & settings,
32  const std::string & delimiter)
33  : BaseContainer (name, settings), context_ (knowledge.get_context ()),
34  delimiter_ (delimiter)
35 {
36  size_ = get_size_ref ();
37  resize (dimensions, delete_vars);
38 }
39 
41  const DoubleVector2D & rhs)
42 : BaseContainer (rhs), context_ (rhs.context_),
43  vector_ (rhs.vector_),
44  size_ (rhs.size_),
46 {
47 }
48 
49 
51 {
52 
53 }
54 
55 void
57 {
58  if (context_ && name_ != "")
59  {
60  ContextGuard context_guard (*context_);
61 
62  Indices dimensions = size ();
63 
64  if (dimensions.x > 0 && dimensions.y > 0)
65  {
66  for (size_t i = 0; i < dimensions.x; ++i)
67  {
68  for (size_t j = 0; j < dimensions.y; ++j)
69  {
71  }
72  }
73  }
74 
76  }
77 }
78 
81 {
82  std::stringstream result;
83 
84  result << "DoubleVector2D: ";
85 
86  if (context_)
87  {
88  ContextGuard context_guard (*context_);
89 
90  Indices dimensions = size ();
91 
92  result << this->name_;
93  result << " [" << dimensions.x << "," << dimensions.y << "]";
94  result << " = [";
95 
96  if (dimensions.x > 0 && dimensions.y > 0)
97  {
98  for (size_t i = 0; i < dimensions.x; ++i)
99  {
100  result << context_->get (vector_[i][0]).to_string ();
101 
102  for (size_t j = 1; j < dimensions.y; ++j)
103  {
104  result << ", " << context_->get (vector_[i][j]).to_string ();
105  }
106  result << "\n";
107  }
108  }
109 
110  result << "]";
111  }
112 
113  return result.str ();
114 }
115 
116 void
118 {
119  modify ();
120 }
121 
124 {
125  return get_debug_info ();
126 }
127 
130 {
131  return new DoubleVector2D (*this);
132 }
133 
134 void
136 {
137  if (context_)
138  {
139  ContextGuard context_guard (*context_);
140  if (index.x < vector_.size () && index.y < vector_[index.x].size ())
141  context_->mark_modified (vector_[index.x][index.y]);
142  }
143 }
144 
145 void
147  const DoubleVector2D & rhs)
148 {
149  if (this != &rhs)
150  {
151  MADARA_GUARD_TYPE guard (mutex_), guard2 (rhs.mutex_);
152 
153  this->context_ = rhs.context_;
154  this->name_ = rhs.name_;
155  this->settings_ = rhs.settings_;
156  this->size_ = rhs.size_;
157  this->vector_ = rhs.vector_;
158  this->delimiter_ = rhs.delimiter_;
159  }
160 }
161 
164 {
165  VariableReference ref;
166 
167  if (context_ && name_ != "")
168  {
169  KnowledgeUpdateSettings keep_local (true);
170  std::stringstream buffer;
171 
172  ContextGuard context_guard (*context_);
173 
174  buffer << name_;
175  buffer << delimiter_;
176  buffer << "size";
177 
178  ref = context_->get_ref (buffer.str (), keep_local);
179  }
180 
181  return ref;
182 }
183 
184 void
186  const Dimensions & dimensions, bool delete_vars)
187 {
188  if (context_ && name_ != "")
189  {
190  ContextGuard context_guard (*context_);
191 
193  "DoubleVector2D::resize: resizing to [%d,%d]\n",
194  (int)dimensions.x, (int)dimensions.y);
195 
196  bool is_reset = dimensions.x == 0 && dimensions.y == 0;
197 
198  if (!size_.is_valid ())
199  {
200  size_ = get_size_ref ();
201  }
202 
203  // save the old size
204  Dimensions old_size = size ();
205  Dimensions new_size (dimensions);
206 
208  "DoubleVector2D::resize: old size is [%d,%d]\n",
209  (int)old_size.x, (int)old_size.y);
210 
211  if (is_reset)
212  {
214  "DoubleVector2D::resize: new size is being reset to size in KB\n");
215 
216  new_size.x = old_size.x;
217  new_size.y = old_size.y;
218  }
219  else
220  {
221 
223  "DoubleVector2D::resize: using dimensions passed in.\n");
224 
225  // set the new size
226  std::vector <KnowledgeRecord::Integer> update (2);
227  update[0] = dimensions.x;
228  update[1] = dimensions.y;
229 
230  context_->set (size_, update, settings_);
231  }
232 
233  // correct the vector for the new size
234  vector_.resize (new_size.x);
235 
236  for (size_t i = 0; i < new_size.x; ++i)
237  {
239  "DoubleVector2D::resize: resizing vector_[%d] to %d.\n",
240  (int)i, (int)new_size.y);
241 
242  vector_[i].resize (new_size.y);
243 
244  // create any new VariableReference needed, default is end of old cols
245 
246  size_t start = old_size.y;
247 
248 
249  // if you've gained rows and this is a new row, reset start to 0
250  if (is_reset || (old_size.x < new_size.x && i >= old_size.x))
251  {
252  start = 0;
253  }
254 
256  "DoubleVector2D::resize: creating var_refs from %d->%d.\n",
257  (int)start, (int)new_size.y);
258 
259  // create new VariableReferences
260  for (size_t j = start; j < new_size.y; ++j)
261  {
262  std::stringstream var_name;
263  var_name << this->name_;
264  var_name << delimiter_;
265  var_name << i;
266  var_name << delimiter_;
267  var_name << j;
268 
269  vector_[i][j] = context_->get_ref (var_name.str (), settings_);
270  }
271  }
272 
273  // delete if we need to delete
274  if ((new_size.x < old_size.x || new_size.y < old_size.y) && delete_vars)
275  {
277  "DoubleVector2D::resize: deleting refs: rows: 0->%d.\n",
278  (int)old_size.x);
279 
280  // delete within the old rows
281  for (size_t i = 0; i < old_size.x; ++i)
282  {
283  // by default, delete from new col size to old col size
284  size_t start = new_size.y;
285 
286  // the exception is when we are deleting the entire row
287  if (old_size.x > new_size.x && i >= new_size.x)
288  {
289  start = 0;
290  }
291 
293  "DoubleVector2D::resize: deleting refs: %d:%d->%d.\n",
294  (int)i, (int)start, (int)old_size.x);
295 
296  // delete old columns
297  for (size_t j = start; j < old_size.y; ++j)
298  {
299  std::stringstream var_name;
300  var_name << this->name_;
301  var_name << delimiter_;
302  var_name << i;
303  var_name << delimiter_;
304  var_name << j;
305 
307  "DoubleVector2D::resize: deleting ref: %s.\n",
308  var_name.str ().c_str ());
309 
310  context_->delete_variable (var_name.str (), settings_);
311  }
312  }
313  }
314  }
315 }
316 
319 {
320  Indices cur_size;
321 
322  if (context_)
323  {
324  KnowledgeRecord record;
325  // lock the KnowledgeBase during access
326  {
327  ContextGuard context_guard (*context_);
328 
329  record = context_->get (size_);
330  }
331 
332  std::vector <KnowledgeRecord::Integer> sizes (record.to_integers ());
333  cur_size.x = (size_t) (sizes.size () >= 2 ? sizes[0] : 0);
334  cur_size.y = (size_t) (sizes.size () >= 2 ? sizes[1] : 0);
335  }
336 
337  return cur_size;
338 }
339 
340 void
342  const std::string & var_name,
343  KnowledgeBase & knowledge, const Indices & dimensions)
344 {
345  if (context_ != &(knowledge.get_context ()) || name_ != var_name)
346  {
347  context_ = &(knowledge.get_context ());
348 
349  ContextGuard context_guard (*context_);
350 
351  name_ = var_name;
352 
353  vector_.clear ();
354 
355  size_ = get_size_ref ();
356 
357  resize (dimensions);
358  }
359 }
360 
361 void
363  const std::string & var_name,
364  Variables & knowledge, const Indices & dimensions)
365 {
366  if (context_ != knowledge.get_context () || name_ != var_name)
367  {
368  context_ = knowledge.get_context ();
369 
370  ContextGuard context_guard (*context_);
371 
372  name_ = var_name;
373 
374  vector_.clear ();
375  resize (dimensions);
376  }
377 }
378 
379 void
381  const std::string & var_name,
382  ThreadSafeContext & knowledge, const Indices & dimensions)
383 {
384  if (context_ != &knowledge || name_ != var_name)
385  {
386  context_ = &knowledge;
387 
388  ContextGuard context_guard (*context_);
389 
390  name_ = var_name;
391 
392  vector_.clear ();
393  resize (dimensions);
394  }
395 }
396 
397 void
399 const std::string & delimiter)
400 {
401  delimiter_ = delimiter;
402  if (context_)
403  {
404  ContextGuard context_guard (*context_);
405 
406  vector_.clear ();
407  resize ({0,0});
408  }
409 }
410 
411 
414 {
415  return delimiter_;
416 }
417 
418 void
420  std::vector <std::vector <type> > & target) const
421 {
422  KnowledgeUpdateSettings keep_local (true);
423 
424  if (context_)
425  {
426  ContextGuard context_guard (*context_);
427 
428  Indices dimensions = size ();
429 
430  target.resize (dimensions.x);
431 
432  for (size_t i = 0; i < dimensions.x; ++i)
433  {
434  target[i].resize (dimensions.y);
435  for (size_t j = 0; j < dimensions.y; ++j)
436  {
437  target[i][j] = context_->get (vector_[i][j], keep_local).to_double ();
438  }
439  }
440  }
441 }
442 
445  const Indices & index) const
446 {
447  type result (0);
448 
449  KnowledgeUpdateSettings keep_local (true);
450 
451  if (context_)
452  {
453  ContextGuard context_guard (*context_);
454 
455  if (index.x < vector_.size () && index.y < vector_[index.x].size ())
456  {
457  result = context_->get (
458  vector_[index.x][index.y], keep_local).to_double ();
459  }
460  }
461 
462  return result;
463 }
464 
465 bool
467  const Indices & index) const
468 {
469  bool result (false);
470 
471  if (context_)
472  {
473  ContextGuard context_guard (*context_);
474 
475  if (index.x < vector_.size () && index.y < vector_[index.x].size ())
476  {
477  result = context_->exists (vector_[index.x][index.y]);
478  }
479  }
480 
481  return result;
482 }
483 
484 int
486 const Indices & index,
487 type value)
488 {
489  int result = -1;
490 
491  if (context_)
492  {
493  ContextGuard context_guard (*context_);
494 
495  if (index.x < vector_.size () && index.y < vector_[index.x].size ())
496  {
497  result = context_->set (vector_[index.x][index.y], value, settings_);
498  }
499  }
500 
501  return result;
502 }
503 
504 
505 int
507 const std::vector<std::vector<type> > & value)
508 {
509  int result = 0;
510 
511  if (context_)
512  {
513  ContextGuard context_guard (*context_);
514 
515  for (size_t i = 0; i < value.size () && i < vector_.size (); ++i)
516  {
517  for (size_t j = 0; j < value[i].size () && j < vector_[i].size (); ++j)
518  {
519  context_->set (vector_[i][j], value[i][j], settings_);
520  }
521  }
522  }
523 
524  return result;
525 }
526 
527 int
529  const Indices & index,
530  type value,
531  const KnowledgeUpdateSettings & settings)
532 {
533  int result = -1;
534 
535  if (context_)
536  {
537  ContextGuard context_guard (*context_);
538 
539  if (index.x < vector_.size () && index.y < vector_[index.x].size ())
540  {
541  result = context_->set (vector_[index.x][index.y], value, settings);
542  }
543  }
544 
545  return result;
546 }
547 
548 
549 int
551  const std::vector<std::vector<type> > & value,
552  const KnowledgeUpdateSettings & settings)
553 {
554  int result = 0;
555 
556  if (context_)
557  {
558  ContextGuard context_guard (*context_);
559 
560  for (size_t i = 0; i < value.size () && i < vector_.size (); ++i)
561  {
562  for (size_t j = 0; j < value[i].size () && j < vector_[i].size (); ++j)
563  {
564  context_->set (vector_[i][j], value[i][j], settings);
565  }
566  }
567  }
568 
569  return result;
570 }
571 
572 void
574  const Indices & index,
575  uint32_t quality,
576  const KnowledgeReferenceSettings & settings)
577 {
578  if (context_)
579  {
580  ContextGuard context_guard (*context_);
581 
582  if (index.x < vector_.size () && index.y < vector_[index.x].size ())
583  context_->set_quality (vector_[index.x][index.y].get_name (), quality,
584  true, settings);
585  }
586 }
587 
588 bool
590 {
591  bool result (false);
592 
594  "DoubleVector2D::is_true: Checking for truth\n");
595 
596  if (context_)
597  {
598  ContextGuard context_guard (*context_);
599 
600  result = true;
601 
603  "DoubleVector2D::is_true: context was not null. Result changed to %d\n",
604  (int)result);
605 
606  for (size_t i = 0; i < vector_.size (); ++i)
607  {
608  for (size_t j = 0; j < vector_[i].size (); ++i)
609  {
611  "DoubleVector2D::is_true: checking [%d,%d], is_false of %d. \n",
612  (int)i, (int)j, (int)context_->get (vector_[i][j]).is_false ());
613 
614  if (context_->get (vector_[i][j]).is_false ())
615  {
617  "DoubleVector2D::is_true: result is false, breaking\n");
618 
619  result = false;
620  break;
621  }
622  }
623  }
624 
625  if (vector_.size () == 0)
626  result = false;
627  }
628 
630  "DoubleVector2D::is_true: final result is %d\n", (int)result);
631 
632  return result;
633 }
634 
635 bool
637 {
638  return !is_true ();
639 }
640 
641 
642 bool
644 {
645  return is_true ();
646 }
647 
648 bool
650 {
651  return is_false ();
652 }
653 
This class encapsulates an entry in a KnowledgeBase.
int set(const std::string &key, T &&value, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of a variable to the specific record.
virtual std::string get_debug_info_(void)
Returns the type of the container along with name and any other useful information.
void operator=(const DoubleVector2D &rhs)
Assignment operator.
madara::knowledge::KnowledgeRecord get(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically returns the value of a variable.
double to_double(void) const
converts the value to a float/double
std::string name_
Prefix of variable.
std::string get_debug_info(void)
Returns the type of the container along with name and any other useful information.
This class stores variables and their values for use by any entity needing state information in a thr...
Manages a 2D array of doubles as a virtual overlay in the KnowledgeBase.
virtual bool is_false_(void) const
Polymorphic is false method which can be used to determine if at least one value in the container is ...
virtual void modify_(void)
Polymorphic modify method used by collection containers.
MADARA_LOCK_TYPE mutex_
guard for access and changes
Optimized reference to a variable within the knowledge base.
#define madara_logger_log(logger, level,...)
Fast version of the madara::logger::log method.
Definition: Logger.h:20
bool is_valid(void) const
Checks to see if the variable reference has been initialized.
bool exists(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically checks to see if a variable already exists.
virtual bool is_true_(void) const
Polymorphic is true method which can be used to determine if all values in the container are true...
void set_name(const std::string &var_name, KnowledgeBase &knowledge, const Dimensions &dimensions={0, 0})
Sets the variable name that this refers to.
double type
convenience typedef for element type
A thread-safe guard for a context or knowledge base.
Definition: ContextGuard.h:23
std::string get_delimiter(void)
Gets the delimiter for adding and detecting subvariables.
virtual BaseContainer * clone(void) const
Clones this container.
std::vector< std::vector< VariableReference > > vector_
Values of the array.
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:44
ThreadSafeContext * context_
Variable context that we are modifying.
bool exists(const Indices &index) const
Checks to see if the index has ever been assigned a value.
static constexpr struct madara::knowledge::tags::string_t string
type operator[](const Indices &index) const
Retrieves an index from the multi-dimensional array.
void set_quality(const Indices &index, uint32_t quality, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings(false))
Sets the quality of writing to a certain variable from this entity.
ThreadSafeContext & get_context(void)
Returns the ThreadSafeContext associated with this Knowledge Base.
bool delete_variable(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Deletes the key.
bool is_false(void) const
Determines if the value of the vector is false.
void set_delimiter(const std::string &delimiter)
Sets the delimiter for adding and detecting subvariables.
void copy_to(std::vector< std::vector< type > > &target) const
Copies the vector elements to an STL vector.
std::vector< Integer > to_integers(void) const
converts the value to a vector of integers
Dimensions size(void) const
Returns the size of the local vector.
Provides functions and classes for the distributed knowledge base.
void modify(void)
Mark the vector as modified.
KnowledgeUpdateSettings settings_
Settings for modifications.
void resize(const Dimensions &dimensions, bool delete_vars=true)
Resizes the vector.
std::string delimiter_
Delimiter for the prefix to subvars.
VariableReference get_ref(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Atomically returns a reference to the variable.
Settings for applying knowledge updates.
bool is_true(void) const
Determines if all values in the vector are true.
VariableReference size_
Reference to the size of 2D array.
uint32_t set_quality(const std::string &key, uint32_t quality, bool force_update, const KnowledgeReferenceSettings &settings)
Atomically sets quality of this process for a variable.
logger::Logger & get_logger(void) const
Gets the logger used for information printing.
bool is_false(void) const
Checks to see if the record is false.
Settings for applying knowledge updates.
int set(const Indices &index, double value)
Sets a knowledge variable to a specified value.
VariableReference get_size_ref(void)
Returns a reference to the size of vector.
std::string to_string(const std::string &delimiter=", ") const
converts the value to a string.
Provides an interface for external functions into the MADARA KaRL variable settings.
This class is an abstract base class for all containers.
Definition: BaseContainer.h:33
void mark_modified(const VariableReference &variable, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Marks the variable reference as updated for the purposes of sending or checkpointing knowledge (for g...
DoubleVector2D(const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings(), const std::string &delimiter=".")
Default constructor.
ThreadSafeContext * get_context(void)
Returns the ThreadSafeContext associated with this Variables facade.