MADARA  3.4.1
KnowledgeRecord.h
Go to the documentation of this file.
1 
2 
3 #ifndef _MADARA_KNOWLEDGE_RECORD_H_
4 #define _MADARA_KNOWLEDGE_RECORD_H_
5 
13 #include <string>
14 #include <vector>
15 #include <map>
16 #include <memory>
17 #include <type_traits>
18 #include "madara/MadaraExport.h"
20 #include "madara/utility/StdInt.h"
26 
27 namespace madara
28 {
29 namespace knowledge
30 {
31 class ThreadSafeContext;
32 
39 namespace tags
40 {
41 using utility::type;
42 
44 constexpr integer_t integer;
45 constexpr integer_t int_;
47 constexpr double_t double_;
48 constexpr double_t dbl;
50 constexpr integers_t integers;
51 constexpr integers_t ints;
53 constexpr doubles_t doubles;
54 constexpr doubles_t dbls;
56 constexpr string_t string;
57 constexpr string_t str;
59 constexpr binary_t binary;
60 
61 template<typename T>
62 struct any
63 {
64  any() {}
65 };
66 
67 template<typename T>
68 struct shared_t
69 {
70  shared_t() {}
71 };
72 
75 template<typename T>
77 {
78  return shared_t<T>{};
79 }
80 } // namespace tags
81 
87 class MADARA_EXPORT KnowledgeRecord
88 {
89 public:
90  // allow ThreadSafeContext to modify private members
91  friend class ThreadSafeContext;
92 
93  enum
94  {
95  UNCREATED = 0,
96  MODIFIED = 1
97  };
98 
99  enum
100  {
101  OWNED = 0,
102  SHARED = 1
103  };
104 
105  enum ValueTypes : uint32_t
106  {
107  EMPTY = 0,
108  INTEGER = 1,
109  STRING = 2,
110  DOUBLE = 4,
111  FLOAT = 4,
112  UNKNOWN_FILE_TYPE = 8,
113  XML = 16,
114  TEXT_FILE = 32,
115  INTEGER_ARRAY = 64,
116  DOUBLE_ARRAY = 128,
117  IMAGE_JPEG = 256,
118  ALL_ARRAYS = INTEGER_ARRAY | DOUBLE_ARRAY,
119  ALL_INTEGERS = INTEGER | INTEGER_ARRAY,
120  ALL_DOUBLES = DOUBLE | DOUBLE_ARRAY,
121  ALL_PRIMITIVE_TYPES =
122  INTEGER | STRING | DOUBLE | INTEGER_ARRAY | DOUBLE_ARRAY,
123  ALL_FILE_TYPES = UNKNOWN_FILE_TYPE | XML | TEXT_FILE | IMAGE_JPEG,
124  ALL_IMAGES = IMAGE_JPEG,
125  ALL_TEXT_FORMATS = XML | TEXT_FILE | STRING,
126  ALL_TYPES = ALL_PRIMITIVE_TYPES | ALL_FILE_TYPES,
127  ALL_CLEARABLES = ALL_ARRAYS | ALL_TEXT_FORMATS | ALL_FILE_TYPES,
128  BUFFER = (1UL << 31),
129  };
130 
131  typedef int64_t Integer;
132 
134 
135 private:
138 
139 public:
143  uint64_t clock = 0;
144 
145 private:
149  uint64_t toi_ = 0;
150 
151 public:
152  uint64_t toi() const
153  {
154  return toi_;
155  }
156  void set_toi(uint64_t new_toi)
157  {
158  toi_ = new_toi;
159  if (has_history())
160  {
161  buf_->back().set_toi(new_toi);
162  }
163  }
164 
168  uint32_t quality = 0;
169 
173  uint32_t write_quality = 0;
174 
175 private:
180  union {
181  Integer int_value_ = 0;
183 
184  std::shared_ptr<std::vector<Integer>> int_array_;
185  std::shared_ptr<std::vector<double>> double_array_;
186  std::shared_ptr<std::string> str_value_;
187  std::shared_ptr<std::vector<unsigned char>> file_value_;
188 
189  std::shared_ptr<CircBuf> buf_;
190  };
191 
195  uint32_t type_ = EMPTY;
196 
201  mutable bool shared_ = OWNED;
202 
203 public:
204  /* default constructor */
206 
207  explicit KnowledgeRecord(logger::Logger& logger) noexcept;
208 
209  /* Integer constructor */
210  template<typename T,
212  explicit KnowledgeRecord(
213  T value, logger::Logger& logger = *logger::global_logger.get()) noexcept;
214 
215  /* Floating point constructor */
216  template<typename T, typename std::enable_if<std::is_floating_point<T>::value,
217  void*>::type = nullptr>
218  explicit KnowledgeRecord(
219  T value, logger::Logger& logger = *logger::global_logger.get()) noexcept;
220 
221  /* Integer array constructor */
222  explicit KnowledgeRecord(const std::vector<Integer>& value,
223  logger::Logger& logger = *logger::global_logger.get());
224 
225  /* Integer array move constructor */
226  explicit KnowledgeRecord(std::vector<Integer>&& value,
227  logger::Logger& logger = *logger::global_logger.get()) noexcept;
228 
229  /* Integer array unique_ptr constructor */
230  explicit KnowledgeRecord(std::unique_ptr<std::vector<Integer>> value,
231  logger::Logger& logger = *logger::global_logger.get()) noexcept;
232 
233  /* Double array constructor */
234  explicit KnowledgeRecord(const std::vector<double>& value,
235  logger::Logger& logger = *logger::global_logger.get());
236 
237  /* Double array move constructor */
238  explicit KnowledgeRecord(std::vector<double>&& value,
239  logger::Logger& logger = *logger::global_logger.get()) noexcept;
240 
241  /* Double array unique_ptr constructor */
242  explicit KnowledgeRecord(std::unique_ptr<std::vector<double>> value,
243  logger::Logger& logger = *logger::global_logger.get()) noexcept;
244 
245  /* String constructor */
246  KnowledgeRecord(const std::string& value,
247  logger::Logger& logger = *logger::global_logger.get());
248 
249  /* String move constructor */
250  explicit KnowledgeRecord(std::string&& value,
251  logger::Logger& logger = *logger::global_logger.get()) noexcept;
252 
253  /* Double array unique_ptr constructor */
254  explicit KnowledgeRecord(std::unique_ptr<std::string> value,
255  logger::Logger& logger = *logger::global_logger.get()) noexcept;
256 
257  /* Char pointer constructor for g++ */
258  explicit KnowledgeRecord(
259  const char* value, logger::Logger& logger = *logger::global_logger.get());
260 
261  /* Binary file unique_ptr constructor */
262  explicit KnowledgeRecord(std::unique_ptr<std::vector<unsigned char>> value,
263  logger::Logger& logger = *logger::global_logger.get()) noexcept;
264 
272  explicit KnowledgeRecord(const CircBuf& buffer,
273  logger::Logger& logger = *logger::global_logger.get());
274 
282  explicit KnowledgeRecord(CircBuf&& buffer,
283  logger::Logger& logger = *logger::global_logger.get()) noexcept;
284 
289  KnowledgeRecord(const KnowledgeRecord& rhs);
290 
295  KnowledgeRecord(KnowledgeRecord&& rhs) noexcept;
296 
297  /* destructor */
298  ~KnowledgeRecord() noexcept;
299 
300 public:
306  template<typename... Args>
307  void emplace_integers(Args&&... args)
308  {
309  emplace_vec<Integer, INTEGER_ARRAY, &KnowledgeRecord::int_array_>(
310  std::forward<Args>(args)...);
311  }
312 
318  template<typename... Args>
319  void emplace(tags::integers_t, Args&&... args)
320  {
321  emplace_integers(std::forward<Args>(args)...);
322  }
323 
329  template<typename... Args>
330  void emplace_doubles(Args&&... args)
331  {
332  emplace_vec<double, DOUBLE_ARRAY, &KnowledgeRecord::double_array_>(
333  std::forward<Args>(args)...);
334  }
335 
341  template<typename... Args>
342  void emplace(tags::doubles_t, Args&&... args)
343  {
344  emplace_doubles(std::forward<Args>(args)...);
345  }
346 
352  template<typename... Args>
353  void emplace_string(Args&&... args)
354  {
355  emplace_val<std::string, STRING, &KnowledgeRecord::str_value_>(
356  std::forward<Args>(args)...);
357  }
358 
364  template<typename... Args>
365  void emplace(tags::string_t, Args&&... args)
366  {
367  emplace_string(std::forward<Args>(args)...);
368  }
369 
375  template<typename... Args>
376  void emplace_file(Args&&... args)
377  {
378  emplace_vec<unsigned char, UNKNOWN_FILE_TYPE,
379  &KnowledgeRecord::file_value_>(std::forward<Args>(args)...);
380  }
381 
387  template<typename... Args>
388  void emplace(tags::binary_t, Args&&... args)
389  {
390  emplace_binary(std::forward<Args>(args)...);
391  }
392 
401  template<typename... Args>
402  void overwrite_circular_buffer(Args&&... args)
403  {
404  emplace_val<CircBuf, BUFFER, &KnowledgeRecord::buf_, true>(
405  std::forward<Args>(args)...);
406  }
407 
413  template<typename... Args>
415  : int_array_(
416  std::make_shared<std::vector<Integer>>(std::forward<Args>(args)...)),
417  type_(INTEGER_ARRAY)
418  {
419  }
420 
426  template<typename... Args>
428  : double_array_(
429  std::make_shared<std::vector<double>>(std::forward<Args>(args)...)),
430  type_(DOUBLE_ARRAY)
431  {
432  }
433 
442  template<typename... Args>
444  : str_value_(std::make_shared<std::string>(std::forward<Args>(args)...)),
445  type_(STRING)
446  {
447  }
448 
454  template<typename... Args>
456  : file_value_(std::make_shared<std::vector<unsigned char>>(
457  std::forward<Args>(args)...)),
458  type_(UNKNOWN_FILE_TYPE)
459  {
460  }
461 
466  bool exists(void) const;
467 
474  KnowledgeRecord retrieve_index(size_t index) const;
475 
482  KnowledgeRecord dec_index(size_t index);
483 
490  KnowledgeRecord inc_index(size_t index);
491 
499  template<typename T,
501  void set_index(size_t index, T value);
502 
510  template<typename T, typename std::enable_if<std::is_floating_point<T>::value,
511  void*>::type = nullptr>
512  void set_index(size_t index, T value);
513 
520  std::string to_string(const std::string& delimiter = ", ") const;
521 
533  size_t to_managed_buffer(char* buffer, size_t buf_size) const;
534 
543  size_t to_managed_string(char* buffer, size_t buf_size) const;
544 
549  std::shared_ptr<const std::string> share_string() const;
550 
555  ssize_t to_file(const std::string& filename) const;
556 
561  void unshare(void);
562 
566  KnowledgeRecord* clone(void) const;
567 
576  Integer to_integer(void) const;
577 
586  double to_double(void) const;
587 
592  std::vector<Integer> to_integers(void) const;
593 
598  std::shared_ptr<const std::vector<Integer>> share_integers() const;
599 
604  std::vector<double> to_doubles(void) const;
605 
610  std::shared_ptr<const std::vector<double>> share_doubles() const;
611 
616  std::shared_ptr<const std::vector<unsigned char>> share_binary() const;
617 
632  unsigned char* to_unmanaged_buffer(size_t& size) const;
633 
640  void set_value(const KnowledgeRecord& new_value);
641 
648  void set_value(KnowledgeRecord&& new_value);
649 
655  void set_full(const KnowledgeRecord& new_value);
656 
662  void set_full(KnowledgeRecord&& new_value);
663 
668  void set_value(Integer new_value);
669 
674  void set_value(int new_value);
675 
680  void set_value(size_t new_value);
681 
687  void set_value(const Integer* new_value, uint32_t size);
688 
693  void set_value(std::vector<Integer>&& new_value);
694 
699  void set_value(const std::vector<Integer>& new_value);
700 
705  void set_value(std::unique_ptr<std::vector<Integer>> new_value);
706 
712  void set_value(const char* new_value, uint32_t size);
713 
718  void set_value(std::string&& new_value);
719 
724  void set_value(const std::string& new_value);
725 
730  void set_value(std::unique_ptr<std::string> new_value);
731 
736  void set_value(double new_value);
737 
742  void set_value(float new_value);
743 
749  void set_value(const double* new_value, uint32_t size);
750 
755  void set_value(std::vector<double>&& new_value);
756 
761  void set_value(const std::vector<double>& new_value);
762 
767  void set_value(std::unique_ptr<std::vector<double>> new_value);
768 
774  void set_xml(const char* new_value, size_t size);
775 
780  void set_xml(std::string&& new_value);
781 
786  void set_xml(const std::string& new_value);
787 
792  void set_xml(std::unique_ptr<std::string> new_value);
793 
799  void set_text(const char* new_value, size_t size);
800 
805  void set_text(std::string&& new_value);
806 
811  void set_text(const std::string& new_value);
812 
817  void set_text(std::unique_ptr<std::string> new_value);
818 
826  static void set_precision(int new_precision);
827 
831  static void set_scientific(void);
832 
836  static void set_fixed(void);
837 
842  static int get_precision(void);
843 
849  void set_jpeg(const unsigned char* new_value, size_t size);
850 
855  void set_jpeg(std::vector<unsigned char>&& new_value);
856 
861  void set_jpeg(const std::vector<unsigned char>& new_value);
862 
867  void set_jpeg(std::unique_ptr<std::vector<unsigned char>> new_value);
868 
874  void set_file(const unsigned char* new_value, size_t size);
875 
880  void set_file(std::vector<unsigned char>&& new_value);
881 
886  void set_file(const std::vector<unsigned char>& new_value);
887 
892  void set_file(std::unique_ptr<std::vector<unsigned char>> new_value);
893 
901  void deep_copy(const KnowledgeRecord& source);
902 
910  KnowledgeRecord deep_copy() const;
911 
916  int status(void) const;
917 
921  void set_modified(void);
922 
927  void resize(size_t new_size);
928 
937  int read_file(const std::string& filename, uint32_t read_as_type = 0);
938 
942  void reset_value(void) noexcept;
943 
944 private:
945  void clear_union(void) noexcept;
946 
947 public:
953  void clear_value(void) noexcept;
954 
958  uint32_t size(void) const;
959 
963  uint32_t type(void) const;
964 
976  bool set_type(uint32_t type);
977 
982  bool is_ref_counted(void) const;
983 
989  static bool is_ref_counted(uint32_t type);
990 
995  bool is_string_type(void) const;
996 
1002  static bool is_string_type(uint32_t type);
1003 
1008  bool is_double_type(void) const;
1009 
1015  static bool is_double_type(uint32_t type);
1016 
1021  bool is_integer_type(void) const;
1022 
1028  static bool is_integer_type(uint32_t type);
1029 
1034  bool is_array_type(void) const;
1035 
1041  static bool is_array_type(uint32_t type);
1042 
1052  KnowledgeRecord fragment(unsigned int first, unsigned int last);
1053 
1058  bool is_image_type(void) const;
1059 
1065  static bool is_image_type(uint32_t type);
1066 
1071  bool is_file_type(void) const;
1072 
1078  static bool is_file_type(uint32_t type);
1079 
1084  bool is_binary_file_type(void) const;
1085 
1091  static bool is_binary_file_type(uint32_t type);
1092 
1096  bool operator<(const KnowledgeRecord& rhs) const;
1097 
1101  bool operator<=(const KnowledgeRecord& rhs) const;
1102 
1106  bool operator==(const KnowledgeRecord& rhs) const;
1107 
1111  bool operator!=(const KnowledgeRecord& rhs) const;
1112 
1116  bool operator>(const KnowledgeRecord& rhs) const;
1117 
1121  bool operator>=(const KnowledgeRecord& rhs) const;
1122 
1126  bool operator!(void) const;
1127 
1131  KnowledgeRecord operator-(void) const;
1132 
1136  KnowledgeRecord& operator=(const KnowledgeRecord& rhs);
1137 
1141  KnowledgeRecord& operator=(KnowledgeRecord&& rhs) noexcept;
1142 
1146  template<typename T>
1147  auto operator=(T&& t) ->
1148  typename std::enable_if<!std::is_convertible<T, KnowledgeRecord>::value,
1149  decltype(this->set_value(std::forward<T>(t)), *this)>::type
1150  {
1151  this->set_value(std::forward<T>(t));
1152  return *this;
1153  }
1154 
1159 
1164 
1169 
1174 
1179 
1183  KnowledgeRecord operator*(const KnowledgeRecord& rhs) const;
1184 
1188  KnowledgeRecord operator/(const KnowledgeRecord& rhs) const;
1189 
1193  KnowledgeRecord operator%(const KnowledgeRecord& rhs) const;
1194 
1198  KnowledgeRecord operator+(const KnowledgeRecord& rhs) const;
1199 
1203  KnowledgeRecord operator-(const KnowledgeRecord& rhs) const;
1204 
1210  explicit operator bool(void) const;
1211 
1215  KnowledgeRecord& operator++(void);
1216 
1220  KnowledgeRecord& operator--(void);
1221 
1230  const char* read(const char* buffer, int64_t& buffer_remaining);
1231 
1241  const char* read(
1242  const char* buffer, std::string& key, int64_t& buffer_remaining);
1243 
1253  const char* read(
1254  const char* buffer, uint32_t& key_id, int64_t& buffer_remaining);
1255 
1272  char* write(char* buffer, int64_t& buffer_remaining) const;
1273 
1293  char* write(
1294  char* buffer, const std::string& key, int64_t& buffer_remaining) const;
1295 
1317  char* write(char* buffer, uint32_t key_id, int64_t& buffer_remaining) const;
1318 
1322  int apply(madara::knowledge::ThreadSafeContext& context,
1323  const std::string& key, unsigned int quality, uint64_t clock,
1324  bool perform_lock);
1325 
1331  bool is_true(void) const;
1332 
1338  bool is_false(void) const;
1339 
1345  inline bool is_valid(void) const
1346  {
1347  return status() != UNCREATED;
1348  }
1349 
1355  int64_t get_encoded_size(const std::string& key) const;
1356 
1362  int64_t get_encoded_size(void) const;
1363 
1368  bool has_history() const
1369  {
1370  return type_ == BUFFER;
1371  }
1372 
1376  size_t get_history_size() const
1377  {
1378  if (type_ == BUFFER)
1379  {
1380  return buf_->size();
1381  }
1382 
1383  if (exists())
1384  {
1385  return 1;
1386  }
1387 
1388  return 0;
1389  }
1390 
1395  size_t get_history_capacity() const
1396  {
1397  if (type_ == BUFFER)
1398  {
1399  return buf_->capacity();
1400  }
1401  else
1402  {
1403  return 0;
1404  }
1405  }
1406 
1417  void set_history_capacity(size_t size)
1418  {
1419  if (type_ == BUFFER)
1420  {
1421  if (size == 0)
1422  {
1423  if (!buf_->empty())
1424  {
1425  *this = std::move(buf_->back());
1426  }
1427  else
1428  {
1429  reset_value();
1430  }
1431  }
1432  else
1433  {
1434  buf_->reserve(size);
1435  }
1436  }
1437  else if (size > 0)
1438  {
1439  KnowledgeRecord tmp = *this;
1440 
1441  new (&buf_) std::shared_ptr<CircBuf>(std::make_shared<CircBuf>(size));
1442  type_ = BUFFER;
1443 
1444  if (tmp.exists())
1445  {
1446  buf_->push_back(std::move(tmp));
1447  }
1448  }
1449  }
1450 
1455  {
1456  set_history_capacity(0);
1457  }
1458 
1459 private:
1460  size_t absolute_index(ssize_t index) const
1461  {
1462  if (type_ != BUFFER)
1463  {
1464  return 0;
1465  }
1466  if (index >= 0)
1467  {
1468  return buf_->front_index() + index;
1469  }
1470  return buf_->back_index() + (index + 1);
1471  }
1472 
1473 public:
1477  template<typename Func>
1478  size_t for_history_range(Func&& func, size_t index, size_t count) const
1479  {
1480  if (type_ != BUFFER)
1481  {
1482  func(*this);
1483  return 1;
1484  }
1485  size_t front = buf_->front_index();
1486  if (index < front)
1487  {
1488  size_t diff = front - index;
1489  if (count > diff)
1490  {
1491  count -= diff;
1492  }
1493  else
1494  {
1495  count = 0;
1496  }
1497  index = front;
1498  }
1499  if (count > buf_->size())
1500  {
1501  count = buf_->size();
1502  }
1503  for (size_t i = index, end = index + count; i < end; ++i)
1504  {
1505  func((*buf_)[i]);
1506  }
1507  return count;
1508  }
1509 
1516  template<typename OutputIterator>
1517  size_t get_history_range(
1518  OutputIterator out, size_t index, size_t count) const;
1519 
1524  template<typename OutputIterator>
1525  size_t get_oldest(OutputIterator out, size_t count) const
1526  {
1527  return get_history(out, 0, count);
1528  }
1529 
1534  template<typename OutputIterator>
1535  auto get_oldest(OutputIterator out) const -> decltype(*out, size_t{})
1536  {
1537  return get_oldest(out, 1);
1538  }
1539 
1544  template<typename OutputIterator>
1545  size_t get_newest(OutputIterator out, size_t count) const
1546  {
1547  return get_history(out, -(ssize_t)count, count);
1548  }
1549 
1554  template<typename OutputIterator>
1555  auto get_newest(OutputIterator out) const -> decltype(*out, size_t{})
1556  {
1557  return get_newest(out, 1);
1558  }
1559 
1564  {
1565  KnowledgeRecord ret;
1566  get_oldest(&ret, 1);
1567  return ret;
1568  }
1569 
1574  {
1575  KnowledgeRecord ret;
1576  get_newest(&ret, 1);
1577  return ret;
1578  }
1579 
1580 private:
1582  {
1583  return buf_->back();
1584  }
1585 
1587  {
1588  return buf_->back();
1589  }
1590 
1591 public:
1596  std::vector<KnowledgeRecord> get_oldest(size_t count) const
1597  {
1598  std::vector<KnowledgeRecord> ret;
1599  get_oldest(std::back_inserter(ret), count);
1600  return ret;
1601  }
1602 
1608  template<typename T>
1609  std::vector<T> get_oldest(size_t count) const
1610  {
1611  std::vector<T> ret;
1612  get_oldest(std::back_inserter(ret), count);
1613  return ret;
1614  }
1615 
1620  std::vector<KnowledgeRecord> get_newest(size_t count) const
1621  {
1622  std::vector<KnowledgeRecord> ret;
1623  get_newest(std::back_inserter(ret), count);
1624  return ret;
1625  }
1626 
1632  template<typename T>
1633  std::vector<T> get_newest(size_t count) const
1634  {
1635  std::vector<T> ret;
1636  get_newest(std::back_inserter(ret), count);
1637  return ret;
1638  }
1639 
1643  std::vector<KnowledgeRecord> get_history() const
1644  {
1645  std::vector<KnowledgeRecord> ret;
1646  get_history(std::back_inserter(ret));
1647  return ret;
1648  }
1649 
1655  template<typename OutputIterator>
1656  size_t get_history(OutputIterator out, ssize_t index, size_t count) const
1657  {
1658  return get_history_range(out, absolute_index(index), count);
1659  }
1660 
1665  template<typename OutputIterator>
1666  auto get_history(OutputIterator out) const -> decltype(*out, size_t{})
1667  {
1668  return get_history_range(out, 0, std::numeric_limits<size_t>::max());
1669  }
1670 
1676  template<typename T>
1677  std::vector<T> get_history() const
1678  {
1679  std::vector<T> ret;
1680  get_history(std::back_inserter(ret));
1681  return ret;
1682  }
1683 
1689  std::vector<KnowledgeRecord> get_history(size_t index, size_t count) const
1690  {
1691  std::vector<KnowledgeRecord> ret;
1692  get_history(std::back_inserter(ret), index, count);
1693  return ret;
1694  }
1695 
1701  KnowledgeRecord get_history(size_t index) const
1702  {
1703  KnowledgeRecord ret;
1704  get_history(&ret, index, 1);
1705  return ret;
1706  }
1707 
1713  {
1714  if (!has_history())
1715  {
1717  "KnowledgeRecord::get_history_newest_index: "
1718  "record has zero capacity");
1719  }
1720  return buf_->back_index();
1721  }
1722 
1728  {
1729  if (!has_history())
1730  {
1732  "KnowledgeRecord::get_history_oldest_index: "
1733  "record has zero capacity");
1734  }
1735  return buf_->front_index();
1736  }
1737 
1742  std::shared_ptr<CircBuf> share_circular_buffer() const;
1743 
1749  void copy_metadata(const KnowledgeRecord& new_value);
1750 
1755  void overwrite(const KnowledgeRecord& new_value);
1756 
1761  void overwrite(KnowledgeRecord&& new_value);
1762 
1763 private:
1764  template<typename... Args>
1766  {
1767  unshare();
1768  return buf_->emplace_back(std::forward<Args>(args)...);
1769  }
1770 
1771  template<typename T>
1772  using MemberType = std::shared_ptr<T> KnowledgeRecord::*;
1773 
1774  template<typename T, uint32_t Type, MemberType<T> Member,
1775  bool Overwrite = false, typename... Args>
1776  std::shared_ptr<const T> emplace_shared_val(Args&&... args)
1777  {
1778  if (has_history() && !Overwrite)
1779  {
1780  KnowledgeRecord tmp;
1781  tmp.copy_metadata(*this);
1782  auto ret =
1783  tmp.emplace_shared_val<T, Type, Member>(std::forward<Args>(args)...);
1784  emplace_hist(std::move(tmp));
1785  return ret;
1786  }
1787  clear_union();
1788  type_ = Type;
1789  return *new (&(this->*Member))
1790  std::shared_ptr<const T>(std::forward<Args>(args)...);
1791  }
1792 
1793  template<typename T, uint32_t Type, MemberType<T> Member,
1794  bool Overwrite = false, typename... Args>
1795  std::shared_ptr<const T> emplace_val(Args&&... args)
1796  {
1797  return emplace_shared_val<T, Type, Member, Overwrite>(
1798  std::move(std::make_shared<const T>(std::forward<Args>(args)...)));
1799  }
1800 
1801  template<typename T, uint32_t Type, MemberType<std::vector<T>> Member,
1802  bool Overwrite = false, typename... Args>
1803  std::shared_ptr<const std::vector<T>> emplace_shared_vec(Args&&... args)
1804  {
1805  return emplace_shared_val<std::vector<T>, Type, Member, Overwrite>(
1806  std::forward<Args>(args)...);
1807  }
1808 
1809  template<typename T, uint32_t Type, MemberType<std::vector<T>> Member,
1810  bool Overwrite = false, typename... Args>
1811  std::shared_ptr<const std::vector<T>> emplace_vec(Args&&... args)
1812  {
1813  return emplace_val<std::vector<T>, Type, Member, Overwrite>(
1814  std::forward<Args>(args)...);
1815  }
1816 };
1817 
1818 typedef ::std::map<std::string, KnowledgeRecord> KnowledgeMap;
1819 typedef ::std::multimap<std::string, KnowledgeRecord> KnowledgeMultiMap;
1820 typedef ::std::vector<KnowledgeRecord> KnowledgeVector;
1821 typedef ::std::vector<std::string> KnowledgeRules;
1822 typedef ::std::vector<std::string> StringVector;
1823 typedef ::std::map<std::string, KnowledgeRecord*> KnowledgeRecords;
1824 
1827 
1828 MADARA_EXPORT void safe_clear(KnowledgeMap& map);
1829 
1835 uint32_t max_quality(const KnowledgeRecords& records);
1836 
1842 uint32_t max_quality(const KnowledgeMap& records);
1843 
1844 } // namespace knowledge
1845 } // namespace madara
1846 
1850 // inline std::ostream & operator<< (std::ostream & stream,
1851 // const madara::knowledge::KnowledgeRecord & rhs);
1852 
1853 #include "KnowledgeRecord.inl"
1854 
1855 #endif // _MADARA_KNOWLEDGE_RECORD_H_
1856 
1857 #include "KnowledgeCast.h"
madara::knowledge::KnowledgeRecord KnowledgeRecord
An exception for out-of-bounds accessing in arrays/vectors.
This class encapsulates an entry in a KnowledgeBase.
std::shared_ptr< const T > emplace_val(Args &&... args)
bool has_history() const
Return true if this record has a circular buffer history.
size_t get_history_capacity() const
Return the maximum amount of history this record can hold.
KnowledgeRecord(tags::doubles_t, Args &&... args)
Forwarding constructor for double arrays Each argument past the first will be forwarded to construct ...
std::shared_ptr< std::string > str_value_
KnowledgeRecord(tags::integers_t, Args &&... args)
Forwarding constructor for integer arrays Each argument past the first will be forwarded to construct...
void emplace_file(Args &&... args)
Construct a file (vector of unsigned char) within this KnowledgeRecord.
size_t get_history_newest_index() const
Gets the absolute index of the newest element in stored history.
std::shared_ptr< const std::vector< T > > emplace_vec(Args &&... args)
void emplace(tags::binary_t, Args &&... args)
Construct a binary (vector of unsigned char) within this KnowledgeRecord.
size_t get_history_oldest_index() const
Gets the absolute index of the oldest element in stored history.
void copy_metadata(const KnowledgeRecord &new_value)
Set metadata of this record equal to that of new_value, but doesn't change value.
std::shared_ptr< const T > emplace_shared_val(Args &&... args)
std::shared_ptr< std::vector< unsigned char > > file_value_
void emplace_doubles(Args &&... args)
Construct a vector of doubles within this KnowledgeRecord.
auto get_history(OutputIterator out) const -> decltype(*out, size_t{})
Copy the stored history of this record to the given output iterator, in order from oldest to newest.
std::shared_ptr< std::vector< double > > double_array_
size_t get_history_size() const
Return the amount of history this record holds.
void set_index(size_t index, T value)
sets the value at the index to the specified value.
size_t get_newest(OutputIterator out, size_t count) const
Copy the count newest stored history entries of this record to the given output iterator,...
void emplace(tags::integers_t, Args &&... args)
Construct a vector of integers within this KnowledgeRecord.
auto get_newest(OutputIterator out) const -> decltype(*out, size_t{})
Copy the newest stored history entry of this record to the given output iterator.
std::vector< KnowledgeRecord > get_newest(size_t count) const
Return the count newest stored history entries of this record in a vector.
std::vector< T > get_history() const
Get a copy of the entire stored history of this record in a vector of the given element type,...
KnowledgeRecord get_oldest() const
Return the oldest stored history entry of this record.
std::vector< T > get_oldest(size_t count) const
Return the count oldest stored history entries of this record in a vector of the given element type,...
std::vector< T > get_newest(size_t count) const
Return the count newest stored history entries of this record in a vector of the given element type,...
void emplace(tags::doubles_t, Args &&... args)
Construct a vector of doubles within this KnowledgeRecord.
size_t for_history_range(Func &&func, size_t index, size_t count) const
Execute a callable for each history element.
KnowledgeRecord(tags::string_t, Args &&... args)
Forwarding constructor for strings Each argument past the first will be forwarded to construct a std:...
void emplace(tags::string_t, Args &&... args)
Construct a string within this KnowledgeRecord.
std::shared_ptr< std::vector< Integer > > int_array_
bool exists(void) const
Checks if record exists (i.e., is not uncreated)
bool is_valid(void) const
Checks to see if the record is valid.
auto operator=(T &&t) -> typename std::enable_if<!std::is_convertible< T, KnowledgeRecord >::value, decltype(this->set_value(std::forward< T >(t)), *this)>::type
Assigns a convertible value to the knowledge record.
KnowledgeRecord get_newest() const
Return the newest stored history entry of this record.
std::vector< KnowledgeRecord > get_oldest(size_t count) const
Return the count oldest stored history entries of this record in a vector.
void emplace_string(Args &&... args)
Construct a string within this KnowledgeRecord.
size_t get_oldest(OutputIterator out, size_t count) const
Copy the count oldest stored history entries of this record to the given output iterator,...
std::vector< KnowledgeRecord > get_history(size_t index, size_t count) const
Return a copy of the given range of history in a vector.
std::shared_ptr< const std::vector< T > > emplace_shared_vec(Args &&... args)
std::shared_ptr< CircBuf > buf_
KnowledgeRecord(tags::binary_t, Args &&... args)
Forwarding constructor for binary files (blobs) Each argument past the first will be forwarded to con...
void clear_history()
Clear all history for this record, keeping the current value.
std::vector< KnowledgeRecord > get_history() const
Get a copy of the entire stored history of this record.
KnowledgeRecord & emplace_hist(Args &&... args)
auto get_oldest(OutputIterator out) const -> decltype(*out, size_t{})
Copy the oldest stored history entry of this record to the given output iterator.
const KnowledgeRecord & ref_newest() const
std::shared_ptr< T > KnowledgeRecord::* MemberType
void set_history_capacity(size_t size)
Set the capacity of this record's history circular buffer.
size_t get_history(OutputIterator out, ssize_t index, size_t count) const
Copy the given range of history to the output iterator given.
size_t absolute_index(ssize_t index) const
void overwrite_circular_buffer(Args &&... args)
Construct a CircularBuffer within this KnowledgeRecord directly.
KnowledgeRecord get_history(size_t index) const
Return the given entry in this record's history.
This class stores variables and their values for use by any entity needing state information in a thr...
A multi-threaded logger for logging to one or more destinations.
Definition: Logger.h:165
General purpose circular buffer container.
constexpr doubles_t doubles
constexpr string_t str
constexpr double_t dbl
constexpr integers_t integers
constexpr string_t string
constexpr integer_t integer
shared_t< T > shared(T)
Used to signal in-place shared_ptr construction in KnowledgeRecord Example: tags::shared(tags::intege...
constexpr double_t double_
constexpr binary_t binary
constexpr doubles_t dbls
constexpr integer_t int_
constexpr integers_t ints
Provides functions and classes for the distributed knowledge base.
::std::map< std::string, KnowledgeRecord * > KnowledgeRecords
::std::vector< KnowledgeRecord > KnowledgeVector
auto operator-(const KnowledgeRecord &l, const T &r) -> decltype(l - knowledge_cast(r))
T get(const KnowledgeRecord &kr)
Get the value of a KnowlegeRecord.
Definition: GetRecord.h:121
uint32_t max_quality(const KnowledgeRecords &records)
Returns the maximum quality within the records.
auto operator==(const KnowledgeRecord &l, const T &r) -> decltype(knowledge_cast< T >(l)==r)
::std::vector< std::string > StringVector
void safe_clear(KnowledgeMap &map)
auto operator-=(KnowledgeRecord &l, const T &r) -> decltype(l -=knowledge_cast(r))
auto operator*(const KnowledgeRecord &l, const T &r) -> decltype(l *knowledge_cast(r))
auto operator/=(KnowledgeRecord &l, const T &r) -> decltype(l/=knowledge_cast(r))
::std::multimap< std::string, KnowledgeRecord > KnowledgeMultiMap
auto operator>=(const KnowledgeRecord &l, const T &r) -> decltype(knowledge_cast< T >(l) >=r)
auto operator/(const KnowledgeRecord &l, const T &r) -> decltype(l/knowledge_cast(r))
auto operator%=(KnowledgeRecord &l, const T &r) -> decltype(l %=knowledge_cast(r))
auto operator%(const KnowledgeRecord &l, const T &r) -> decltype(l % knowledge_cast(r))
KnowledgeRecord KnowledgeValue
auto operator<(const KnowledgeRecord &l, const T &r) -> decltype(knowledge_cast< T >(l)< r)
std::string KnowledgeKey
auto operator+(const KnowledgeRecord &l, const T &r) -> decltype(l+knowledge_cast(r))
auto operator!=(const KnowledgeRecord &l, const T &r) -> decltype(knowledge_cast< T >(l) !=r)
::std::vector< std::string > KnowledgeRules
auto operator*=(KnowledgeRecord &l, const T &r) -> decltype(l *=knowledge_cast(r))
auto operator+=(KnowledgeRecord &l, const T &r) -> decltype(l+=knowledge_cast(r))
auto operator<=(const KnowledgeRecord &l, const T &r) -> decltype(knowledge_cast< T >(l)<=r)
::std::map< std::string, KnowledgeRecord > KnowledgeMap
auto operator>(const KnowledgeRecord &l, const T &r) -> decltype(knowledge_cast< T >(l) > r)
Provides knowledge logging services to files and terminals.
Definition: GlobalLogger.h:12
MADARA_EXPORT utility::Refcounter< logger::Logger > global_logger
MADARA_EXPORT bool exists(const char *originator, uint64_t clock, uint32_t update_number, OriginatorFragmentMap &map)
Checks if a fragment already exists within a fragment map.
typename std::enable_if< Pred, T >::type enable_if_
Less verbose synonym for std::enable_if.
Definition: StlHelper.h:74
int read_file(const std::string &filename, void *&buffer, size_t &size, bool add_zero_char)
Reads a file into a provided void pointer.
Definition: Utility.cpp:418
constexpr bool is_floating_point()
Less verbose equivalent for std::is_floating_point.
Definition: StlHelper.h:145
Copyright(c) 2020 Galois.
helper type for specifying template type parameters using a function argument instead of inside expli...
Definition: StlHelper.h:67