MADARA  3.1.8
IntegerVector2D.cpp
Go to the documentation of this file.
1 #include "IntegerVector2D.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 IntegerVector2D & 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 << "IntegerVector2D: ";
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 IntegerVector2D (*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 IntegerVector2D & 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  "IntegerVector2D::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  "IntegerVector2D::resize: old size is [%d,%d]\n",
209  (int)old_size.x, (int)old_size.y);
210 
211  if (is_reset)
212  {
214  "IntegerVector2D::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  "IntegerVector2D::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  "IntegerVector2D::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  "IntegerVector2D::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  "IntegerVector2D::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  "IntegerVector2D::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  "IntegerVector2D::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_integer ();
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_integer ();
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  "IntegerVector2D::is_true: Checking for truth\n");
595 
596  if (context_)
597  {
598  ContextGuard context_guard (*context_);
599 
600  result = true;
601 
603  "IntegerVector2D::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  "IntegerVector2D::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  "IntegerVector2D::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  "IntegerVector2D::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.
bool exists(const Indices &index) const
Checks to see if the index has ever been assigned a value.
int set(const Indices &index, type value)
Sets a knowledge variable to a specified value.
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.
virtual BaseContainer * clone(void) const
Clones this container.
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.
type operator[](const Indices &index) const
Retrieves an index from the multi-dimensional array.
madara::knowledge::KnowledgeRecord get(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically returns the value of a variable.
Manages a 2D array of integers as a virtual overlay in the KnowledgeBase.
void operator=(const IntegerVector2D &rhs)
Assignment operator.
std::string name_
Prefix of variable.
VariableReference get_size_ref(void)
Returns a reference to the size of vector.
void set_name(const std::string &var_name, KnowledgeBase &knowledge, const Dimensions &dimensions={0, 0})
Sets the variable name that this refers to.
This class stores variables and their values for use by any entity needing state information in a thr...
void resize(const Dimensions &dimensions, bool delete_vars=true)
Resizes the vector.
std::string delimiter_
Delimiter for the prefix to subvars.
ThreadSafeContext * context_
Variable context that we are modifying.
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.
IntegerVector2D(const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings(), const std::string &delimiter=".")
Default constructor.
bool exists(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically checks to see if a variable already exists.
std::string get_delimiter(void)
Gets the delimiter for adding and detecting subvariables.
void modify(void)
Mark the vector as modified.
virtual void modify_(void)
Polymorphic modify method used by collection containers.
A thread-safe guard for a context or knowledge base.
Definition: ContextGuard.h:23
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:44
bool is_true(void) const
Determines if all values in the vector are true.
VariableReference size_
Reference to the size of 2D array.
Integer to_integer(void) const
converts the value to an integer
static constexpr struct madara::knowledge::tags::string_t string
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.
std::vector< Integer > to_integers(void) const
converts the value to a vector of integers
Provides functions and classes for the distributed knowledge base.
KnowledgeUpdateSettings settings_
Settings for modifications.
VariableReference get_ref(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Atomically returns a reference to the variable.
Settings for applying knowledge updates.
virtual std::string get_debug_info_(void)
Returns the type of the container along with name and any other useful information.
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.
Dimensions size(void) const
Returns the size of the local vector.
virtual bool is_true_(void) const
Polymorphic is true method which can be used to determine if all values in the container are true...
bool is_false(void) const
Checks to see if the record is false.
Settings for applying knowledge updates.
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 ...
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
std::vector< std::vector< VariableReference > > vector_
Values of the array.
void copy_to(std::vector< std::vector< type > > &target) const
Copies the vector elements to an STL vector.
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...
std::string get_debug_info(void)
Returns the type of the container along with name and any other useful information.
ThreadSafeContext * get_context(void)
Returns the ThreadSafeContext associated with this Variables facade.
KnowledgeRecord::Integer type
convenience typedef for element type