MADARA  3.2.3
ThreadSafeContext.inl
Go to the documentation of this file.
1 #ifndef _MADARA_THREADSAFECONTEXT_INL_
2 #define _MADARA_THREADSAFECONTEXT_INL_
3 
12 
13 #include <sstream>
14 
15 namespace madara { namespace knowledge {
16 
17 inline int
19  const std::string & key,
20  const std::string & filename,
21  const KnowledgeUpdateSettings & settings)
22 {
23  VariableReference variable = get_ref (key, settings);
24  return read_file (variable, filename, settings);
25 }
26 
27 inline KnowledgeRecord
29  const std::string & key,
30  const KnowledgeReferenceSettings & settings) const
31 {
32  const KnowledgeRecord *ret = with (key, settings);
33  if (ret) {
34  return *ret;
35  }
36  return KnowledgeRecord();
37 }
38 
39 // return the value of a variable
40 inline KnowledgeRecord
42  const VariableReference & variable,
43  const KnowledgeReferenceSettings & settings) const
44 {
45  const KnowledgeRecord *ret = with (variable, settings);
46  if (ret) {
47  return *ret;
48  }
49  return KnowledgeRecord();
50 }
51 
52 inline KnowledgeRecord *
54  const std::string & key,
55  const KnowledgeReferenceSettings & settings)
56 {
57  KnowledgeMap::iterator found;
58 
59  MADARA_GUARD_TYPE guard (mutex_);
60 
61  if (settings.expand_variables)
62  {
63  std::string cur_key = expand_statement (key);
64  found = map_.find (cur_key);
65  }
66  else
67  {
68  found = map_.find (key);
69  }
70 
71  if (found != map_.end ())
72  {
73  return &found->second;
74  }
75 
76  return nullptr;
77 }
78 
79 // return the value of a variable
80 inline KnowledgeRecord *
82  const VariableReference & variable,
84 {
85  MADARA_GUARD_TYPE guard (mutex_);
86 
87  return variable.get_record_unsafe();
88 }
89 
90 inline const KnowledgeRecord *
92  const std::string & key,
93  const KnowledgeReferenceSettings & settings) const
94 {
95  KnowledgeMap::const_iterator found;
96 
97  MADARA_GUARD_TYPE guard (mutex_);
98 
99  if (settings.expand_variables)
100  {
101  std::string cur_key = expand_statement (key);
102  found = map_.find (cur_key);
103  }
104  else
105  {
106  found = map_.find (key);
107  }
108 
109  if (found != map_.end ())
110  {
111  return &found->second;
112  }
113 
114  return nullptr;
115 }
116 
117 // return the value of a variable
118 inline const KnowledgeRecord *
120  const VariableReference & variable,
121  const KnowledgeReferenceSettings &) const
122 {
123  MADARA_GUARD_TYPE guard (mutex_);
124 
125  return variable.get_record_unsafe();
126 }
127 
128 // return the value of a variable
129 inline bool
131  const VariableReference & variable,
132  const KnowledgeReferenceSettings &) const
133 {
134  MADARA_GUARD_TYPE guard (mutex_);
135 
136  auto record = variable.get_record_unsafe();
137  return record && record->exists ();
138 }
139 
140 // return the value of a variable
141 inline KnowledgeRecord
143  const VariableReference & variable,
144  size_t index,
146 {
147  MADARA_GUARD_TYPE guard (mutex_);
148 
149  auto record = variable.get_record_unsafe();
150  if (record)
151  return record->retrieve_index (index);
152  else
153  return knowledge::KnowledgeRecord ();
154 }
155 
156 inline KnowledgeRecord
158  const std::string & key,
159  size_t index,
160  const KnowledgeReferenceSettings & settings)
161 {
162  VariableReference variable = get_ref (key, settings);
163  return retrieve_index (variable, index, settings);
164 }
165 
166 template<typename T>
167 inline int
169  const std::string & key,
170  T && value,
171  const KnowledgeUpdateSettings & settings)
172 {
173  VariableReference variable = get_ref (key, settings);
174  return set (variable, std::forward<T>(value), settings);
175 }
176 
177 template<typename T>
178 inline int
180  const VariableReference & variable,
181  T && value,
182  const KnowledgeUpdateSettings & settings)
183 {
184  MADARA_GUARD_TYPE guard (mutex_);
185 
186  if (variable.is_valid())
187  return set_unsafe(variable, std::forward<T>(value), settings);
188  else
189  return -1;
190 }
191 
192 template<typename T>
193 inline int
195  const T * value,
196  uint32_t size,
197  const KnowledgeUpdateSettings & settings)
198 {
199  VariableReference variable = get_ref (key, settings);
200  return set (variable, value, size, settings);
201 }
202 
203 // set the value of a variable
204 template<typename T>
205 inline int
207  const VariableReference & variable,
208  const T * value,
209  uint32_t size,
210  const KnowledgeUpdateSettings & settings)
211 {
212  MADARA_GUARD_TYPE guard (mutex_);
213  if (variable.is_valid())
214  {
215  return set_unsafe_impl(variable, settings, value, size);
216  }
217  else
218  return -1;
219 
220  return 0;
221 }
222 
223 // set the value of a variable
224 template<typename... Args>
225 inline int
227  const VariableReference & variable,
228  const KnowledgeUpdateSettings & settings,
229  Args&&... args)
230 {
231  auto record = variable.get_record_unsafe();
232 
233  // check if we have the appropriate write quality
234  if (!settings.always_overwrite &&
235  record->write_quality < record->quality)
236  return -2;
237  else
238  record->quality = 0;
239 
240  record->set_value(std::forward<Args>(args)...);
241  record->quality = record->write_quality;
242 
243  return 0;
244 }
245 
246 template<typename T>
247 // set the value of a variable
248 inline int
250  const VariableReference & variable,
251  T && value,
252  const KnowledgeUpdateSettings & settings)
253 {
254  int ret = set_unsafe_impl(variable, settings, std::forward<T>(value));
255 
256  if (ret == 0)
257  mark_and_signal (variable, settings);
258 
259  return ret;
260 }
261 
262 template<typename T>
263 // set the value of a variable
264 inline int
266  const VariableReference & variable,
267  const T * value,
268  size_t size,
269  const KnowledgeUpdateSettings & settings)
270 {
271  int ret = set_unsafe_impl(variable, settings, value, size);
272 
273  if (ret == 0)
274  mark_and_signal (variable, settings);
275 
276  return ret;
277 }
278 
279 inline int
281  const std::string & key,
282  const char * value, size_t size,
283  const KnowledgeUpdateSettings & settings)
284 {
285  VariableReference variable = get_ref (key, settings);
286  return set_xml (variable, value, size, settings);
287 }
288 
289 inline int
291  const std::string & key,
292  const char * value, size_t size,
293  const KnowledgeUpdateSettings & settings)
294 {
295  VariableReference variable = get_ref (key, settings);
296  return set_text (variable, value, size, settings);
297 }
298 
299 inline int
301  const std::string & key,
302  const unsigned char * value, size_t size,
303  const KnowledgeUpdateSettings & settings)
304 {
305  VariableReference variable = get_ref (key, settings);
306  return set_jpeg (variable, value, size, settings);
307 }
308 
309 inline int
311  const std::string & key,
312  const unsigned char * value, size_t size,
313  const KnowledgeUpdateSettings & settings)
314 {
315  VariableReference variable = get_ref (key, settings);
316  return set_file (variable, value, size, settings);
317 }
318 
319 template<typename T>
320 inline int
322  const std::string & key,
323  size_t index, T&& value,
324  const KnowledgeUpdateSettings & settings)
325 {
326  VariableReference variable = get_ref (key, settings);
327  return set_index (variable, index, std::forward<T>(value), settings);
328 }
329 
330 template<typename T>
331 inline int
333  const VariableReference & variable, size_t index,
334  T&& value,
335  const KnowledgeUpdateSettings & settings)
336 {
337  MADARA_GUARD_TYPE guard (mutex_);
338  if (variable.is_valid())
339  return set_index_unsafe(variable, index, std::forward<T>(value), settings);
340  else
341  return -1;
342 }
343 
344 template<typename T>
345 inline int
347  const VariableReference & variable, size_t index,
348  T&& value, const KnowledgeUpdateSettings & settings)
349 {
350  auto record = variable.get_record_unsafe();
351  // check if we have the appropriate write quality
352  if (!settings.always_overwrite &&
353  record->write_quality < record->quality)
354  return -2;
355  else
356  record->quality = 0;
357 
358  record->set_index (index, std::forward<T>(value));
359  record->quality = record->write_quality;
360 
361  return 0;
362 }
363 
364 template<typename T>
365 inline int
367  const VariableReference & variable, size_t index,
368  T&& value, const KnowledgeUpdateSettings & settings)
369 {
370  int ret = set_index_unsafe_impl(variable, index,
371  std::forward<T>(value), settings);
372 
373  if (ret == 0)
374  mark_and_signal (variable, settings);
375 
376  return ret;
377 }
378 
379 inline KnowledgeRecord
381  const std::string & key,
382  const KnowledgeUpdateSettings & settings)
383 {
384  VariableReference variable = get_ref (key, settings);
385  return inc (variable, settings);
386 }
387 
388 inline KnowledgeRecord
390  const std::string & key,
391  const KnowledgeUpdateSettings & settings)
392 {
393  VariableReference variable = get_ref (key, settings);
394  return dec (variable, settings);
395 }
396 
397 inline KnowledgeRecord
399  const VariableReference & variable,
400  const KnowledgeUpdateSettings & settings)
401 {
402  MADARA_GUARD_TYPE guard (mutex_);
403  auto record = variable.get_record_unsafe();
404  if (record)
405  {
406  // check if we have the appropriate write quality
407  if (settings.always_overwrite ||
408  record->write_quality >= record->quality)
409  {
410  ++ (*record);
411  record->quality = record->write_quality;
412  mark_and_signal (variable, settings);
413  }
414 
415  return *record;
416  }
417 
418  return knowledge::KnowledgeRecord ();
419 }
420 
421 #ifndef _MADARA_NO_KARL_
422 
423 // return whether or not the key exists
424 inline bool
426 const std::string & expression)
427 {
428  MADARA_GUARD_TYPE guard (mutex_);
429 
430  return interpreter_->delete_expression (expression);
431 }
432 
433 #endif // _MADARA_NO_KARL_
434 
435 inline bool
437 const std::string & key,
438 const KnowledgeReferenceSettings & settings)
439 {
440  // enter the mutex
441  bool found (false);
442  std::string key_actual;
443  const std::string * key_ptr;
444  MADARA_GUARD_TYPE guard (mutex_);
445 
446  if (settings.expand_variables)
447  {
448  key_actual = expand_statement (key);
449  key_ptr = &key_actual;
450  }
451  else
452  key_ptr = &key;
453 
454  // find the key and update found with result of find
455  KnowledgeMap::iterator record = map_.find (*key_ptr);
456  found = record != map_.end ();
457 
458  if (found)
459  {
460  record->second.clear_value ();
461  }
462 
463  return found;
464 }
465 
466 // return whether or not the key exists
467 inline bool
469 const std::string & key,
470 const KnowledgeReferenceSettings & settings)
471 {
472  // enter the mutex
473  std::string key_actual;
474  bool result (false);
475 
476  const std::string * key_ptr;
477  MADARA_GUARD_TYPE guard (mutex_);
478 
479  if (settings.expand_variables)
480  {
481  key_actual = expand_statement (key);
482  key_ptr = &key_actual;
483  }
484  else
485  key_ptr = &key;
486 
487  // erase any changed or local changed map entries
488  changed_map_.erase (key_ptr->c_str());
489  local_changed_map_.erase (key_ptr->c_str());
490 
491  // erase the map
492  result = map_.erase (*key_ptr) == 1;
493 
494  return result;
495 }
496 
497 // return whether or not the key exists
498 inline bool
500 const VariableReference & var,
502 {
503  // enter the mutex
504  MADARA_GUARD_TYPE guard (mutex_);
505 
506  // erase any changed or local changed map entries
507  changed_map_.erase (var.entry_->first.c_str ());
508  local_changed_map_.erase (var.entry_->first.c_str ());
509 
510  // erase the map
511  return map_.erase (var.entry_->first.c_str ()) == 1;
512 }
513 
514 inline void
515 ThreadSafeContext::delete_variables(KnowledgeMap::iterator begin,
516  KnowledgeMap::iterator end,
518 {
519  for (auto cur = begin; cur != end; ++cur) {
520  changed_map_.erase (cur->first.c_str ());
521  local_changed_map_.erase (cur->first.c_str ());
522  }
523  map_.erase (begin, end);
524 }
525 
526 // return whether or not the key exists
527 inline bool
529  const std::string & key,
530  const KnowledgeReferenceSettings & settings) const
531 {
532  // enter the mutex
533  std::string key_actual;
534  const std::string * key_ptr;
535  MADARA_GUARD_TYPE guard (mutex_);
536 
537  if (settings.expand_variables)
538  {
539  key_actual = expand_statement (key);
540  key_ptr = &key_actual;
541  }
542  else
543  key_ptr = &key;
544 
545  // if key is not null
546  if (*key_ptr != "")
547  {
548  // find the key in the knowledge base
549  KnowledgeMap::const_iterator found = map_.find (*key_ptr);
550 
551  // if it's found, then return the value
552  if (found != map_.end ())
553  return found->second.status () != knowledge::KnowledgeRecord::UNCREATED;
554  }
555 
556  // if no match, return empty (0)
557  return false;
558 }
559 
560 // Atomically decrement a stored value. Only reason we are inlining this function
561 // is because it is called by only one function, and we can save a bit of
562 // execution time via expansion into that function call.
563 inline KnowledgeRecord
565  const VariableReference & variable,
566  const KnowledgeUpdateSettings & settings)
567 {
568  MADARA_GUARD_TYPE guard (mutex_);
569  auto record = variable.get_record_unsafe();
570  if (record)
571  {
572  // check if we have the appropriate write quality
573  if (settings.always_overwrite ||
574  record->write_quality >= record->quality)
575  {
576  -- (*record);
577  record->quality = record->write_quality;
578 
579  mark_and_signal (variable, settings);
580  }
581 
582  return *record;
583  }
584 
585  return knowledge::KnowledgeRecord ();
586 }
587 
590 inline uint64_t
592  uint64_t clock)
593 {
594  MADARA_GUARD_TYPE guard (mutex_);
595 
596  // clock_ is always increasing. We never reset it to a lower clock value
597  // user can check return value to see if the clock was set.
598  if (clock_ < clock)
599  clock_ = clock;
600 
601  return clock_;
602 }
603 
606 inline uint64_t
608  const std::string & key, uint64_t clock,
609  const KnowledgeReferenceSettings & settings)
610 {
611  // enter the mutex
612  std::string key_actual;
613  const std::string * key_ptr;
614  MADARA_GUARD_TYPE guard (mutex_);
615 
616  if (settings.expand_variables)
617  {
618  key_actual = expand_statement (key);
619  key_ptr = &key_actual;
620  }
621  else
622  key_ptr = &key;
623 
624  // check for null key
625  if (*key_ptr == "")
626  return 0;
627 
628  // create the key if it didn't exist
629  knowledge::KnowledgeRecord & record = map_[*key_ptr];
630 
631  // check for value already set
632  if (record.clock < clock)
633  {
634  record.clock = clock;
635 
636  // try to update the global clock as well
637  this->set_clock (clock);
638  }
639 
640  return record.clock;
641 }
642 
645 inline uint64_t
647  const std::string & key,
648  const KnowledgeUpdateSettings & settings)
649 {
650  // enter the mutex
651  std::string key_actual;
652  const std::string * key_ptr;
653  MADARA_GUARD_TYPE guard (mutex_);
654 
655  if (settings.expand_variables)
656  {
657  key_actual = expand_statement (key);
658  key_ptr = &key_actual;
659  }
660  else
661  key_ptr = &key;
662 
663  // check for null key
664  if (*key_ptr == "")
665  return 0;
666 
667  // create the key if it didn't exist
668  knowledge::KnowledgeRecord & record = map_[*key_ptr];
669 
670  return record.clock += settings.clock_increment;
671 }
672 
674 inline uint64_t
676  const KnowledgeUpdateSettings & settings)
677 {
678  MADARA_GUARD_TYPE guard (mutex_);
679  return clock_ += settings.clock_increment;
680 }
681 
684 inline uint64_t
686 {
687  MADARA_GUARD_TYPE guard (mutex_);
688  return clock_;
689 }
690 
691 inline madara::logger::Logger &
693 {
694  MADARA_GUARD_TYPE guard (mutex_);
695  return *logger_;
696 }
697 
698 inline void
700  logger::Logger & logger) const
701 {
702  MADARA_GUARD_TYPE guard (mutex_);
703  logger_ = &logger;
704 }
705 
707 inline uint64_t
709  const std::string & key,
710  const KnowledgeReferenceSettings & settings) const
711 {
712  // enter the mutex
713  std::string key_actual;
714  const std::string * key_ptr;
715  MADARA_GUARD_TYPE guard (mutex_);
716 
717  if (settings.expand_variables)
718  {
719  key_actual = expand_statement (key);
720  key_ptr = &key_actual;
721  }
722  else
723  key_ptr = &key;
724 
725  // check for null key
726  if (*key_ptr == "")
727  return 0;
728 
729  // find the key in the knowledge base
730  KnowledgeMap::const_iterator found = map_.find (*key_ptr);
731 
732  // if it's found, then compare the value
733  if (found != map_.end ())
734  {
735  return found->second.clock;
736  }
737  else
738  // key does not exist
739  return 0;
740 }
741 
744 inline void
746 {
747  mutex_.lock ();
748 }
749 
750 inline bool
752 {
753  return mutex_.try_lock ();
754 }
755 
757 inline void
759 {
760  mutex_.unlock ();
761 }
762 
765 inline void
767  const std::string & statement, unsigned int level) const
768 {
769  madara_logger_ptr_log (logger_, (int)level,
770  this->expand_statement (statement).c_str ());
771 }
772 
773 // clear all variables and their values
774 inline void
776 {
777  // enter the mutex
778  MADARA_GUARD_TYPE guard (mutex_);
779 
780  changed_map_.clear ();
781  local_changed_map_.clear ();
782 
783  if (erase)
784  {
785  map_.clear ();
786  }
787  else
788  {
789  for (KnowledgeMap::iterator i = map_.begin ();
790  i != map_.end (); ++i)
791  {
792  i->second.reset_value ();
793  }
794  }
795 
796  changed_.MADARA_CONDITION_NOTIFY_ONE ();
797 }
798 
799 
802 inline void
804  bool extra_release)
805 {
806  // enter the mutex
807  MADARA_GUARD_TYPE guard (mutex_);
808 
809  // if the caller is relying on a recursive call (e.g. KnowlegeBase::wait),
810  // we'll need to call an extra release for this to work. Otherwise, the
811  // context would remain locked to the calling thread - even though it will
812  // now be put to sleep
813  if (extra_release)
814  mutex_.MADARA_LOCK_UNLOCK ();
815 
816  changed_.wait (mutex_);
817 
818  //if (extra_release)
819  // mutex_.MADARA_LOCK_LOCK ();
820 }
821 
822 inline void
824  const std::string & key,
825  const KnowledgeUpdateSettings & settings
826  )
827 {
828  VariableReference ref = get_ref (key, settings);
829  if (ref.is_valid ())
830  mark_to_send (ref, settings);
831 }
832 
833 inline void
835  const VariableReference & ref,
836  const KnowledgeUpdateSettings & settings
837  )
838 {
839  MADARA_GUARD_TYPE guard (mutex_);
840  if (ref.is_valid()) {
841  mark_to_send_unsafe (ref, settings);
842  }
843 }
844 
845 inline void
847  VariableReference ref,
849  )
850 {
851  changed_map_[ref.get_name()] = std::move(ref);
852 
853  KnowledgeRecord &record = *ref.get_record_unsafe();
854  if (record.status () != KnowledgeRecord::MODIFIED)
855  record.set_modified ();
856 }
857 
858 inline void
860  const std::string & key,
861  const KnowledgeUpdateSettings & settings
862  )
863 {
864  VariableReference ref = get_ref (key, settings);
865  if (ref.is_valid ())
866  mark_to_checkpoint (ref, settings);
867 }
868 
869 inline void
871  const VariableReference & ref,
872  const KnowledgeUpdateSettings & settings
873  )
874 {
875  MADARA_GUARD_TYPE guard (mutex_);
876  if (ref.is_valid()) {
877  mark_to_checkpoint_unsafe (ref, settings);
878  }
879 }
880 
881 inline void
883  VariableReference ref,
885  )
886 {
887  local_changed_map_[ref.get_name()] = std::move(ref);
888 
889  KnowledgeRecord &record = *ref.get_record_unsafe();
890  if (record.status () != KnowledgeRecord::MODIFIED)
891  record.set_modified ();
892 }
893 
894 inline void
896  VariableReference ref,
897  const KnowledgeUpdateSettings & settings)
898 {
899  // otherwise set the value
900  if (ref.get_name()[0] != '.' || settings.treat_locals_as_globals)
901  {
902  if (!settings.treat_globals_as_locals)
903  {
904  mark_to_send_unsafe (std::move(ref));
905  }
906  }
907 
908  // track local changes now checkpoints all state, not just local
909  if (settings.track_local_changes)
910  {
911  mark_to_checkpoint_unsafe (std::move(ref));
912  }
913 
914  if (settings.signal_changes)
915  changed_.MADARA_CONDITION_NOTIFY_ALL ();
916 }
917 
918 inline void
920  const std::string & key,
921  const KnowledgeUpdateSettings & settings
922  )
923 {
924  VariableReference ref = get_ref (key, settings);
925  if (ref.is_valid ())
926  mark_modified (ref, settings);
927 }
928 
929 inline void
931  const VariableReference & ref,
932  const KnowledgeUpdateSettings & settings
933  )
934 {
935  MADARA_GUARD_TYPE guard (mutex_);
936  mark_and_signal (ref, settings);
937 }
938 
939 inline std::string
941 {
942  MADARA_GUARD_TYPE guard (mutex_);
943  std::stringstream result;
944 
945  result << changed_map_.size () << " modifications ready to send:\n";
946 
947  for (auto &entry : changed_map_)
948  {
949  KnowledgeRecord &record = *entry.second.get_record_unsafe();
950  if (record.is_binary_file_type ())
951  {
952  result << "File: ";
953  }
954  else if (record.type () == knowledge::KnowledgeRecord::DOUBLE)
955  {
956  result << "Double: ";
957  }
958  else if (record.type () == knowledge::KnowledgeRecord::DOUBLE_ARRAY)
959  {
960  result << "Double array: ";
961  }
962  else if (record.type () == knowledge::KnowledgeRecord::INTEGER)
963  {
964  result << "Integer: ";
965  }
966  else if (record.type () == knowledge::KnowledgeRecord::INTEGER_ARRAY)
967  {
968  result << "Integer array: ";
969  }
970  else if (record.is_string_type ())
971  {
972  result << "String: ";
973  }
974  else
975  {
976  result << "Unknown: ";
977  }
978 
979  result << entry.first << " = " << record.to_string () << "\n";
980  }
981 
982  return result.str ();
983 }
984 
985 
987 inline const VariableReferenceMap &
989 {
990  MADARA_GUARD_TYPE guard (mutex_);
991 
992  return changed_map_;
993 }
994 
995 inline VariableReferences
997 {
998  MADARA_GUARD_TYPE guard (mutex_);
999 
1000  VariableReferences snapshot;
1001  snapshot.reserve (changed_map_.size ());
1002  int cur = 0;
1003 
1005  "ThreadSafeContext::save_modifieds:" \
1006  " changed_map.size=%d, snapshot.size=%d\n",
1007  (int)changed_map_.size (), (int)snapshot.size ());
1008 
1009  for (auto &entry : changed_map_)
1010  {
1012  "ThreadSafeContext::save_modifieds:" \
1013  " snapshot[%d].name=%s\n",
1014  cur, entry.first);
1015 
1016  snapshot.emplace_back (entry.second);
1017  }
1018 
1019  return snapshot;
1020 }
1021 
1022 inline void
1024 const VariableReferences & modifieds) const
1025 {
1026  MADARA_GUARD_TYPE guard (mutex_);
1027 
1028  for (auto &entry : modifieds)
1029  {
1030  changed_map_.insert (std::make_pair(entry.get_name (), entry));
1031  }
1032 }
1033 
1035 inline const VariableReferenceMap &
1037 {
1038  MADARA_GUARD_TYPE guard (mutex_);
1039 
1040  return local_changed_map_;
1041 }
1042 
1044 inline void
1046 {
1047  MADARA_GUARD_TYPE guard (mutex_);
1048 
1049  changed_map_.clear ();
1050 }
1051 
1052 
1054 inline void
1056 {
1057  MADARA_GUARD_TYPE guard (mutex_);
1058 
1059  // each synchronization counts as an event, since this is a
1060  // pretty important networking event
1061 
1062  //++this->clock_;
1063 
1064  for (KnowledgeMap::iterator i = map_.begin ();
1065  i != map_.end ();
1066  ++i)
1067  for (auto &entry : map_)
1068  {
1069  if (entry.first.size () > 0 && entry.first[0] != '.')
1070  {
1071  // local or global doesn't matter. Clock and modification
1072  // aren't really a part of local variable checking anyway
1073  //i->second.status = KnowledgeRecord::MODIFIED;
1074 
1075  if (entry.second.status () != knowledge::KnowledgeRecord::UNCREATED)
1077  else
1078  entry.second.set_value (KnowledgeRecord::Integer (0));
1079 
1080  //i->second.clock = this->clock_;
1081  }
1082  }
1083 }
1084 
1086 inline void
1088  const std::string & variable)
1089 {
1090  MADARA_GUARD_TYPE guard (mutex_);
1091 
1092  changed_map_.erase (variable.c_str());
1093 }
1094 
1095 inline void
1097 {
1098  MADARA_GUARD_TYPE guard (mutex_);
1099 
1100  local_changed_map_.clear ();
1101 }
1102 
1103 
1105 inline void
1107 {
1108  if (lock)
1109  {
1110  MADARA_GUARD_TYPE guard (mutex_);
1111  changed_.MADARA_CONDITION_NOTIFY_ONE ();
1112  }
1113  else
1114  changed_.MADARA_CONDITION_NOTIFY_ONE ();
1115 }
1116 
1117 inline void
1119  const std::string & filename)
1120 {
1121  logger_->add_file (filename);
1122 }
1123 
1124 inline int
1126 {
1127  return logger_->get_level ();
1128 }
1129 
1130 inline void
1132 {
1133  logger_->set_level (level);
1134 }
1135 
1136 } }
1137 
1138 #endif // _MADARA_THREADSAFECONTEXT_INL_
This class encapsulates an entry in a KnowledgeBase.
bool expand_variables
Toggle for always attempting to expand variables (true) or never expanding variables (false) ...
int set(const std::string &key, T &&value, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of a variable to the specific record.
void delete_variables(KnowledgeMap::iterator begin, KnowledgeMap::iterator end, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Deletes variables.
madara::knowledge::KnowledgeMap map_
Hash table containing variable names and values.
int set_index_unsafe(const VariableReference &variable, size_t index, T &&value, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
NON-Atomically sets the value of an array index to a value.
int32_t type(void) const
returns the size of the value
uint64_t set_clock(uint64_t clock)
Atomically sets the lamport clock.
int set_index_unsafe_impl(const VariableReference &variable, size_t index, T &&value, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
uint32_t quality
priority of the update
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.
madara::knowledge::KnowledgeRecord KnowledgeRecord
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.
void mark_and_signal(VariableReference ref, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
method for marking a record modified and signaling changes
KnowledgeRecord * get_record_unsafe(void) const
Returns a pointer to the variable&#39;s KnowledgeRecord Do not use this pointer unless you&#39;ve locked the ...
void lock(void) const
Locks the mutex on this context.
bool signal_changes
Toggle whether to signal changes have happened.
bool delete_expression(const std::string &expression)
Deletes the expression from the interpreter cache.
int set_unsafe(const VariableReference &variable, T &&value, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
NON-Atomically sets the value of a variable to the specific value.
void set_level(int level)
Sets the maximum logging detail level.
Definition: Logger.inl:44
bool is_binary_file_type(void) const
returns true if the knowledge record has a binary file type
void signal(bool lock=true) const
Signals that this thread is done with the context.
const VariableReferenceMap & get_modifieds(void) const
Retrieves a list of modified variables.
void print(unsigned int level) const
Atomically prints all variables and values in the context.
VariableReferences save_modifieds(void) const
Saves the list of modified records to use later for resending.
bool exists(void) const
Checks if record exists (i.e., is not uncreated)
void attach_logger(logger::Logger &logger) const
Attaches a logger to be used for printing.
Provides knowledge logging services to files and terminals.
Definition: GlobalLogger.h:11
void mark_to_checkpoint(const VariableReference &variable, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Changes variable reference to modified at current clock for the purposes of checkpointing (even if it...
int get_log_level(void)
Gets the log level.
Optimized reference to a variable within the knowledge base.
int set_index(const std::string &key, size_t index, T &&value, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of an array index to a value.
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.
A multi-threaded logger for logging to one or more destinations.
Definition: Logger.h:88
void apply_modified(void)
Changes all global variables to modified at current clock.
int get_level(void)
Gets the maximum logging detail level.
Definition: Logger.inl:66
int status(void) const
returns the status of the record.
static struct madara::knowledge::tags::string_t string
madara::knowledge::KnowledgeRecord dec(const std::string &key, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically decrements the value of the variable.
int set_xml(const std::string &key, const char *value, size_t size, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of a variable to an XML string.
uint64_t clock_increment
Default clock increment.
void add_logger(const std::string &filename)
Adds a file to the logger.
bool try_lock(void) const
Locks the mutex on this context.
#define madara_logger_ptr_log(logger, level,...)
Fast version of the madara::logger::log method for Logger pointers.
Definition: Logger.h:32
void unlock(void) const
Unlocks the mutex on this context.
int set_unsafe_impl(const VariableReference &variable, const KnowledgeUpdateSettings &settings, Args &&...args)
const VariableReferenceMap & get_local_modified(void) const
Retrieves a list of modified local variables.
void add_file(const std::string &filename)
Adds a file to the logger.
Definition: Logger.inl:14
VariableReference get_ref(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Atomically returns a reference to the variable.
void mark_to_send_unsafe(VariableReference ref, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Changes variable to modified at current clock, and queues it to send, even if it is a local that woul...
void set_modified(void)
sets the status to modified
void wait_for_change(bool extra_release=false)
Wait for a change to happen to the context.
uint64_t inc_clock(const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically increments the Lamport clock and returns the new clock time (intended for sending knowledg...
std::map< const char *, VariableReference, VariableReferenceMapCompare > VariableReferenceMap
a map of variable references
bool always_overwrite
Toggle for always overwriting records, regardless of quality, clock values, etc.
std::vector< VariableReference > VariableReferences
a vector of variable references
int set_text(const std::string &key, const char *value, size_t size, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically sets the value of a variable to an XML string.
std::string expand_statement(const std::string &statement) const
Expands a string with variable expansion.
void mark_to_checkpoint_unsafe(VariableReference ref, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Changes variable to modified at current clock for the purposes of checkpointing.
bool delete_variable(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Deletes the key.
logger::Logger * logger_
Logger for printing.
madara::knowledge::KnowledgeRecord * with(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Atomically returns a reference to the variable.
const char * get_name(void) const
Returns the name of the variable.
Provides functions and classes for the distributed knowledge base.
uint64_t get_clock(void) const
Atomically gets the Lamport clock.
void mark_to_send(const VariableReference &variable, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Changes variable reference to modified at current clock, and queues it to send, even if it is a local...
void reset_checkpoint(void) const
Reset all checkpoint variables in the modified lists.
void add_modifieds(const VariableReferences &modifieds) const
Adds a list of VariableReferences to the current modified list.
bool clear(const std::string &key, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Clears a variable.
Settings for applying knowledge updates.
bool treat_globals_as_locals
Toggle whether updates to global variables are treated as local variables and not marked as modified ...
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.
logger::Logger & get_logger(void) const
Gets the logger used for information printing.
KnowledgeRecord retrieve_index(size_t index) const
retrieves the value at an array index.
std::string debug_modifieds(void) const
Retrieves a stringified list of all modified variables that are ready to send over transport on next ...
KnowledgeRecord retrieve_index(const std::string &key, size_t index, const KnowledgeReferenceSettings &settings=KnowledgeReferenceSettings())
Retrieves a value at a specified index within a knowledge array.
bool track_local_changes
Toggle for checkpointing support.
bool delete_expression(const std::string &expression)
Attempts to delete an expression from cache.
Definition: Interpreter.inl:82
Settings for applying knowledge updates.
bool is_string_type(void) const
returns true if the record is a string type (STRING, XML, TEXT_FILE)
std::string to_string(const std::string &delimiter=", ") const
converts the value to a string.
madara::expression::Interpreter * interpreter_
KaRL interpreter.
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...
bool treat_locals_as_globals
Toggle whether updates to local variables are treated as global variables that should be sent over th...
uint64_t clock
last modification time
void set_log_level(int level)
Sets the log level.
madara::knowledge::KnowledgeRecord inc(const std::string &key, const KnowledgeUpdateSettings &settings=KnowledgeUpdateSettings())
Atomically increments the value of the variable.
void reset_modified(void)
Reset all variables to be unmodified.