MADARA  3.2.3
IntegerVector.cpp
Go to the documentation of this file.
1 #include "IntegerVector.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  int size,
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 (size, delete_vars);
24 }
25 
27  const std::string & name,
29  int size,
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 (size, delete_vars);
38 }
39 
41  const IntegerVector & rhs)
42 : BaseContainer (rhs),
43  context_ (rhs.context_),
44  vector_ (rhs.vector_),
45  size_ (rhs.size_)
46 {
47 
48 }
49 
50 
52 {
53 
54 }
55 
56 void
58 {
59  if (context_ && name_ != "")
60  {
61  ContextGuard context_guard (*context_);
62  for (size_t index = 0; index < vector_.size (); ++index)
63  context_->mark_modified (vector_[index]);
64 
66  }
67 }
68 
71 {
72  std::stringstream result;
73 
74  result << "Integer Vector: ";
75 
76  if (context_)
77  {
78  ContextGuard context_guard (*context_);
79  MADARA_GUARD_TYPE guard (mutex_);
80  size_t elements = vector_.size ();
81 
82  result << this->name_;
83  result << " [" << elements << "]";
84  result << " = [";
85 
86  if (elements > 0)
87  {
88  result << context_->get (vector_[0]).to_string ();
89 
90  for (size_t index = 1; index < elements; ++index)
91  {
92  result << ", " << context_->get (vector_[index]).to_string ();
93  }
94  }
95 
96  result << "]";
97  }
98 
99  return result.str ();
100 }
101 
102 void
104 {
105  modify ();
106 }
107 
110 {
111  return get_debug_info ();
112 }
113 
116 {
117  return new IntegerVector (*this);
118 }
119 
120 void
122 {
123  if (context_ && name_ != "" && index < vector_.size ())
124  {
125  ContextGuard context_guard (*context_);
126  context_->mark_modified (vector_[index]);
127  }
128 }
129 
130 void
132  const IntegerVector & 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 
147 void
149 {
150  if (context_ && name_ != "")
151  {
152  ContextGuard context_guard (*context_);
153  MADARA_GUARD_TYPE guard (mutex_);
154 
155  if (!size_.is_valid ())
156  {
157  size_ = get_size_ref ();
158  }
159 
160  size_t i = size ();
161  resize ((int)i + 1);
162  set (i, value);
163  }
164 }
165 
168 {
169  VariableReference ref;
170 
171  if (context_ && name_ != "")
172  {
173  KnowledgeUpdateSettings keep_local (true);
174  std::stringstream buffer;
175 
176  ContextGuard context_guard (*context_);
177  MADARA_GUARD_TYPE guard (mutex_);
178 
179  buffer << name_;
180  buffer << delimiter_;
181  buffer << "size";
182 
183  ref = context_->get_ref (buffer.str (), keep_local);
184  }
185 
186  return ref;
187 }
188 
189 void
191  int size, bool delete_vars)
192 {
193  if (context_ && name_ != "")
194  {
195  ContextGuard context_guard (*context_);
196  MADARA_GUARD_TYPE guard (mutex_);
197 
198  if (!size_.is_valid ())
199  {
200  size_ = get_size_ref ();
201  }
202 
203  if (size >= 0)
204  {
205  size_t old_size = vector_.size ();
206 
207  if (old_size != (size_t)size)
208  {
209  vector_.resize (size);
210 
212 
213  if ((size_t)size > old_size)
214  {
215  for (; old_size < (size_t)size; ++old_size)
216  {
217  std::stringstream buffer;
218  buffer << name_;
219  buffer << delimiter_;
220  buffer << old_size;
221  vector_[old_size] = context_->get_ref (buffer.str (), settings_);
222  }
223  }
224  else if (delete_vars)
225  {
226  for (; (size_t)size < old_size; ++size)
227  {
228  std::stringstream buffer;
229  buffer << name_;
230  buffer << delimiter_;
231  buffer << size;
232 
233  context_->delete_variable (buffer.str (), settings_);
234  }
235  }
236  }
237  }
238  else
239  {
240  // dynamically allocate size from the context
241  size_t cur_size =
242  (size_t) context_->get (size_, settings_).to_integer ();
243 
244  size_t old_size = vector_.size ();
245 
246  if (old_size != cur_size)
247  {
248  vector_.resize (cur_size);
249 
250  if (cur_size > old_size)
251  {
252  for (; old_size < cur_size; ++old_size)
253  {
254  std::stringstream buffer;
255  buffer << name_;
256  buffer << delimiter_;
257  buffer << old_size;
258  vector_[old_size] = context_->get_ref (buffer.str (), settings_);
259  }
260  }
261  else if (delete_vars)
262  {
263  for (; cur_size < old_size; ++cur_size)
264  {
265  std::stringstream buffer;
266  buffer << name_;
267  buffer << delimiter_;
268  buffer << cur_size;
269 
270  context_->delete_variable (buffer.str (), settings_);
271  }
272  }
273  }
274  }
275  }
276 }
277 
278 size_t
280 {
281  MADARA_GUARD_TYPE guard (mutex_);
282  return vector_.size ();
283 }
284 
285 void
287  const std::string & var_name,
289 {
290  if (context_ != &(knowledge.get_context ()) || name_ != var_name)
291  {
292  context_ = &(knowledge.get_context ());
293 
294  ContextGuard context_guard (*context_);
295  MADARA_GUARD_TYPE guard (mutex_);
296 
297  name_ = var_name;
298 
299  vector_.clear ();
300 
301  size_ = get_size_ref ();
302 
303  resize (size);
304  }
305 }
306 
307 void
309  const std::string & var_name,
310  Variables & knowledge, int size)
311 {
312  if (context_ != knowledge.get_context () || name_ != var_name)
313  {
314  context_ = knowledge.get_context ();
315 
316  ContextGuard context_guard (*context_);
317  MADARA_GUARD_TYPE guard (mutex_);
318 
319  name_ = var_name;
320 
321  vector_.clear ();
322  resize (size);
323  }
324 }
325 
326 void
328  const std::string & var_name,
330 {
331  if (context_ != &knowledge || name_ != var_name)
332  {
333  context_ = &knowledge;
334 
335  ContextGuard context_guard (*context_);
336  MADARA_GUARD_TYPE guard (mutex_);
337 
338  name_ = var_name;
339 
340  vector_.clear ();
341  resize (size);
342  }
343 }
344 
345 void
347 const std::string & delimiter)
348 {
349  delimiter_ = delimiter;
350  if (context_)
351  {
352  ContextGuard context_guard (*context_);
353  MADARA_GUARD_TYPE guard (mutex_);
354 
355  vector_.clear ();
356  resize (-1);
357  }
358 }
359 
360 
363 {
364  return delimiter_;
365 }
366 
367 void
369  IntegerVector & other, bool refresh_keys, bool delete_keys)
370 {
371  if (context_ && other.context_)
372  {
373  std::lock(*context_, *other.context_, mutex_, other.mutex_);
374 
375  ContextGuard context_guard (*context_, std::adopt_lock);
376  ContextGuard other_context_guard (*other.context_, std::adopt_lock);
377  MADARA_GUARD_TYPE guard (mutex_, std::adopt_lock),
378  guard2 (other.mutex_, std::adopt_lock);
379 
380 
381  if (refresh_keys)
382  {
383  other.resize ();
384  this->resize ();
385  }
386 
387  size_t other_size = other.vector_.size ();
388  size_t this_size = this->vector_.size ();
389 
390  for (size_t i = 0; i < this_size; ++i)
391  {
392  // temp = this[i];
394 
395  if (i < other_size)
396  {
397  // this[i] = other[i];
398  context_->set (this->vector_[i],
399  context_->get (other.vector_[i], other.settings_),
400  settings_);
401 
402  // other[i] = temp;
403  other.context_->set (other.vector_[i], temp, other.settings_);
404  }
405  else
406  {
407  if (delete_keys)
408  {
409  std::stringstream buffer;
410  buffer << this->name_;
411  buffer << delimiter_;
412  buffer << i;
413  this->context_->delete_variable (buffer.str (), other.settings_);
414  }
415  else
416  {
418  this->context_->set (this->vector_[i], zero, this->settings_);
419  }
420 
421  {
422  std::stringstream buffer;
423  buffer << other.name_;
424  buffer << delimiter_;
425  buffer << i;
426 
427  // other[i] = temp;
428  other.context_->set (buffer.str (), temp, other.settings_);
429  }
430  }
431 
432  }
433 
434  // copy the other vector's elements to this vector's location
435  for (size_t i = this_size; i < other_size; ++i)
436  {
437  std::stringstream buffer;
438  buffer << this->name_;
439  buffer << delimiter_;
440  buffer << i;
441  context_->set (buffer.str (),
442  other.context_->get (other.vector_[i], other.settings_), this->settings_);
443  }
444 
445  // set the size appropriately
446  this->context_->set (this->size_,
447  knowledge::KnowledgeRecord::Integer (other_size), this->settings_);
448  other.context_->set (other.size_,
450 
451  if (refresh_keys)
452  {
453  this->resize (-1, true);
454  other.resize (-1, true);
455  }
456  }
457 }
458 
459 void
461 {
462  if (context_ && other.context_)
463  {
464  std::lock(*context_, *other.context_, mutex_, other.mutex_);
465 
466  ContextGuard context_guard (*context_, std::adopt_lock);
467  ContextGuard other_context_guard (*other.context_, std::adopt_lock);
468  MADARA_GUARD_TYPE guard (mutex_, std::adopt_lock),
469  guard2 (other.mutex_, std::adopt_lock);
470 
471 
472  size_t other_size = other.vector_.size ();
473  size_t this_size = this->vector_.size ();
474 
475  size_t size = other_size + this_size;
476  other.resize ((int)size);
477 
478  for (size_t i = 0, j = other_size; i < this_size; ++i, ++j)
479  {
480  other.context_->set (other.vector_[j], (*this)[i], other.settings_);
481  }
482 
483  this->resize (0, true);
484  }
485 }
486 
487 void
489  KnowledgeVector & target) const
490 {
491  if (context_)
492  {
493  ContextGuard context_guard (*context_);
494  MADARA_GUARD_TYPE guard (mutex_);
495 
496  target.resize (vector_.size ());
497 
498  for (size_t i = 0; i < vector_.size (); ++i)
499  {
500  target[i] = knowledge::KnowledgeRecord ((*this)[i]);
501  }
502  }
503 }
504 
505 void
507 std::vector <type> & target) const
508 {
509  if (context_)
510  {
511  ContextGuard context_guard (*context_);
512  MADARA_GUARD_TYPE guard (mutex_);
513 
514  target.resize (vector_.size ());
515 
516  for (size_t i = 0; i < vector_.size (); ++i)
517  {
518  target[i] = (*this)[i];
519  }
520  }
521 }
522 
523 bool
525  size_t index) const
526 {
527  bool result (false);
528 
529  if (index < vector_.size () && context_)
530  {
531  ContextGuard context_guard (*context_);
532  MADARA_GUARD_TYPE guard (mutex_);
533  result = context_->exists (vector_[index]);
534  }
535 
536  return result;
537 }
538 
541  size_t index) const
542 {
544  KnowledgeUpdateSettings keep_local (true);
545 
546  if (index < vector_.size () && context_)
547  {
548  ContextGuard context_guard (*context_);
549  MADARA_GUARD_TYPE guard (mutex_);
550  result = context_->get (vector_[index], keep_local);
551  }
552 
553  return result.to_integer ();
554 }
555 
558  size_t index) const
559 {
561  KnowledgeUpdateSettings keep_local (true);
562 
563  if (index < vector_.size () && context_)
564  {
565  ContextGuard context_guard (*context_);
566  MADARA_GUARD_TYPE guard (mutex_);
567  result = context_->get (vector_[index], keep_local);
568  }
569 
570  return result;
571 }
572 
575 {
577  KnowledgeUpdateSettings keep_local (true);
578 
579  // if we have something to actually set
580  if (vector_.size () > 0 && context_)
581  {
582  ContextGuard context_guard (*context_);
583  MADARA_GUARD_TYPE guard (mutex_);
584  // set last element first so we're not constantly resizing
585  result.set_index (vector_.size () - 1,
586  context_->get (vector_[vector_.size () - 1], keep_local).to_integer ());
587 
588  for (size_t i = 0; i < vector_.size () - 1; ++i)
589  {
590  result.set_index (i,
591  context_->get (vector_[i], keep_local).to_integer ());
592  }
593  }
594 
595  return result;
596 }
597 
598 int
600  size_t index,
601  const type & value)
602 {
603  int result = -1;
604 
605  if (index < vector_.size () && context_)
606  {
607  ContextGuard context_guard (*context_);
608  MADARA_GUARD_TYPE guard (mutex_);
609  result = context_->set (vector_[index], value, settings_);
610  }
611 
612  return result;
613 }
614 
617 size_t index)
618 {
619  type result (0);
620 
621  if (index < vector_.size () && context_)
622  {
623  ContextGuard context_guard (*context_);
624  MADARA_GUARD_TYPE guard (mutex_);
625  result = context_->inc (vector_[index], settings_).to_integer ();
626  }
627 
628  return result;
629 }
630 
631 int
633  size_t index,
634  const type & value,
635  const KnowledgeUpdateSettings & settings)
636 {
637  int result = -1;
638 
639  if (index < vector_.size () && context_)
640  {
641  ContextGuard context_guard (*context_);
642  MADARA_GUARD_TYPE guard (mutex_);
643  result = context_->set (vector_[index], value, settings);
644  }
645 
646  return result;
647 }
648 
649 int
651  const std::vector <type> & value)
652 {
653  int result = -1;
654 
655  if (context_)
656  {
657  ContextGuard context_guard (*context_);
658  MADARA_GUARD_TYPE guard (mutex_);
659  if (vector_.size () < value.size ())
660  resize ((int)value.size (), false);
661 
662  for (size_t i = 0; i < value.size (); ++i)
663  {
664  context_->set (vector_[i], value[i], settings_);
665  }
666 
667  result = 0;
668  }
669 
670  return result;
671 }
672 
673 int
675  const std::vector <type> & value,
676  const KnowledgeUpdateSettings & settings)
677 {
678  int result = -1;
679 
680  if (context_)
681  {
682  ContextGuard context_guard (*context_);
683  MADARA_GUARD_TYPE guard (mutex_);
684  if (vector_.size () < value.size ())
685  resize ((int)value.size (), false);
686 
687  for (size_t i = 0; i < value.size (); ++i)
688  {
689  context_->set (vector_[i], value[i], settings);
690  }
691 
692  result = 0;
693  }
694 
695  return result;
696 }
697 
698 void
700  size_t index,
701  uint32_t quality,
702  const KnowledgeReferenceSettings & settings)
703 {
704  if (index < vector_.size () && context_)
705  {
706  ContextGuard context_guard (*context_);
707  MADARA_GUARD_TYPE guard (mutex_);
708  context_->set_quality (vector_[index].get_name (), quality,
709  true, settings);
710  }
711 }
712 
713 bool
715 {
716  bool result (false);
717 
719  "IntegerVector::is_true: Checking for truth\n");
720 
721  if (context_)
722  {
723  ContextGuard context_guard (*context_);
724  MADARA_GUARD_TYPE guard (mutex_);
725 
726  result = true;
727 
729  "IntegerVector::is_true: context was not null. Result changed to %d\n",
730  (int)result);
731 
732  for (size_t index = 0; index < vector_.size (); ++index)
733  {
734 
736  "IntegerVector::is_true: checking index %d, is_false of %d. \n",
737  (int)result, (int)context_->get (vector_[index]).is_false ());
738 
739  if (context_->get (vector_[index]).is_false ())
740  {
742  "IntegerVector::is_true: result is false, breaking\n");
743 
744  result = false;
745  break;
746  }
747  }
748 
749  if (vector_.size () == 0)
750  result = false;
751  }
752 
754  "IntegerVector::is_true: final result is %d\n", (int)result);
755 
756  return result;
757 }
758 
759 bool
761 {
762  return !is_true ();
763 }
764 
765 
766 bool
768 {
769  return is_true ();
770 }
771 
772 bool
774 {
775  return is_false ();
776 }
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.
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.
int set(size_t index, const type &value=madara::knowledge::KnowledgeRecord::MODIFIED)
Sets a knowledge variable to a specified value.
virtual std::string get_debug_info_(void)
Returns the type of the container along with name and any other useful information.
std::string get_name(void) const
Returns the name of the container.
virtual bool is_true_(void) const
Polymorphic is true method which can be used to determine if all values in the container are true...
madara::knowledge::KnowledgeRecord KnowledgeRecord
VariableReference get_size_ref(void)
Returns a reference to the size field of the current name.
virtual void modify_(void)
Polymorphic modify method used by collection containers.
std::string name_
Prefix of variable.
type inc(size_t index)
Increments an index by a specified value.
void set_name(const std::string &var_name, KnowledgeBase &knowledge, int size=-1)
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...
This class stores a vector of integers inside of KaRL.
Definition: IntegerVector.h:31
MADARA_LOCK_TYPE mutex_
guard for access and changes
ThreadSafeContext * context_
Variable context that we are modifying.
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 is_true(void) const
Determines if all values in the vector are true.
bool exists(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically checks to see if a variable already exists.
::std::vector< KnowledgeRecord > KnowledgeVector
IntegerVector(const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings(), const std::string &delimiter=".")
Default constructor.
type operator[](size_t index) const
Retrieves a copy of the record from the map.
knowledge::KnowledgeRecord::Integer type
trait that describes the value type
Definition: IntegerVector.h:35
A thread-safe guard for a context or knowledge base.
Definition: ContextGuard.h:23
void resize(int size=-1, bool delete_vars=true)
Resizes the vector.
size_t size(void) const
Returns the size of the local vector.
static struct madara::knowledge::tags::string_t string
void operator=(const IntegerVector &rhs)
Assignment operator.
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:45
bool exists(size_t index) const
Checks to see if the index has ever been assigned a value.
void modify(void)
Mark the vector as modified.
knowledge::KnowledgeRecord to_record(void) const
Retrieves the entire vector as a native double array in a record.
VariableReference get_ref(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Atomically returns a reference to the variable.
void set_index(size_t index, T value)
sets the value at the index to the specified value.
bool is_false(void) const
Determines if the value of the vector is false.
Integer to_integer(void) const
converts the value to an integer.
VariableReference size_
Reference to the size field of the vector space.
void exchange(IntegerVector &other, bool refresh_keys=true, bool delete_keys=true)
Exchanges the vector at this location with the vector at another location.
ThreadSafeContext & get_context(void)
Returns the ThreadSafeContext associated with this Knowledge Base.
std::vector< VariableReference > vector_
Values of the array.
bool delete_variable(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Deletes the key.
std::string get_debug_info(void)
Returns the type of the container along with name and any other useful information.
Provides functions and classes for the distributed knowledge base.
KnowledgeUpdateSettings settings_
Settings for modifications.
std::string delimiter_
Delimiter for the prefix to subvars.
void copy_to(KnowledgeVector &target) const
Copies the vector elements to an STL vector of Knowledge Records.
Settings for applying knowledge updates.
madara::knowledge::KnowledgeRecord get(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically returns the value of a variable.
void transfer_to(IntegerVector &other)
Transfers elements from this vector to another.
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.
std::string to_string(const std::string &delimiter=", ") const
converts the value to a string.
virtual BaseContainer * clone(void) const
Clones this container.
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...
void push_back(type value)
Pushes the value to the end of the array after incrementing the array size.
void set_delimiter(const std::string &delimiter)
Sets the delimiter for adding and detecting subvariables.
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 ...
ThreadSafeContext * get_context(void)
Returns the ThreadSafeContext associated with this Variables facade.
std::string get_delimiter(void)
Gets the delimiter for adding and detecting subvariables.
madara::knowledge::KnowledgeRecord inc(const std::string &key, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically increments the value of the variable.