MADARA  3.4.1
BufferVector.cpp
Go to the documentation of this file.
1 #include "BufferVector.h"
3 
4 namespace madara
5 {
6 namespace knowledge
7 {
8 namespace containers
9 {
11  const KnowledgeUpdateSettings& settings, const std::string& delimiter)
12  : BaseContainer("", settings), context_(0), delimiter_(delimiter)
13 {
14 }
15 
17  int size, bool delete_vars, const KnowledgeUpdateSettings& settings,
18  const std::string& delimiter)
19  : BaseContainer(name, settings),
20  context_(&(knowledge.get_context())),
21  delimiter_(delimiter)
22 {
23  size_ = get_size_ref();
24  resize(size, delete_vars);
25 }
26 
28  int size, bool delete_vars, const KnowledgeUpdateSettings& settings,
29  const std::string& delimiter)
30  : BaseContainer(name, settings),
31  context_(knowledge.get_context()),
32  delimiter_(delimiter)
33 {
34  size_ = get_size_ref();
35  resize(size, delete_vars);
36 }
37 
39  : BaseContainer(rhs),
40  context_(rhs.context_),
41  vector_(rhs.vector_),
42  size_(rhs.size_),
43  delimiter_(rhs.delimiter_)
44 {
45 }
46 
48 
50 {
51  if (context_ && name_ != "")
52  {
53  ContextGuard context_guard(*context_);
54  for (size_t index = 0; index < vector_.size(); ++index)
56 
58  }
59 }
60 
62 {
63  std::stringstream result;
64 
65  result << "Buffer Vector: ";
66 
67  if (context_)
68  {
69  ContextGuard context_guard(*context_);
70  MADARA_GUARD_TYPE guard(mutex_);
71  size_t elements = vector_.size();
72 
73  result << this->name_;
74  result << " [" << elements << "]";
75  result << " = [";
76 
77  if (elements > 0)
78  {
79  result << context_->get(vector_[0]).to_string();
80 
81  for (size_t index = 1; index < elements; ++index)
82  {
83  result << ", " << context_->get(vector_[index]).to_string();
84  }
85  }
86 
87  result << "]";
88  }
89 
90  return result.str();
91 }
92 
94 {
95  modify();
96 }
97 
99 {
100  return get_debug_info();
101 }
102 
104 {
105  return new BufferVector(*this);
106 }
107 
108 void BufferVector::modify(size_t index)
109 {
110  if (context_ && name_ != "" && index < vector_.size())
111  {
112  ContextGuard context_guard(*context_);
113  context_->mark_modified(vector_[index]);
114  }
115 }
116 
118 {
119  if (this != &rhs)
120  {
121  MADARA_GUARD_TYPE guard(mutex_), guard2(rhs.mutex_);
122 
123  this->context_ = rhs.context_;
124  this->name_ = rhs.name_;
125  this->settings_ = rhs.settings_;
126  this->size_ = rhs.size_;
127  this->vector_ = rhs.vector_;
128  this->delimiter_ = rhs.delimiter_;
129  }
130 }
131 
132 void BufferVector::push_back(const unsigned char* value, size_t size)
133 {
134  if (context_ && name_ != "")
135  {
136  ContextGuard context_guard(*context_);
137  MADARA_GUARD_TYPE guard(mutex_);
138 
139  if (!size_.is_valid())
140  {
141  size_ = get_size_ref();
142  }
143 
144  size_t i = this->size();
145  resize((int)i + 1);
146  set_file(i, value, size);
147  }
148 }
149 
151 {
152  VariableReference ref;
153 
154  if (context_ && name_ != "")
155  {
156  KnowledgeUpdateSettings keep_local(true);
157  std::stringstream buffer;
158 
159  ContextGuard context_guard(*context_);
160  MADARA_GUARD_TYPE guard(mutex_);
161 
162  buffer << name_;
163  buffer << delimiter_;
164  buffer << "size";
165 
166  ref = context_->get_ref(buffer.str(), keep_local);
167  }
168 
169  return ref;
170 }
171 
172 void BufferVector::resize(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(
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 = 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 < 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 (; 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 
259 size_t BufferVector::size(void) const
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 {
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  BufferVector& 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_,
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 {
429  if (context_ && other.context_)
430  {
431  std::lock(*context_, *other.context_, mutex_, other.mutex_);
432 
433  ContextGuard context_guard(*context_, std::adopt_lock);
434  ContextGuard other_context_guard(*other.context_, std::adopt_lock);
435  MADARA_GUARD_TYPE guard(mutex_, std::adopt_lock),
436  guard2(other.mutex_, std::adopt_lock);
437 
438  size_t other_size = other.vector_.size();
439  size_t this_size = this->vector_.size();
440 
441  size_t size = other_size + this_size;
442  other.resize((int)size);
443 
444  for (size_t i = 0, j = other_size; i < this_size; ++i, ++j)
445  {
446  other.context_->set(other.vector_[j], (*this)[i], other.settings_);
447  }
448 
449  this->resize(0, true);
450  }
451 }
452 
454 {
455  if (context_)
456  {
457  ContextGuard context_guard(*context_);
458  MADARA_GUARD_TYPE guard(mutex_);
459 
460  target.clear();
461  target.reserve(vector_.size());
462 
463  for (const auto& cur : vector_)
464  {
465  if (cur.is_valid())
466  {
467  target.emplace_back(context_->get(cur));
468  }
469  else
470  {
471  target.emplace_back();
472  }
473  }
474  }
475 }
476 
478 {
479  return to_record(index);
480 }
481 
483 {
485 
486  if (index < vector_.size() && context_)
487  {
488  ContextGuard context_guard(*context_);
489  MADARA_GUARD_TYPE guard(mutex_);
490  result = context_->get(vector_[index], settings_);
491  }
492 
493  return result;
494 }
495 
496 bool BufferVector::exists(size_t index) const
497 {
498  bool result(false);
499 
500  if (index < vector_.size() && context_)
501  {
502  ContextGuard context_guard(*context_);
503  MADARA_GUARD_TYPE guard(mutex_);
504  result = context_->exists(vector_[index]);
505  }
506 
507  return result;
508 }
509 
510 int BufferVector::read_file(size_t index, const std::string& filename)
511 {
512  int result = -1;
513 
514  if (index < vector_.size() && context_)
515  {
516  ContextGuard context_guard(*context_);
517  MADARA_GUARD_TYPE guard(mutex_);
518  result = context_->read_file(vector_[index], filename, settings_);
519  }
520 
521  return result;
522 }
523 
524 int BufferVector::read_file(size_t index, const std::string& filename,
525  const KnowledgeUpdateSettings& settings)
526 {
527  int result = -1;
528 
529  if (index < vector_.size() && context_)
530  {
531  ContextGuard context_guard(*context_);
532  MADARA_GUARD_TYPE guard(mutex_);
533  result = context_->read_file(vector_[index], filename, settings);
534  }
535 
536  return result;
537 }
538 
540  size_t index, const unsigned char* value, size_t size)
541 {
542  int result = -1;
543 
544  if (index < vector_.size() && context_)
545  {
546  ContextGuard context_guard(*context_);
547  MADARA_GUARD_TYPE guard(mutex_);
548  result = context_->set_file(vector_[index], value, size, settings_);
549  }
550 
551  return result;
552 }
553 
554 int BufferVector::set(size_t index, const knowledge::KnowledgeRecord& value)
555 {
556  int result = -1;
557 
558  if (index < vector_.size() && context_)
559  {
560  ContextGuard context_guard(*context_);
561  MADARA_GUARD_TYPE guard(mutex_);
562 
563  context_->set(vector_[index], value, settings_);
564  }
565 
566  return result;
567 }
568 
569 int BufferVector::set_file(size_t index, const unsigned char* value,
570  size_t size, const KnowledgeUpdateSettings& settings)
571 {
572  int result = -1;
573 
574  if (index < vector_.size() && context_)
575  {
576  ContextGuard context_guard(*context_);
577  MADARA_GUARD_TYPE guard(mutex_);
578  result = context_->set_file(vector_[index], value, size, settings);
579  }
580 
581  return result;
582 }
583 
585  size_t index, const unsigned char* value, size_t size)
586 {
587  int result = -1;
588 
589  if (index < vector_.size() && context_)
590  {
591  ContextGuard context_guard(*context_);
592  MADARA_GUARD_TYPE guard(mutex_);
593  result = context_->set_jpeg(vector_[index], value, size, settings_);
594  }
595 
596  return result;
597 }
598 
599 int BufferVector::set_jpeg(size_t index, const unsigned char* value,
600  size_t size, const KnowledgeUpdateSettings& settings)
601 {
602  int result = -1;
603 
604  if (index < vector_.size() && context_)
605  {
606  ContextGuard context_guard(*context_);
607  MADARA_GUARD_TYPE guard(mutex_);
608  result = context_->set_jpeg(vector_[index], value, size, settings);
609  }
610 
611  return result;
612 }
613 
615  size_t index, uint32_t quality, const KnowledgeReferenceSettings& settings)
616 {
617  if (index < vector_.size() && context_)
618  {
619  ContextGuard context_guard(*context_);
620  MADARA_GUARD_TYPE guard(mutex_);
621 
622  context_->set_quality(vector_[index].get_name(), quality, true, settings);
623  }
624 }
625 
626 bool BufferVector::is_true(void) const
627 {
628  bool result(false);
629 
631  "BufferVector::is_true: Checking for truth\n");
632 
633  if (context_)
634  {
635  ContextGuard context_guard(*context_);
636  MADARA_GUARD_TYPE guard(mutex_);
637 
638  result = true;
639 
641  "BufferVector::is_true: context was not null. Result changed to %d\n",
642  (int)result);
643 
644  for (size_t index = 0; index < vector_.size(); ++index)
645  {
647  "BufferVector::is_true: checking index %d, is_false of %d. \n",
648  (int)result, (int)context_->get(vector_[index]).is_false());
649 
650  if (context_->get(vector_[index]).is_false())
651  {
653  "BufferVector::is_true: result is false, breaking\n");
654 
655  result = false;
656  break;
657  }
658  }
659 
660  if (vector_.size() == 0)
661  result = false;
662  }
663 
665  "BufferVector::is_true: final result is %d\n", (int)result);
666 
667  return result;
668 }
669 
670 bool BufferVector::is_false(void) const
671 {
672  return !is_true();
673 }
674 
675 bool BufferVector::is_true_(void) const
676 {
677  return is_true();
678 }
679 
680 bool BufferVector::is_false_(void) const
681 {
682  return is_false();
683 }
684 }
685 }
686 }
#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::string to_string(const std::string &delimiter=", ") const
converts the value to a string.
Integer to_integer(void) const
converts the value to an integer.
bool is_false(void) const
Checks to see if the record is false.
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...
bool exists(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically checks to see if a variable already exists.
logger::Logger & get_logger(void) const
Gets the logger used for information printing.
int read_file(const std::string &key, const std::string &filename, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically reads a file into a variable.
madara::knowledge::KnowledgeRecord get(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings()) const
Atomically returns the current value of 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...
int set(const std::string &key, T &&value, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of a variable to the specific record.
bool delete_variable(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Deletes the key.
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.
VariableReference get_ref(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Atomically returns a reference to the variable.
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.
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.
Optimized reference to a variable within the knowledge base.
bool is_valid(void) const
Checks to see if the variable reference has been initialized.
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
std::string get_name(void) const
Returns the name of the container.
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 character buffers.
Definition: BufferVector.h:32
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.
knowledge::KnowledgeRecord to_record(size_t index) const
Retrieves a copy of the record from the map.
void copy_to(KnowledgeVector &target) const
Copies the vector elements to an STL vector of Knowledge Records.
int set_jpeg(size_t index, const unsigned char *value, size_t size)
Atomically sets the value of an index to a JPEG image.
std::vector< VariableReference > vector_
Values of the array.
Definition: BufferVector.h:372
void transfer_to(BufferVector &other)
Transfers elements from this vector to another.
void set_delimiter(const std::string &delimiter)
Sets the delimiter for adding and detecting subvariables.
void resize(int size=-1, bool delete_vars=true)
Resizes the vector.
VariableReference get_size_ref(void) const
Returns a reference to the size field of the current name.
size_t size(void) const
Returns the size of the local vector.
void push_back(const unsigned char *value, size_t size)
Pushes the value to the end of the array after incrementing the array size.
virtual bool is_true_(void) const
Polymorphic is true method which can be used to determine if all values in the container are true.
bool is_true(void) const
Determines if all values in the vector are true.
std::string get_delimiter(void)
Gets the delimiter for adding and detecting subvariables.
int set(size_t index, const knowledge::KnowledgeRecord &value)
Atomically sets the value of an index to a provided record.
void modify(void)
Mark the vector as modified.
knowledge::KnowledgeRecord operator[](size_t index) const
Retrieves a copy of the record from the map.
int read_file(size_t index, const std::string &filename)
Read a file into the index using stored settings.
virtual BaseContainer * clone(void) const
Clones this container.
void exchange(BufferVector &other, bool refresh_keys=true, bool delete_keys=true)
Exchanges the vector at this location with the vector at another location.
bool exists(size_t index) const
Checks to see if the index has ever been assigned a value.
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.
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 ...
std::string get_debug_info(void)
Returns the type of the container along with name and any other useful information.
void operator=(const BufferVector &rhs)
Assignment operator.
BufferVector(const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings(), const std::string &delimiter=".")
Default constructor.
std::string delimiter_
Delimiter for the prefix to subvars.
Definition: BufferVector.h:382
bool is_false(void) const
Determines if the value of the vector is false.
virtual 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: BufferVector.h:377
ThreadSafeContext * context_
Variable context that we are modifying.
Definition: BufferVector.h:367
virtual void modify_(void)
Polymorphic modify method used by collection containers.
Provides container classes for fast knowledge base access and mutation.
Definition: Barrier.h:27
constexpr string_t string
Provides functions and classes for the distributed knowledge base.
::std::vector< KnowledgeRecord > KnowledgeVector
Copyright(c) 2020 Galois.