MADARA  3.4.1
IntegerVector.cpp
Go to the documentation of this file.
1 #include "IntegerVector.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, int size,
12  bool delete_vars, const KnowledgeUpdateSettings& settings,
13  const std::string& delimiter)
14  : BaseContainer(name, settings),
15  context_(&(knowledge.get_context())),
16  delimiter_(delimiter)
17 {
18  size_ = get_size_ref();
19  resize(size, delete_vars);
20 }
21 
23  const std::string& name, Variables& knowledge, int size, bool delete_vars,
24  const KnowledgeUpdateSettings& settings, const std::string& delimiter)
25  : BaseContainer(name, settings),
26  context_(knowledge.get_context()),
27  delimiter_(delimiter)
28 {
29  size_ = get_size_ref();
30  resize(size, delete_vars);
31 }
32 
34  const IntegerVector& rhs)
35  : BaseContainer(rhs),
36  context_(rhs.context_),
37  vector_(rhs.vector_),
38  size_(rhs.size_)
39 {
40 }
41 
43 
45 {
46  if (context_ && name_ != "")
47  {
48  ContextGuard context_guard(*context_);
49  for (size_t index = 0; index < vector_.size(); ++index)
50  context_->mark_modified(vector_[index]);
51 
52  context_->mark_modified(size_);
53  }
54 }
55 
57 {
58  std::stringstream result;
59 
60  result << "Integer Vector: ";
61 
62  if (context_)
63  {
64  ContextGuard context_guard(*context_);
65  MADARA_GUARD_TYPE guard(mutex_);
66  size_t elements = vector_.size();
67 
68  result << this->name_;
69  result << " [" << elements << "]";
70  result << " = [";
71 
72  if (elements > 0)
73  {
74  result << context_->get(vector_[0]).to_string();
75 
76  for (size_t index = 1; index < elements; ++index)
77  {
78  result << ", " << context_->get(vector_[index]).to_string();
79  }
80  }
81 
82  result << "]";
83  }
84 
85  return result.str();
86 }
87 
89 {
90  modify();
91 }
92 
94 {
95  return get_debug_info();
96 }
97 
100 {
101  return new IntegerVector(*this);
102 }
103 
105 {
106  if (context_ && name_ != "" && index < vector_.size())
107  {
108  ContextGuard context_guard(*context_);
109  context_->mark_modified(vector_[index]);
110  }
111 }
112 
114  const IntegerVector& rhs)
115 {
116  if (this != &rhs)
117  {
118  MADARA_GUARD_TYPE guard(mutex_), guard2(rhs.mutex_);
119 
120  this->context_ = rhs.context_;
121  this->name_ = rhs.name_;
122  this->settings_ = rhs.settings_;
123  this->size_ = rhs.size_;
124  this->vector_ = rhs.vector_;
125  this->delimiter_ = rhs.delimiter_;
126  }
127 }
128 
130 {
131  if (context_ && name_ != "")
132  {
133  ContextGuard context_guard(*context_);
134  MADARA_GUARD_TYPE guard(mutex_);
135 
136  if (!size_.is_valid())
137  {
138  size_ = get_size_ref();
139  }
140 
141  size_t i = size();
142  resize((int)i + 1);
143  set(i, value);
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  MADARA_GUARD_TYPE guard(mutex_);
159 
160  buffer << name_;
161  buffer << delimiter_;
162  buffer << "size";
163 
164  ref = context_->get_ref(buffer.str(), keep_local);
165  }
166 
167  return ref;
168 }
169 
171  int size, bool delete_vars)
172 {
173  if (context_ && name_ != "")
174  {
175  ContextGuard context_guard(*context_);
176  MADARA_GUARD_TYPE guard(mutex_);
177 
178  if (!size_.is_valid())
179  {
180  size_ = get_size_ref();
181  }
182 
183  if (size >= 0)
184  {
185  size_t old_size = vector_.size();
186 
187  if (old_size != (size_t)size)
188  {
189  vector_.resize(size);
190 
191  context_->set(
192  size_, knowledge::KnowledgeRecord::Integer(size), settings_);
193 
194  if ((size_t)size > old_size)
195  {
196  for (; old_size < (size_t)size; ++old_size)
197  {
198  std::stringstream buffer;
199  buffer << name_;
200  buffer << delimiter_;
201  buffer << old_size;
202  vector_[old_size] = context_->get_ref(buffer.str(), settings_);
203  }
204  }
205  else if (delete_vars)
206  {
207  for (; (size_t)size < old_size; ++size)
208  {
209  std::stringstream buffer;
210  buffer << name_;
211  buffer << delimiter_;
212  buffer << size;
213 
214  context_->delete_variable(buffer.str(), settings_);
215  }
216  }
217  }
218  }
219  else
220  {
221  // dynamically allocate size from the context
222  size_t cur_size = (size_t)context_->get(size_, settings_).to_integer();
223 
224  size_t old_size = vector_.size();
225 
226  if (old_size != cur_size)
227  {
228  vector_.resize(cur_size);
229 
230  if (cur_size > old_size)
231  {
232  for (; old_size < cur_size; ++old_size)
233  {
234  std::stringstream buffer;
235  buffer << name_;
236  buffer << delimiter_;
237  buffer << old_size;
238  vector_[old_size] = context_->get_ref(buffer.str(), settings_);
239  }
240  }
241  else if (delete_vars)
242  {
243  for (; cur_size < old_size; ++cur_size)
244  {
245  std::stringstream buffer;
246  buffer << name_;
247  buffer << delimiter_;
248  buffer << cur_size;
249 
250  context_->delete_variable(buffer.str(), settings_);
251  }
252  }
253  }
254  }
255  }
256 }
257 
259 {
260  MADARA_GUARD_TYPE guard(mutex_);
261  return vector_.size();
262 }
263 
265  const std::string& var_name, KnowledgeBase& knowledge, int size)
266 {
267  if (context_ != &(knowledge.get_context()) || name_ != var_name)
268  {
269  context_ = &(knowledge.get_context());
270 
271  ContextGuard context_guard(*context_);
272  MADARA_GUARD_TYPE guard(mutex_);
273 
274  name_ = var_name;
275 
276  vector_.clear();
277 
278  size_ = get_size_ref();
279 
280  resize(size);
281  }
282 }
283 
285  const std::string& var_name, Variables& knowledge, int size)
286 {
287  if (context_ != knowledge.get_context() || name_ != var_name)
288  {
289  context_ = knowledge.get_context();
290 
291  ContextGuard context_guard(*context_);
292  MADARA_GUARD_TYPE guard(mutex_);
293 
294  name_ = var_name;
295 
296  vector_.clear();
297  resize(size);
298  }
299 }
300 
302  const std::string& var_name, ThreadSafeContext& knowledge, int size)
303 {
304  if (context_ != &knowledge || name_ != var_name)
305  {
306  context_ = &knowledge;
307 
308  ContextGuard context_guard(*context_);
309  MADARA_GUARD_TYPE guard(mutex_);
310 
311  name_ = var_name;
312 
313  vector_.clear();
314  resize(size);
315  }
316 }
317 
319  const std::string& delimiter)
320 {
321  delimiter_ = delimiter;
322  if (context_)
323  {
324  ContextGuard context_guard(*context_);
325  MADARA_GUARD_TYPE guard(mutex_);
326 
327  vector_.clear();
328  resize(-1);
329  }
330 }
331 
333 {
334  return delimiter_;
335 }
336 
338  IntegerVector& other, bool refresh_keys, bool delete_keys)
339 {
340  if (context_ && other.context_)
341  {
342  std::lock(*context_, *other.context_, mutex_, other.mutex_);
343 
344  ContextGuard context_guard(*context_, std::adopt_lock);
345  ContextGuard other_context_guard(*other.context_, std::adopt_lock);
346  MADARA_GUARD_TYPE guard(mutex_, std::adopt_lock),
347  guard2(other.mutex_, std::adopt_lock);
348 
349  if (refresh_keys)
350  {
351  other.resize();
352  this->resize();
353  }
354 
355  size_t other_size = other.vector_.size();
356  size_t this_size = this->vector_.size();
357 
358  for (size_t i = 0; i < this_size; ++i)
359  {
360  // temp = this[i];
362  context_->get(this->vector_[i], settings_);
363 
364  if (i < other_size)
365  {
366  // this[i] = other[i];
367  context_->set(this->vector_[i],
368  context_->get(other.vector_[i], other.settings_), settings_);
369 
370  // other[i] = temp;
371  other.context_->set(other.vector_[i], temp, other.settings_);
372  }
373  else
374  {
375  if (delete_keys)
376  {
377  std::stringstream buffer;
378  buffer << this->name_;
379  buffer << delimiter_;
380  buffer << i;
381  this->context_->delete_variable(buffer.str(), other.settings_);
382  }
383  else
384  {
386  this->context_->set(this->vector_[i], zero, this->settings_);
387  }
388 
389  {
390  std::stringstream buffer;
391  buffer << other.name_;
392  buffer << delimiter_;
393  buffer << i;
394 
395  // other[i] = temp;
396  other.context_->set(buffer.str(), temp, other.settings_);
397  }
398  }
399  }
400 
401  // copy the other vector's elements to this vector's location
402  for (size_t i = this_size; i < other_size; ++i)
403  {
404  std::stringstream buffer;
405  buffer << this->name_;
406  buffer << delimiter_;
407  buffer << i;
408  context_->set(buffer.str(),
409  other.context_->get(other.vector_[i], other.settings_),
410  this->settings_);
411  }
412 
413  // set the size appropriately
414  this->context_->set(this->size_,
415  knowledge::KnowledgeRecord::Integer(other_size), this->settings_);
416  other.context_->set(other.size_,
418 
419  if (refresh_keys)
420  {
421  this->resize(-1, true);
422  other.resize(-1, true);
423  }
424  }
425 }
426 
428  IntegerVector& other)
429 {
430  if (context_ && other.context_)
431  {
432  std::lock(*context_, *other.context_, mutex_, other.mutex_);
433 
434  ContextGuard context_guard(*context_, std::adopt_lock);
435  ContextGuard other_context_guard(*other.context_, std::adopt_lock);
436  MADARA_GUARD_TYPE guard(mutex_, std::adopt_lock),
437  guard2(other.mutex_, std::adopt_lock);
438 
439  size_t other_size = other.vector_.size();
440  size_t this_size = this->vector_.size();
441 
442  size_t size = other_size + this_size;
443  other.resize((int)size);
444 
445  for (size_t i = 0, j = other_size; i < this_size; ++i, ++j)
446  {
447  other.context_->set(other.vector_[j], (*this)[i], other.settings_);
448  }
449 
450  this->resize(0, true);
451  }
452 }
453 
455  KnowledgeVector& target) const
456 {
457  if (context_)
458  {
459  ContextGuard context_guard(*context_);
460  MADARA_GUARD_TYPE guard(mutex_);
461 
462  target.resize(vector_.size());
463 
464  for (size_t i = 0; i < vector_.size(); ++i)
465  {
466  target[i] = knowledge::KnowledgeRecord((*this)[i]);
467  }
468  }
469 }
470 
472  std::vector<type>& target) const
473 {
474  if (context_)
475  {
476  ContextGuard context_guard(*context_);
477  MADARA_GUARD_TYPE guard(mutex_);
478 
479  target.resize(vector_.size());
480 
481  for (size_t i = 0; i < vector_.size(); ++i)
482  {
483  target[i] = (*this)[i];
484  }
485  }
486 }
487 
489 {
490  bool result(false);
491 
492  if (index < vector_.size() && context_)
493  {
494  ContextGuard context_guard(*context_);
495  MADARA_GUARD_TYPE guard(mutex_);
496  result = context_->exists(vector_[index]);
497  }
498 
499  return result;
500 }
501 
504 {
506  KnowledgeUpdateSettings keep_local(true);
507 
508  if (index < vector_.size() && context_)
509  {
510  ContextGuard context_guard(*context_);
511  MADARA_GUARD_TYPE guard(mutex_);
512  result = context_->get(vector_[index], keep_local);
513  }
514 
515  return result.to_integer();
516 }
517 
520 {
522  KnowledgeUpdateSettings keep_local(true);
523 
524  if (index < vector_.size() && context_)
525  {
526  ContextGuard context_guard(*context_);
527  MADARA_GUARD_TYPE guard(mutex_);
528  result = context_->get(vector_[index], keep_local);
529  }
530 
531  return result;
532 }
533 
536 {
538  KnowledgeUpdateSettings keep_local(true);
539 
540  // if we have something to actually set
541  if (vector_.size() > 0 && context_)
542  {
543  ContextGuard context_guard(*context_);
544  MADARA_GUARD_TYPE guard(mutex_);
545  // set last element first so we're not constantly resizing
546  result.set_index(vector_.size() - 1,
547  context_->get(vector_[vector_.size() - 1], keep_local).to_integer());
548 
549  for (size_t i = 0; i < vector_.size() - 1; ++i)
550  {
551  result.set_index(i, context_->get(vector_[i], keep_local).to_integer());
552  }
553  }
554 
555  return result;
556 }
557 
559  size_t index, const type& value)
560 {
561  int result = -1;
562 
563  if (index < vector_.size() && context_)
564  {
565  ContextGuard context_guard(*context_);
566  MADARA_GUARD_TYPE guard(mutex_);
567  result = context_->set(vector_[index], value, settings_);
568  }
569 
570  return result;
571 }
572 
575 {
576  type result(0);
577 
578  if (index < vector_.size() && context_)
579  {
580  ContextGuard context_guard(*context_);
581  MADARA_GUARD_TYPE guard(mutex_);
582  result = context_->inc(vector_[index], settings_).to_integer();
583  }
584 
585  return result;
586 }
587 
589  size_t index, const type& value, const KnowledgeUpdateSettings& settings)
590 {
591  int result = -1;
592 
593  if (index < vector_.size() && context_)
594  {
595  ContextGuard context_guard(*context_);
596  MADARA_GUARD_TYPE guard(mutex_);
597  result = context_->set(vector_[index], value, settings);
598  }
599 
600  return result;
601 }
602 
604  const std::vector<type>& value)
605 {
606  int result = -1;
607 
608  if (context_)
609  {
610  ContextGuard context_guard(*context_);
611  MADARA_GUARD_TYPE guard(mutex_);
612  if (vector_.size() < value.size())
613  resize((int)value.size(), false);
614 
615  for (size_t i = 0; i < value.size(); ++i)
616  {
617  context_->set(vector_[i], value[i], settings_);
618  }
619 
620  result = 0;
621  }
622 
623  return result;
624 }
625 
627  const std::vector<type>& value, const KnowledgeUpdateSettings& settings)
628 {
629  int result = -1;
630 
631  if (context_)
632  {
633  ContextGuard context_guard(*context_);
634  MADARA_GUARD_TYPE guard(mutex_);
635  if (vector_.size() < value.size())
636  resize((int)value.size(), false);
637 
638  for (size_t i = 0; i < value.size(); ++i)
639  {
640  context_->set(vector_[i], value[i], settings);
641  }
642 
643  result = 0;
644  }
645 
646  return result;
647 }
648 
650  size_t index, uint32_t quality, const KnowledgeReferenceSettings& settings)
651 {
652  if (index < vector_.size() && context_)
653  {
654  ContextGuard context_guard(*context_);
655  MADARA_GUARD_TYPE guard(mutex_);
656  context_->set_quality(vector_[index].get_name(), quality, true, settings);
657  }
658 }
659 
661 {
662  bool result(false);
663 
665  "IntegerVector::is_true: Checking for truth\n");
666 
667  if (context_)
668  {
669  ContextGuard context_guard(*context_);
670  MADARA_GUARD_TYPE guard(mutex_);
671 
672  result = true;
673 
675  "IntegerVector::is_true: context was not null. Result changed to %d\n",
676  (int)result);
677 
678  for (size_t index = 0; index < vector_.size(); ++index)
679  {
681  "IntegerVector::is_true: checking index %d, is_false of %d. \n",
682  (int)result, (int)context_->get(vector_[index]).is_false());
683 
684  if (context_->get(vector_[index]).is_false())
685  {
687  "IntegerVector::is_true: result is false, breaking\n");
688 
689  result = false;
690  break;
691  }
692  }
693 
694  if (vector_.size() == 0)
695  result = false;
696  }
697 
699  "IntegerVector::is_true: final result is %d\n", (int)result);
700 
701  return result;
702 }
703 
705 {
706  return !is_true();
707 }
708 
710 {
711  return is_true();
712 }
713 
715 {
716  return is_false();
717 }
#define madara_logger_log(loggering, level,...)
Fast version of the madara::logger::log method.
Definition: Logger.h:20
const ThreadSafeContext * context_
madara::knowledge::KnowledgeRecord KnowledgeRecord
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.
void set_index(size_t index, T value)
sets the value at the index to the specified value.
Integer to_integer(void) const
converts the value to an integer.
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...
madara::knowledge::KnowledgeRecord get(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically returns the current value of a variable.
int set(const std::string &key, T &&value, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of a variable to the specific record.
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
This class stores a vector of integers inside of KaRL.
Definition: IntegerVector.h:32
VariableReference size_
Reference to the size field of the vector space.
int set(size_t index, const type &value=madara::knowledge::KnowledgeRecord::MODIFIED)
Sets a knowledge variable to a specified value.
void set_name(const std::string &var_name, KnowledgeBase &knowledge, int size=-1)
Sets the variable name that this refers to.
virtual BaseContainer * clone(void) const
Clones this container.
type operator[](size_t index) const
Retrieves a copy of the record from the map.
void modify(void)
Mark the vector as modified.
virtual std::string get_debug_info_(void)
Returns the type of the container along with name and any other useful information.
void set_delimiter(const std::string &delimiter)
Sets the delimiter for adding and detecting subvariables.
virtual bool is_true_(void) const
Polymorphic is true method which can be used to determine if all values in the container are true.
virtual void modify_(void)
Polymorphic modify method used by collection containers.
knowledge::KnowledgeRecord::Integer type
trait that describes the value type
Definition: IntegerVector.h:35
void copy_to(KnowledgeVector &target) const
Copies the vector elements to an STL vector of Knowledge Records.
std::vector< VariableReference > vector_
Values of the array.
std::string get_delimiter(void)
Gets the delimiter for adding and detecting subvariables.
void push_back(type value)
Pushes the value to the end of the array after incrementing the array size.
void resize(int size=-1, bool delete_vars=true)
Resizes the vector.
void transfer_to(IntegerVector &other)
Transfers elements from this vector to another.
size_t size(void) const
Returns the size of the local vector.
std::string get_debug_info(void)
Returns the type of the container along with name and any other useful information.
void set_quality(size_t index, uint32_t quality, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings(false))
Sets the quality of writing to a certain variable from this entity.
std::string delimiter_
Delimiter for the prefix to subvars.
type inc(size_t index)
Increments an index by a specified value.
knowledge::KnowledgeRecord to_record(void) const
Retrieves the entire vector as a native double array in a record.
void operator=(const IntegerVector &rhs)
Assignment operator.
bool is_true(void) const
Determines if all values in the vector are true.
IntegerVector(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 exists(size_t index) const
Checks to see if the index has ever been assigned a value.
ThreadSafeContext * context_
Variable context that we are modifying.
bool is_false(void) const
Determines if the value of the vector is false.
void exchange(IntegerVector &other, bool refresh_keys=true, bool delete_keys=true)
Exchanges the vector at this location with the vector at another location.
VariableReference get_size_ref(void)
Returns a reference to the size field of the current name.
constexpr string_t string
Provides functions and classes for the distributed knowledge base.
::std::vector< KnowledgeRecord > KnowledgeVector