MADARA  3.4.1
DoubleVector2D.cpp
Go to the documentation of this file.
1 #include "DoubleVector2D.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 DoubleVector2D& 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)
55  {
56  for (size_t i = 0; i < dimensions.x; ++i)
57  {
58  for (size_t j = 0; j < dimensions.y; ++j)
59  {
60  context_->mark_modified(vector_[i][j]);
61  }
62  }
63  }
64 
65  context_->mark_modified(size_);
66  }
67 }
68 
70 {
71  std::stringstream result;
72 
73  result << "DoubleVector2D: ";
74 
75  if (context_)
76  {
77  ContextGuard context_guard(*context_);
78 
79  Indices dimensions = size();
80 
81  result << this->name_;
82  result << " [" << dimensions.x << "," << dimensions.y << "]";
83  result << " = [";
84 
85  if (dimensions.x > 0 && dimensions.y > 0)
86  {
87  for (size_t i = 0; i < dimensions.x; ++i)
88  {
89  result << context_->get(vector_[i][0]).to_string();
90 
91  for (size_t j = 1; j < dimensions.y; ++j)
92  {
93  result << ", " << context_->get(vector_[i][j]).to_string();
94  }
95  result << "\n";
96  }
97  }
98 
99  result << "]";
100  }
101 
102  return result.str();
103 }
104 
106 {
107  modify();
108 }
109 
111 {
112  return get_debug_info();
113 }
114 
117 {
118  return new DoubleVector2D(*this);
119 }
120 
122 {
123  if (context_)
124  {
125  ContextGuard context_guard(*context_);
126  if (index.x < vector_.size() && index.y < vector_[index.x].size())
127  context_->mark_modified(vector_[index.x][index.y]);
128  }
129 }
130 
132  const DoubleVector2D& rhs)
133 {
134  if (this != &rhs)
135  {
136  MADARA_GUARD_TYPE guard(mutex_), guard2(rhs.mutex_);
137 
138  this->context_ = rhs.context_;
139  this->name_ = rhs.name_;
140  this->settings_ = rhs.settings_;
141  this->size_ = rhs.size_;
142  this->vector_ = rhs.vector_;
143  this->delimiter_ = rhs.delimiter_;
144  }
145 }
146 
149 {
150  VariableReference ref;
151 
152  if (context_ && name_ != "")
153  {
154  KnowledgeUpdateSettings keep_local(true);
155  std::stringstream buffer;
156 
157  ContextGuard context_guard(*context_);
158 
159  buffer << name_;
160  buffer << delimiter_;
161  buffer << "size";
162 
163  ref = context_->get_ref(buffer.str(), keep_local);
164  }
165 
166  return ref;
167 }
168 
170  const Dimensions& dimensions, bool delete_vars)
171 {
172  if (context_ && name_ != "")
173  {
174  ContextGuard context_guard(*context_);
175 
177  "DoubleVector2D::resize: resizing to [%d,%d]\n", (int)dimensions.x,
178  (int)dimensions.y);
179 
180  bool is_reset = dimensions.x == 0 && dimensions.y == 0;
181 
182  if (!size_.is_valid())
183  {
184  size_ = get_size_ref();
185  }
186 
187  // save the old size
188  Dimensions old_size = size();
189  Dimensions new_size(dimensions);
190 
192  "DoubleVector2D::resize: old size is [%d,%d]\n", (int)old_size.x,
193  (int)old_size.y);
194 
195  if (is_reset)
196  {
198  "DoubleVector2D::resize: new size is being reset to size in KB\n");
199 
200  new_size.x = old_size.x;
201  new_size.y = old_size.y;
202  }
203  else
204  {
206  "DoubleVector2D::resize: using dimensions passed in.\n");
207 
208  // set the new size
209  std::vector<KnowledgeRecord::Integer> update(2);
210  update[0] = dimensions.x;
211  update[1] = dimensions.y;
212 
213  context_->set(size_, update, settings_);
214  }
215 
216  // correct the vector for the new size
217  vector_.resize(new_size.x);
218 
219  for (size_t i = 0; i < new_size.x; ++i)
220  {
222  "DoubleVector2D::resize: resizing vector_[%d] to %d.\n", (int)i,
223  (int)new_size.y);
224 
225  vector_[i].resize(new_size.y);
226 
227  // create any new VariableReference needed, default is end of old cols
228 
229  size_t start = old_size.y;
230 
231  // if you've gained rows and this is a new row, reset start to 0
232  if (is_reset || (old_size.x < new_size.x && i >= old_size.x))
233  {
234  start = 0;
235  }
236 
238  "DoubleVector2D::resize: creating var_refs from %d->%d.\n",
239  (int)start, (int)new_size.y);
240 
241  // create new VariableReferences
242  for (size_t j = start; j < new_size.y; ++j)
243  {
244  std::stringstream var_name;
245  var_name << this->name_;
246  var_name << delimiter_;
247  var_name << i;
248  var_name << delimiter_;
249  var_name << j;
250 
251  vector_[i][j] = context_->get_ref(var_name.str(), settings_);
252  }
253  }
254 
255  // delete if we need to delete
256  if ((new_size.x < old_size.x || new_size.y < old_size.y) && delete_vars)
257  {
259  "DoubleVector2D::resize: deleting refs: rows: 0->%d.\n",
260  (int)old_size.x);
261 
262  // delete within the old rows
263  for (size_t i = 0; i < old_size.x; ++i)
264  {
265  // by default, delete from new col size to old col size
266  size_t start = new_size.y;
267 
268  // the exception is when we are deleting the entire row
269  if (old_size.x > new_size.x && i >= new_size.x)
270  {
271  start = 0;
272  }
273 
275  "DoubleVector2D::resize: deleting refs: %d:%d->%d.\n", (int)i,
276  (int)start, (int)old_size.x);
277 
278  // delete old columns
279  for (size_t j = start; j < old_size.y; ++j)
280  {
281  std::stringstream var_name;
282  var_name << this->name_;
283  var_name << delimiter_;
284  var_name << i;
285  var_name << delimiter_;
286  var_name << j;
287 
289  "DoubleVector2D::resize: deleting ref: %s.\n",
290  var_name.str().c_str());
291 
292  context_->delete_variable(var_name.str(), settings_);
293  }
294  }
295  }
296  }
297 }
298 
301 {
302  Indices cur_size;
303 
304  if (context_)
305  {
306  KnowledgeRecord record;
307  // lock the KnowledgeBase during access
308  {
309  ContextGuard context_guard(*context_);
310 
311  record = context_->get(size_);
312  }
313 
314  std::vector<KnowledgeRecord::Integer> sizes(record.to_integers());
315  cur_size.x = (size_t)(sizes.size() >= 2 ? sizes[0] : 0);
316  cur_size.y = (size_t)(sizes.size() >= 2 ? sizes[1] : 0);
317  }
318 
319  return cur_size;
320 }
321 
323  const std::string& var_name, KnowledgeBase& knowledge,
324  const Indices& dimensions)
325 {
326  if (context_ != &(knowledge.get_context()) || name_ != var_name)
327  {
328  context_ = &(knowledge.get_context());
329 
330  ContextGuard context_guard(*context_);
331 
332  name_ = var_name;
333 
334  vector_.clear();
335 
336  size_ = get_size_ref();
337 
338  resize(dimensions);
339  }
340 }
341 
343  const std::string& var_name, Variables& knowledge,
344  const Indices& dimensions)
345 {
346  if (context_ != knowledge.get_context() || name_ != var_name)
347  {
348  context_ = knowledge.get_context();
349 
350  ContextGuard context_guard(*context_);
351 
352  name_ = var_name;
353 
354  vector_.clear();
355  resize(dimensions);
356  }
357 }
358 
360  const std::string& var_name, ThreadSafeContext& knowledge,
361  const Indices& dimensions)
362 {
363  if (context_ != &knowledge || name_ != var_name)
364  {
365  context_ = &knowledge;
366 
367  ContextGuard context_guard(*context_);
368 
369  name_ = var_name;
370 
371  vector_.clear();
372  resize(dimensions);
373  }
374 }
375 
377  const std::string& delimiter)
378 {
379  delimiter_ = delimiter;
380  if (context_)
381  {
382  ContextGuard context_guard(*context_);
383 
384  vector_.clear();
385  resize({0, 0});
386  }
387 }
388 
390 {
391  return delimiter_;
392 }
393 
395  std::vector<std::vector<type> >& target) const
396 {
397  KnowledgeUpdateSettings keep_local(true);
398 
399  if (context_)
400  {
401  ContextGuard context_guard(*context_);
402 
403  Indices dimensions = size();
404 
405  target.resize(dimensions.x);
406 
407  for (size_t i = 0; i < dimensions.x; ++i)
408  {
409  target[i].resize(dimensions.y);
410  for (size_t j = 0; j < dimensions.y; ++j)
411  {
412  target[i][j] = context_->get(vector_[i][j], keep_local).to_double();
413  }
414  }
415  }
416 }
417 
420  const Indices& index) const
421 {
422  type result(0);
423 
424  KnowledgeUpdateSettings keep_local(true);
425 
426  if (context_)
427  {
428  ContextGuard context_guard(*context_);
429 
430  if (index.x < vector_.size() && index.y < vector_[index.x].size())
431  {
432  result = context_->get(vector_[index.x][index.y], keep_local).to_double();
433  }
434  }
435 
436  return result;
437 }
438 
440  const Indices& index) const
441 {
442  bool result(false);
443 
444  if (context_)
445  {
446  ContextGuard context_guard(*context_);
447 
448  if (index.x < vector_.size() && index.y < vector_[index.x].size())
449  {
450  result = context_->exists(vector_[index.x][index.y]);
451  }
452  }
453 
454  return result;
455 }
456 
458  const Indices& index, type value)
459 {
460  int result = -1;
461 
462  if (context_)
463  {
464  ContextGuard context_guard(*context_);
465 
466  if (index.x < vector_.size() && index.y < vector_[index.x].size())
467  {
468  result = context_->set(vector_[index.x][index.y], value, settings_);
469  }
470  }
471 
472  return result;
473 }
474 
476  const std::vector<std::vector<type> >& value)
477 {
478  int result = 0;
479 
480  if (context_)
481  {
482  ContextGuard context_guard(*context_);
483 
484  for (size_t i = 0; i < value.size() && i < vector_.size(); ++i)
485  {
486  for (size_t j = 0; j < value[i].size() && j < vector_[i].size(); ++j)
487  {
488  context_->set(vector_[i][j], value[i][j], settings_);
489  }
490  }
491  }
492 
493  return result;
494 }
495 
497  const Indices& index, type value, const KnowledgeUpdateSettings& settings)
498 {
499  int result = -1;
500 
501  if (context_)
502  {
503  ContextGuard context_guard(*context_);
504 
505  if (index.x < vector_.size() && index.y < vector_[index.x].size())
506  {
507  result = context_->set(vector_[index.x][index.y], value, settings);
508  }
509  }
510 
511  return result;
512 }
513 
515  const std::vector<std::vector<type> >& value,
516  const KnowledgeUpdateSettings& settings)
517 {
518  int result = 0;
519 
520  if (context_)
521  {
522  ContextGuard context_guard(*context_);
523 
524  for (size_t i = 0; i < value.size() && i < vector_.size(); ++i)
525  {
526  for (size_t j = 0; j < value[i].size() && j < vector_[i].size(); ++j)
527  {
528  context_->set(vector_[i][j], value[i][j], settings);
529  }
530  }
531  }
532 
533  return result;
534 }
535 
537  const Indices& index, uint32_t quality,
538  const KnowledgeReferenceSettings& settings)
539 {
540  if (context_)
541  {
542  ContextGuard context_guard(*context_);
543 
544  if (index.x < vector_.size() && index.y < vector_[index.x].size())
545  context_->set_quality(
546  vector_[index.x][index.y].get_name(), quality, true, settings);
547  }
548 }
549 
551 {
552  bool result(false);
553 
555  "DoubleVector2D::is_true: Checking for truth\n");
556 
557  if (context_)
558  {
559  ContextGuard context_guard(*context_);
560 
561  result = true;
562 
564  "DoubleVector2D::is_true: context was not null. Result changed to %d\n",
565  (int)result);
566 
567  for (size_t i = 0; i < vector_.size(); ++i)
568  {
569  for (size_t j = 0; j < vector_[i].size(); ++i)
570  {
572  "DoubleVector2D::is_true: checking [%d,%d], is_false of %d. \n",
573  (int)i, (int)j, (int)context_->get(vector_[i][j]).is_false());
574 
575  if (context_->get(vector_[i][j]).is_false())
576  {
578  "DoubleVector2D::is_true: result is false, breaking\n");
579 
580  result = false;
581  break;
582  }
583  }
584  }
585 
586  if (vector_.size() == 0)
587  result = false;
588  }
589 
591  "DoubleVector2D::is_true: final result is %d\n", (int)result);
592 
593  return result;
594 }
595 
597 {
598  return !is_true();
599 }
600 
602 {
603  return is_true();
604 }
605 
607 {
608  return is_false();
609 }
#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 2D array of doubles as a virtual overlay in the KnowledgeBase.
VariableReference get_size_ref(void)
Returns a reference to the size of 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.
ThreadSafeContext * context_
Variable context that we are modifying.
void set_name(const std::string &var_name, KnowledgeBase &knowledge, const Dimensions &dimensions={0, 0})
Sets the variable name that this refers to.
void modify(void)
Mark the vector as modified.
std::string get_delimiter(void)
Gets the delimiter for adding and detecting subvariables.
virtual std::string get_debug_info_(void)
Returns the type of the container along with name and any other useful information.
std::string get_debug_info(void)
Returns the type of the container along with name and any other useful information.
int set(const Indices &index, double value)
Sets a knowledge variable to a specified value.
std::vector< std::vector< VariableReference > > vector_
Values of the array.
bool is_true(void) const
Determines if all values in the vector are true.
void operator=(const DoubleVector2D &rhs)
Assignment operator.
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.
void resize(const Dimensions &dimensions, bool delete_vars=true)
Resizes the vector.
VariableReference size_
Reference to the size of 2D array.
void set_delimiter(const std::string &delimiter)
Sets the delimiter for adding and detecting subvariables.
DoubleVector2D(const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings(), const std::string &delimiter=".")
Default constructor.
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 ...
bool is_false(void) const
Determines if the value of the vector is false.
Dimensions size(void) const
Returns the size of the local vector.
std::string delimiter_
Delimiter for the prefix to subvars.
virtual void modify_(void)
Polymorphic modify method used by collection containers.
bool exists(const Indices &index) const
Checks to see if the index has ever been assigned a value.
double type
convenience typedef for element type
void copy_to(std::vector< std::vector< type > > &target) const
Copies the vector elements to an STL vector.
virtual BaseContainer * clone(void) const
Clones this container.
constexpr string_t string
Provides functions and classes for the distributed knowledge base.