MADARA  3.2.3
BufferVector.cpp
Go to the documentation of this file.
1 #include "BufferVector.h"
3 
4 namespace madara { namespace knowledge { namespace containers {
5 
7  const KnowledgeUpdateSettings & settings,
8  const std::string & delimiter)
9  : BaseContainer ("", settings), context_ (0), delimiter_ (delimiter)
10 {
11 }
12 
14  const std::string & name,
16  int size,
17  bool delete_vars,
18  const KnowledgeUpdateSettings & settings,
19  const std::string & delimiter)
20  : BaseContainer (name, settings), context_ (&(knowledge.get_context ())),
21  delimiter_ (delimiter)
22 {
23  size_ = get_size_ref ();
24  resize (size, delete_vars);
25 }
26 
28  const std::string & name,
30  int size,
31  bool delete_vars,
32  const KnowledgeUpdateSettings & settings,
33  const std::string & delimiter)
34  : BaseContainer (name, settings), context_ (knowledge.get_context ()),
35  delimiter_ (delimiter)
36 {
37  size_ = get_size_ref ();
38  resize (size, delete_vars);
39 }
40 
42 : BaseContainer (rhs), context_ (rhs.context_),
43  vector_ (rhs.vector_),
44  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 << "Buffer 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 
103 void
105 {
106  modify ();
107 }
108 
111 {
112  return get_debug_info ();
113 }
114 
117 {
118  return new BufferVector (*this);
119 }
120 
121 void
122 BufferVector::modify (size_t index)
123 {
124  if (context_ && name_ != "" && index < vector_.size ())
125  {
126  ContextGuard context_guard (*context_);
127  context_->mark_modified (vector_[index]);
128  }
129 }
130 
131 void
133  const BufferVector & rhs)
134 {
135  if (this != &rhs)
136  {
137  MADARA_GUARD_TYPE guard (mutex_), guard2 (rhs.mutex_);
138 
139  this->context_ = rhs.context_;
140  this->name_ = rhs.name_;
141  this->settings_ = rhs.settings_;
142  this->size_ = rhs.size_;
143  this->vector_ = rhs.vector_;
144  this->delimiter_ = rhs.delimiter_;
145  }
146 }
147 
148 void
150  const unsigned char * value, size_t size)
151 {
152  if (context_ && name_ != "")
153  {
154  ContextGuard context_guard (*context_);
155  MADARA_GUARD_TYPE guard (mutex_);
156 
157  if (!size_.is_valid ())
158  {
159  size_ = get_size_ref ();
160  }
161 
162  size_t i = this->size ();
163  resize ((int)i + 1);
164  set_file (i, value, size);
165  }
166 }
167 
168 
171 {
172  VariableReference ref;
173 
174  if (context_ && name_ != "")
175  {
176  KnowledgeUpdateSettings keep_local (true);
177  std::stringstream buffer;
178 
179  ContextGuard context_guard (*context_);
180  MADARA_GUARD_TYPE guard (mutex_);
181 
182  buffer << name_;
183  buffer << delimiter_;
184  buffer << "size";
185 
186  ref = context_->get_ref (buffer.str (), keep_local);
187  }
188 
189  return ref;
190 }
191 
192 void
194  int size, bool delete_vars)
195 {
196  if (context_ && name_ != "")
197  {
198  ContextGuard context_guard (*context_);
199  MADARA_GUARD_TYPE guard (mutex_);
200 
201  if (!size_.is_valid ())
202  {
203  size_ = get_size_ref ();
204  }
205 
206  if (size >= 0)
207  {
208  size_t old_size = vector_.size ();
209 
210  if (old_size != (size_t)size)
211  {
212  vector_.resize (size);
213 
215 
216  if ((size_t)size > old_size)
217  {
218  for (; old_size < (size_t)size; ++old_size)
219  {
220  std::stringstream buffer;
221  buffer << name_;
222  buffer << delimiter_;
223  buffer << old_size;
224  vector_[old_size] = context_->get_ref (buffer.str (), settings_);
225  }
226  }
227  else if (delete_vars)
228  {
229  for (; (size_t)size < old_size; ++size)
230  {
231  std::stringstream buffer;
232  buffer << name_;
233  buffer << delimiter_;
234  buffer << size;
235 
236  context_->delete_variable (buffer.str (), settings_);
237  }
238  }
239  }
240  }
241  else
242  {
243  // dynamically allocate size from the context
244  size_t cur_size =
246 
247  size_t old_size = vector_.size ();
248 
249  if (old_size != cur_size)
250  {
251  vector_.resize (cur_size);
252 
253  if (cur_size > old_size)
254  {
255  for (; old_size < cur_size; ++old_size)
256  {
257  std::stringstream buffer;
258  buffer << name_;
259  buffer << delimiter_;
260  buffer << old_size;
261  vector_[old_size] = context_->get_ref (buffer.str (), settings_);
262  }
263  }
264  else if (delete_vars)
265  {
266  for (; cur_size < old_size; ++cur_size)
267  {
268  std::stringstream buffer;
269  buffer << name_;
270  buffer << delimiter_;
271  buffer << cur_size;
272 
273  context_->delete_variable (buffer.str (), settings_);
274  }
275  }
276  }
277  }
278  }
279 }
280 
281 size_t
282 BufferVector::size (void) const
283 {
284  MADARA_GUARD_TYPE guard (mutex_);
285  return vector_.size();
286 }
287 
288 void
290  const std::string & var_name,
292 {
293  if (context_ != &(knowledge.get_context ()) || name_ != var_name)
294  {
295  context_ = &(knowledge.get_context ());
296 
297  ContextGuard context_guard (*context_);
298  MADARA_GUARD_TYPE guard (mutex_);
299 
300  name_ = var_name;
301 
302  vector_.clear ();
303 
304  size_ = get_size_ref ();
305 
306  resize (size);
307  }
308 }
309 
310 void
312  const std::string & var_name,
313  Variables & knowledge, int size)
314 {
315  if (context_ != knowledge.get_context () || name_ != var_name)
316  {
317  context_ = knowledge.get_context ();
318 
319  ContextGuard context_guard (*context_);
320  MADARA_GUARD_TYPE guard (mutex_);
321 
322  name_ = var_name;
323 
324  vector_.clear ();
325  resize (size);
326  }
327 }
328 
329 void
331  const std::string & var_name,
333 {
334  if (context_ != &knowledge || name_ != var_name)
335  {
336  context_ = &knowledge;
337 
338  ContextGuard context_guard (*context_);
339  MADARA_GUARD_TYPE guard (mutex_);
340 
341  name_ = var_name;
342 
343  vector_.clear ();
344  resize (size);
345  }
346 }
347 
348 void
350 const std::string & delimiter)
351 {
352  delimiter_ = delimiter;
353  if (context_)
354  {
355  ContextGuard context_guard (*context_);
356  MADARA_GUARD_TYPE guard (mutex_);
357 
358  vector_.clear ();
359  resize (-1);
360  }
361 }
362 
363 
366 {
367  return delimiter_;
368 }
369 
370 void
372  BufferVector & other, bool refresh_keys, bool delete_keys)
373 {
374  if (context_ && other.context_)
375  {
376  std::lock(*context_, *other.context_, mutex_, other.mutex_);
377 
378  ContextGuard context_guard (*context_, std::adopt_lock);
379  ContextGuard other_context_guard (*other.context_, std::adopt_lock);
380  MADARA_GUARD_TYPE guard (mutex_, std::adopt_lock),
381  guard2 (other.mutex_, std::adopt_lock);
382 
383  if (refresh_keys)
384  {
385  other.resize ();
386  this->resize ();
387  }
388 
389  size_t other_size = other.vector_.size ();
390  size_t this_size = this->vector_.size ();
391 
392  for (size_t i = 0; i < this_size; ++i)
393  {
394  // temp = this[i];
396 
397  if (i < other_size)
398  {
399  // this[i] = other[i];
400  context_->set (this->vector_[i],
401  context_->get (other.vector_[i], other.settings_),
402  settings_);
403 
404  // other[i] = temp;
405  other.context_->set (other.vector_[i], temp, other.settings_);
406  }
407  else
408  {
409  if (delete_keys)
410  {
411  std::stringstream buffer;
412  buffer << this->name_;
413  buffer << delimiter_;
414  buffer << i;
415  this->context_->delete_variable (buffer.str (), other.settings_);
416  }
417  else
418  {
420  this->context_->set (this->vector_[i], zero, this->settings_);
421  }
422 
423  {
424  std::stringstream buffer;
425  buffer << other.name_;
426  buffer << delimiter_;
427  buffer << i;
428 
429  // other[i] = temp;
430  other.context_->set (buffer.str (), temp, other.settings_);
431  }
432  }
433 
434  }
435 
436  // copy the other vector's elements to this vector's location
437  for (size_t i = this_size; i < other_size; ++i)
438  {
439  std::stringstream buffer;
440  buffer << this->name_;
441  buffer << delimiter_;
442  buffer << i;
443  context_->set (buffer.str (),
444  other.context_->get (other.vector_[i], other.settings_), this->settings_);
445  }
446 
447  // set the size appropriately
448  this->context_->set (this->size_,
449  knowledge::KnowledgeRecord::Integer (other_size), this->settings_);
450  other.context_->set (other.size_,
452 
453  if (refresh_keys)
454  {
455  this->resize (-1, true);
456  other.resize (-1, true);
457  }
458  }
459 }
460 
461 void
463 {
464  if (context_ && other.context_)
465  {
466  std::lock(*context_, *other.context_, mutex_, other.mutex_);
467 
468  ContextGuard context_guard (*context_, std::adopt_lock);
469  ContextGuard other_context_guard (*other.context_, std::adopt_lock);
470  MADARA_GUARD_TYPE guard (mutex_, std::adopt_lock),
471  guard2 (other.mutex_, std::adopt_lock);
472 
473 
474  size_t other_size = other.vector_.size ();
475  size_t this_size = this->vector_.size ();
476 
477  size_t size = other_size + this_size;
478  other.resize ((int)size);
479 
480  for (size_t i = 0, j = other_size; i < this_size; ++i, ++j)
481  {
482  other.context_->set (other.vector_[j], (*this)[i], other.settings_);
483  }
484 
485  this->resize (0, true);
486  }
487 }
488 
489 void
491  KnowledgeVector & target) const
492 {
493  if (context_)
494  {
495  ContextGuard context_guard (*context_);
496  MADARA_GUARD_TYPE guard (mutex_);
497 
498  target.clear ();
499  target.reserve (vector_.size());
500 
501  for (const auto &cur : vector_)
502  {
503  if (cur.is_valid()) {
504  target.emplace_back (context_->get (cur));
505  } else {
506  target.emplace_back ();
507  }
508  }
509  }
510 }
511 
514  size_t index) const
515 {
516  return to_record (index);
517 }
518 
521  size_t index) const
522 {
524 
525  if (index < vector_.size () && context_)
526  {
527  ContextGuard context_guard (*context_);
528  MADARA_GUARD_TYPE guard (mutex_);
529  result = context_->get (vector_[index], settings_);
530  }
531 
532  return result;
533 }
534 
535 bool
537  size_t index) const
538 {
539  bool result (false);
540 
541  if (index < vector_.size () && context_)
542  {
543  ContextGuard context_guard (*context_);
544  MADARA_GUARD_TYPE guard (mutex_);
545  result = context_->exists (vector_[index]);
546  }
547 
548  return result;
549 }
550 
551 
552 int
554  size_t index,
555  const std::string & filename)
556 {
557  int result = -1;
558 
559  if (index < vector_.size () && context_)
560  {
561  ContextGuard context_guard (*context_);
562  MADARA_GUARD_TYPE guard (mutex_);
563  result = context_->read_file (vector_[index], filename, settings_);
564  }
565 
566  return result;
567 }
568 
569 
570 int
572  size_t index,
573  const std::string & filename,
574  const KnowledgeUpdateSettings & settings)
575 {
576  int result = -1;
577 
578  if (index < vector_.size () && context_)
579  {
580  ContextGuard context_guard (*context_);
581  MADARA_GUARD_TYPE guard (mutex_);
582  result = context_->read_file (vector_[index], filename, settings);
583  }
584 
585  return result;
586 }
587 
588 
589 int
591  size_t index,
592  const unsigned char * value, size_t size)
593 {
594  int result = -1;
595 
596  if (index < vector_.size () && context_)
597  {
598  ContextGuard context_guard (*context_);
599  MADARA_GUARD_TYPE guard (mutex_);
600  result = context_->set_file (vector_[index], value, size, settings_);
601  }
602 
603  return result;
604 }
605 
606 int
608  size_t index, const knowledge::KnowledgeRecord & value)
609 {
610  int result = -1;
611 
612  if (index < vector_.size () && context_)
613  {
614  ContextGuard context_guard (*context_);
615  MADARA_GUARD_TYPE guard (mutex_);
616 
617  context_->set (vector_[index], value, settings_);
618  }
619 
620  return result;
621 }
622 
623 int
625  size_t index,
626  const unsigned char * value, size_t size,
627  const KnowledgeUpdateSettings & settings)
628 {
629  int result = -1;
630 
631  if (index < vector_.size () && context_)
632  {
633  ContextGuard context_guard (*context_);
634  MADARA_GUARD_TYPE guard (mutex_);
635  result = context_->set_file (vector_[index], value, size, settings);
636  }
637 
638  return result;
639 }
640 
641 
642 int
644  size_t index,
645  const unsigned char * value, size_t size)
646 {
647  int result = -1;
648 
649  if (index < vector_.size () && context_)
650  {
651  ContextGuard context_guard (*context_);
652  MADARA_GUARD_TYPE guard (mutex_);
653  result = context_->set_jpeg (vector_[index], value, size, settings_);
654  }
655 
656  return result;
657 }
658 
659 int
661  size_t index,
662  const unsigned char * value, size_t size,
663  const KnowledgeUpdateSettings & settings)
664 {
665  int result = -1;
666 
667  if (index < vector_.size () && context_)
668  {
669  ContextGuard context_guard (*context_);
670  MADARA_GUARD_TYPE guard (mutex_);
671  result = context_->set_jpeg (vector_[index], value, size, settings);
672  }
673 
674  return result;
675 }
676 
677 void
679  size_t index,
680  uint32_t quality,
681  const KnowledgeReferenceSettings & settings)
682 {
683  if (index < vector_.size () && context_)
684  {
685  ContextGuard context_guard (*context_);
686  MADARA_GUARD_TYPE guard (mutex_);
687 
688  context_->set_quality (vector_[index].get_name (), quality, true,
689  settings);
690  }
691 }
692 
693 bool
695 {
696  bool result (false);
697 
699  "BufferVector::is_true: Checking for truth\n");
700 
701  if (context_)
702  {
703  ContextGuard context_guard (*context_);
704  MADARA_GUARD_TYPE guard (mutex_);
705 
706  result = true;
707 
709  "BufferVector::is_true: context was not null. Result changed to %d\n",
710  (int)result);
711 
712  for (size_t index = 0; index < vector_.size (); ++index)
713  {
714 
716  "BufferVector::is_true: checking index %d, is_false of %d. \n",
717  (int)result, (int)context_->get (vector_[index]).is_false ());
718 
719  if (context_->get (vector_[index]).is_false ())
720  {
722  "BufferVector::is_true: result is false, breaking\n");
723 
724  result = false;
725  break;
726  }
727  }
728 
729  if (vector_.size () == 0)
730  result = false;
731  }
732 
734  "BufferVector::is_true: final result is %d\n", (int)result);
735 
736  return result;
737 }
738 
739 bool
741 {
742  return !is_true ();
743 }
744 
745 
746 bool
748 {
749  return is_true ();
750 }
751 
752 bool
754 {
755  return is_false ();
756 }
757 
758 } } }
This class encapsulates an entry in a KnowledgeBase.
bool is_false(void) const
Determines if the value of the vector is false.
int set(const std::string &key, T &&value, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of a variable to the specific record.
This class stores a vector of character buffers.
Definition: BufferVector.h:31
VariableReference size_
Reference to the size field of the vector space.
Definition: BufferVector.h:390
std::vector< VariableReference > vector_
Values of the array.
Definition: BufferVector.h:385
int set_jpeg(size_t index, const unsigned char *value, size_t size)
Atomically sets the value of an index to a JPEG image.
void resize(int size=-1, bool delete_vars=true)
Resizes the vector.
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...
int set_file(const std::string &key, const unsigned char *value, size_t size, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of a variable to an arbitrary string.
int set_jpeg(const std::string &key, const unsigned char *value, size_t size, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of a variable to a JPEG image.
size_t size(void) const
Returns the size of the local vector.
std::string name_
Prefix of variable.
std::string get_delimiter(void)
Gets the delimiter for adding and detecting subvariables.
void push_back(const unsigned char *value, size_t size)
Pushes the value to the end of the array after incrementing the array size.
void exchange(BufferVector &other, bool refresh_keys=true, bool delete_keys=true)
Exchanges the vector at this location with the vector at another location.
std::string get_debug_info(void)
Returns the type of the container along with name and any other useful information.
This class stores variables and their values for use by any entity needing state information in a thr...
void transfer_to(BufferVector &other)
Transfers elements from this vector to another.
void modify(void)
Mark the vector as modified.
void operator=(const BufferVector &rhs)
Assignment operator.
MADARA_LOCK_TYPE mutex_
guard for access and changes
bool is_true(void) const
Determines if all values in the vector are true.
VariableReference get_size_ref(void) const
Returns a reference to the size field of the current name.
void copy_to(KnowledgeVector &target) const
Copies the vector elements to an STL vector of Knowledge Records.
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 exists(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically checks to see if a variable already exists.
Provides container classes for fast knowledge base access and mutation.
Definition: Barrier.h:27
::std::vector< KnowledgeRecord > KnowledgeVector
virtual void modify_(void)
Polymorphic modify method used by collection containers.
A thread-safe guard for a context or knowledge base.
Definition: ContextGuard.h:23
static struct madara::knowledge::tags::string_t string
knowledge::KnowledgeRecord operator[](size_t index) const
Retrieves a copy of the record from the map.
bool exists(size_t index) const
Checks to see if the index has ever been assigned a value.
This class provides a distributed knowledge base to users.
Definition: KnowledgeBase.h:45
virtual BaseContainer * clone(void) const
Clones this container.
int set(size_t index, const knowledge::KnowledgeRecord &value)
Atomically sets the value of an index to a provided record.
void set_delimiter(const std::string &delimiter)
Sets the delimiter for adding and detecting subvariables.
VariableReference get_ref(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Atomically returns a reference to the variable.
std::string delimiter_
Delimiter for the prefix to subvars.
Definition: BufferVector.h:395
Integer to_integer(void) const
converts the value to an integer.
int read_file(size_t index, const std::string &filename)
Read a file into the index using stored settings.
ThreadSafeContext & get_context(void)
Returns the ThreadSafeContext associated with this Knowledge Base.
bool delete_variable(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Deletes the key.
Provides functions and classes for the distributed knowledge base.
KnowledgeUpdateSettings settings_
Settings for modifications.
ThreadSafeContext * context_
Variable context that we are modifying.
Definition: BufferVector.h:380
knowledge::KnowledgeRecord to_record(size_t index) const
Retrieves a copy of the record from the map.
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.
Copyright (c) 2015 Carnegie Mellon University.
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.
BufferVector(const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings(), const std::string &delimiter=".")
Default constructor.
Definition: BufferVector.cpp:6
virtual std::string get_debug_info_(void)
Returns the type of the container along with name and any other useful information.
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
int read_file(const std::string &key, const std::string &filename, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically reads a file into a variable.
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 set_name(const std::string &var_name, KnowledgeBase &knowledge, int size=-1)
Sets the variable name that this refers to.
int set_file(size_t index, const unsigned char *value, size_t size)
Atomically sets the value of an index to an arbitrary string using stored settings.
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.
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.