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