3 #ifndef _MADARA_KNOWLEDGE_RECORD_H_
4 #define _MADARA_KNOWLEDGE_RECORD_H_
17 #include <type_traits>
18 #include "madara/MadaraExport.h"
31 class ThreadSafeContext;
112 UNKNOWN_FILE_TYPE = 8,
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),
161 buf_->back().set_toi(new_toi);
168 uint32_t quality = 0;
173 uint32_t write_quality = 0;
195 uint32_t type_ = EMPTY;
201 mutable bool shared_ = OWNED;
217 void*>::
type =
nullptr>
262 explicit
KnowledgeRecord(std::unique_ptr<std::vector<
unsigned char>> value,
306 template<typename... Args>
307 void emplace_integers(Args&&... args)
309 emplace_vec<Integer, INTEGER_ARRAY, &KnowledgeRecord::int_array_>(
310 std::forward<Args>(args)...);
318 template<
typename... Args>
321 emplace_integers(std::forward<Args>(args)...);
329 template<
typename... Args>
332 emplace_vec<double, DOUBLE_ARRAY, &KnowledgeRecord::double_array_>(
333 std::forward<Args>(args)...);
341 template<
typename... Args>
344 emplace_doubles(std::forward<Args>(args)...);
352 template<
typename... Args>
355 emplace_val<std::string, STRING, &KnowledgeRecord::str_value_>(
356 std::forward<Args>(args)...);
364 template<
typename... Args>
367 emplace_string(std::forward<Args>(args)...);
375 template<
typename... Args>
378 emplace_vec<
unsigned char, UNKNOWN_FILE_TYPE,
387 template<
typename... Args>
390 emplace_binary(std::forward<Args>(args)...);
401 template<
typename... Args>
404 emplace_val<CircBuf, BUFFER, &KnowledgeRecord::buf_, true>(
405 std::forward<Args>(args)...);
413 template<
typename... Args>
416 std::make_shared<std::vector<
Integer>>(std::forward<Args>(args)...)),
426 template<
typename... Args>
429 std::make_shared<std::vector<double>>(std::forward<Args>(args)...)),
442 template<
typename... Args>
444 : str_value_(std::make_shared<std::
string>(std::forward<Args>(args)...)),
454 template<
typename... Args>
456 : file_value_(std::make_shared<std::vector<unsigned char>>(
457 std::forward<Args>(args)...)),
458 type_(UNKNOWN_FILE_TYPE)
501 void set_index(
size_t index, T value);
510 template<typename T, typename std::enable_if<std::is_floating_point<T>::value,
533 size_t to_managed_buffer(
char* buffer,
size_t buf_size)
const;
543 size_t to_managed_string(
char* buffer,
size_t buf_size)
const;
549 std::shared_ptr<const std::string> share_string()
const;
555 ssize_t to_file(
const std::string& filename)
const;
576 Integer to_integer(
void)
const;
586 double to_double(
void)
const;
592 std::vector<Integer> to_integers(
void)
const;
598 std::shared_ptr<const std::vector<Integer>> share_integers()
const;
604 std::vector<double> to_doubles(
void)
const;
610 std::shared_ptr<const std::vector<double>> share_doubles()
const;
616 std::shared_ptr<const std::vector<unsigned char>> share_binary()
const;
632 unsigned char* to_unmanaged_buffer(
size_t& size)
const;
668 void set_value(
Integer new_value);
674 void set_value(
int new_value);
680 void set_value(
size_t new_value);
687 void set_value(
const Integer* new_value, uint32_t size);
693 void set_value(std::vector<Integer>&& new_value);
699 void set_value(
const std::vector<Integer>& new_value);
705 void set_value(std::unique_ptr<std::vector<Integer>> new_value);
712 void set_value(
const char* new_value, uint32_t size);
730 void set_value(std::unique_ptr<std::string> new_value);
736 void set_value(
double new_value);
742 void set_value(
float new_value);
749 void set_value(
const double* new_value, uint32_t size);
755 void set_value(std::vector<double>&& new_value);
761 void set_value(
const std::vector<double>& new_value);
767 void set_value(std::unique_ptr<std::vector<double>> new_value);
774 void set_xml(
const char* new_value,
size_t size);
792 void set_xml(std::unique_ptr<std::string> new_value);
799 void set_text(
const char* new_value,
size_t size);
817 void set_text(std::unique_ptr<std::string> new_value);
826 static void set_precision(
int new_precision);
831 static void set_scientific(
void);
836 static void set_fixed(
void);
842 static int get_precision(
void);
849 void set_jpeg(
const unsigned char* new_value,
size_t size);
855 void set_jpeg(std::vector<unsigned char>&& new_value);
861 void set_jpeg(
const std::vector<unsigned char>& new_value);
867 void set_jpeg(std::unique_ptr<std::vector<unsigned char>> new_value);
874 void set_file(
const unsigned char* new_value,
size_t size);
880 void set_file(std::vector<unsigned char>&& new_value);
886 void set_file(
const std::vector<unsigned char>& new_value);
892 void set_file(std::unique_ptr<std::vector<unsigned char>> new_value);
916 int status(
void)
const;
921 void set_modified(
void);
927 void resize(
size_t new_size);
942 void reset_value(
void) noexcept;
945 void clear_union(
void) noexcept;
953 void clear_value(
void) noexcept;
958 uint32_t size(
void)
const;
963 uint32_t
type(
void)
const;
976 bool set_type(uint32_t
type);
982 bool is_ref_counted(
void)
const;
989 static bool is_ref_counted(uint32_t
type);
995 bool is_string_type(
void)
const;
1002 static bool is_string_type(uint32_t
type);
1008 bool is_double_type(
void)
const;
1015 static bool is_double_type(uint32_t
type);
1021 bool is_integer_type(
void)
const;
1028 static bool is_integer_type(uint32_t
type);
1034 bool is_array_type(
void)
const;
1041 static bool is_array_type(uint32_t
type);
1058 bool is_image_type(
void)
const;
1065 static bool is_image_type(uint32_t
type);
1071 bool is_file_type(
void)
const;
1078 static bool is_file_type(uint32_t
type);
1084 bool is_binary_file_type(
void)
const;
1091 static bool is_binary_file_type(uint32_t
type);
1126 bool operator!(
void)
const;
1146 template<
typename T>
1148 typename std::enable_if<!std::is_convertible<T, KnowledgeRecord>::value,
1149 decltype(this->set_value(std::forward<T>(t)), *
this)>
::type
1151 this->set_value(std::forward<T>(t));
1210 explicit operator bool(
void)
const;
1230 const char* read(
const char* buffer, int64_t& buffer_remaining);
1242 const char* buffer,
std::string& key, int64_t& buffer_remaining);
1254 const char* buffer, uint32_t& key_id, int64_t& buffer_remaining);
1272 char* write(
char* buffer, int64_t& buffer_remaining)
const;
1294 char* buffer,
const std::string& key, int64_t& buffer_remaining)
const;
1317 char* write(
char* buffer, uint32_t key_id, int64_t& buffer_remaining)
const;
1323 const std::string& key,
unsigned int quality, uint64_t clock,
1331 bool is_true(
void)
const;
1338 bool is_false(
void)
const;
1347 return status() != UNCREATED;
1355 int64_t get_encoded_size(
const std::string& key)
const;
1362 int64_t get_encoded_size(
void)
const;
1370 return type_ == BUFFER;
1378 if (type_ == BUFFER)
1380 return buf_->size();
1397 if (type_ == BUFFER)
1399 return buf_->capacity();
1419 if (type_ == BUFFER)
1425 *
this = std::move(buf_->back());
1434 buf_->reserve(size);
1441 new (&buf_) std::shared_ptr<CircBuf>(std::make_shared<CircBuf>(size));
1446 buf_->push_back(std::move(tmp));
1456 set_history_capacity(0);
1462 if (type_ != BUFFER)
1468 return buf_->front_index() + index;
1470 return buf_->back_index() + (index + 1);
1477 template<
typename Func>
1480 if (type_ != BUFFER)
1485 size_t front = buf_->front_index();
1488 size_t diff = front - index;
1499 if (count > buf_->size())
1501 count = buf_->size();
1503 for (
size_t i = index, end = index + count; i < end; ++i)
1516 template<
typename OutputIterator>
1517 size_t get_history_range(
1518 OutputIterator out,
size_t index,
size_t count)
const;
1524 template<
typename OutputIterator>
1527 return get_history(out, 0, count);
1534 template<
typename OutputIterator>
1535 auto get_oldest(OutputIterator out)
const -> decltype(*out,
size_t{})
1537 return get_oldest(out, 1);
1544 template<
typename OutputIterator>
1547 return get_history(out, -(ssize_t)count, count);
1554 template<
typename OutputIterator>
1555 auto get_newest(OutputIterator out)
const -> decltype(*out,
size_t{})
1557 return get_newest(out, 1);
1566 get_oldest(&ret, 1);
1576 get_newest(&ret, 1);
1583 return buf_->back();
1588 return buf_->back();
1598 std::vector<KnowledgeRecord> ret;
1599 get_oldest(std::back_inserter(ret), count);
1608 template<
typename T>
1612 get_oldest(std::back_inserter(ret), count);
1622 std::vector<KnowledgeRecord> ret;
1623 get_newest(std::back_inserter(ret), count);
1632 template<
typename T>
1636 get_newest(std::back_inserter(ret), count);
1645 std::vector<KnowledgeRecord> ret;
1646 get_history(std::back_inserter(ret));
1655 template<
typename OutputIterator>
1656 size_t get_history(OutputIterator out, ssize_t index,
size_t count)
const
1658 return get_history_range(out, absolute_index(index), count);
1665 template<
typename OutputIterator>
1666 auto get_history(OutputIterator out)
const -> decltype(*out,
size_t{})
1668 return get_history_range(out, 0, std::numeric_limits<size_t>::max());
1676 template<
typename T>
1680 get_history(std::back_inserter(ret));
1689 std::vector<KnowledgeRecord>
get_history(
size_t index,
size_t count)
const
1691 std::vector<KnowledgeRecord> ret;
1692 get_history(std::back_inserter(ret), index, count);
1704 get_history(&ret, index, 1);
1717 "KnowledgeRecord::get_history_newest_index: "
1718 "record has zero capacity");
1720 return buf_->back_index();
1732 "KnowledgeRecord::get_history_oldest_index: "
1733 "record has zero capacity");
1735 return buf_->front_index();
1742 std::shared_ptr<CircBuf> share_circular_buffer()
const;
1764 template<
typename... Args>
1768 return buf_->emplace_back(std::forward<Args>(args)...);
1771 template<
typename T>
1774 template<
typename T, u
int32_t Type, MemberType<T> Member,
1775 bool Overwrite = false,
typename... Args>
1778 if (has_history() && !Overwrite)
1784 emplace_hist(std::move(tmp));
1789 return *
new (&(this->*Member))
1790 std::shared_ptr<const T>(std::forward<Args>(args)...);
1793 template<
typename T, u
int32_t Type, MemberType<T> Member,
1794 bool Overwrite = false,
typename... Args>
1797 return emplace_shared_val<T, Type, Member, Overwrite>(
1798 std::move(std::make_shared<const T>(std::forward<Args>(args)...)));
1801 template<
typename T, u
int32_t Type, MemberType<std::vector<T>> Member,
1802 bool Overwrite = false,
typename... Args>
1805 return emplace_shared_val<std::vector<T>, Type, Member, Overwrite>(
1806 std::forward<Args>(args)...);
1809 template<
typename T, u
int32_t Type, MemberType<std::vector<T>> Member,
1810 bool Overwrite = false,
typename... Args>
1813 return emplace_val<std::vector<T>, Type, Member, Overwrite>(
1814 std::forward<Args>(args)...);
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_
KnowledgeRecord & ref_newest()
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.
void set_toi(uint64_t new_toi)
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,...
KnowledgeRecord() noexcept
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.
General purpose circular buffer container.
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.
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)
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.
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.
int read_file(const std::string &filename, void *&buffer, size_t &size, bool add_zero_char)
Reads a file into a provided void pointer.
constexpr bool is_floating_point()
Less verbose equivalent for std::is_floating_point.
Copyright(c) 2020 Galois.
helper type for specifying template type parameters using a function argument instead of inside expli...