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