3 #ifndef _KNOWLEDGE_RECORD_INL_
4 #define _KNOWLEDGE_RECORD_INL_
31 template<typename T, utility::enable_if_<utility::is_int_numeric<T>(),
int>>
34 : logger_(&
logger), int_value_((
Integer)value), type_(INTEGER)
39 typename std::enable_if<std::is_floating_point<T>::value,
void*>
::type>
42 : logger_(&
logger), double_value_((
double)value), type_(DOUBLE)
57 set_value(std::move(value));
61 std::unique_ptr<std::vector<Integer>> value,
65 set_value(std::move(value));
79 set_value(std::move(value));
86 set_value(std::move(value));
100 set_value(std::move(value));
107 set_value(std::move(value));
118 std::unique_ptr<std::vector<unsigned char>> value,
122 set_file(std::move(value));
136 overwrite_circular_buffer(std::move(buffer));
139 : logger_(rhs.logger_),
142 quality(rhs.quality),
143 write_quality(rhs.write_quality),
145 shared_(rhs.is_ref_counted() ? SHARED : OWNED)
163 std::shared_ptr<std::vector<unsigned char>>(rhs.
file_value_);
165 new (&
buf_) std::shared_ptr<CircBuf>(rhs.
buf_);
170 : logger_(std::move(rhs.logger_)),
173 quality(rhs.quality),
174 write_quality(rhs.write_quality),
178 if (rhs.type_ == EMPTY)
181 if (rhs.type_ == INTEGER)
182 int_value_ = rhs.int_value_;
183 else if (rhs.type_ == INTEGER_ARRAY)
185 std::shared_ptr<std::vector<Integer>>(std::move(rhs.int_array_));
186 else if (rhs.type_ == DOUBLE)
187 double_value_ = rhs.double_value_;
188 else if (rhs.type_ == DOUBLE_ARRAY)
190 std::shared_ptr<std::vector<double>>(std::move(rhs.double_array_));
191 else if (is_string_type(rhs.type_))
192 new (&str_value_) std::shared_ptr<std::string>(std::move(rhs.str_value_));
193 else if (is_binary_file_type(rhs.type_))
195 std::shared_ptr<std::vector<unsigned char>>(std::move(rhs.file_value_));
196 else if (rhs.type_ == BUFFER)
197 new (&buf_) std::shared_ptr<CircBuf>(std::move(rhs.buf_));
250 rhs.
has_history() ? std::move(rhs.ref_newest()) : std::move(rhs);
253 else if (rhs.has_history())
309 std::shared_ptr<std::vector<unsigned char>>(rhs.
file_value_);
311 new (&
buf_) std::shared_ptr<CircBuf>(rhs.
buf_);
322 if (rhs.type_ ==
EMPTY)
333 std::shared_ptr<std::vector<Integer>>(std::move(rhs.int_array_));
334 else if (rhs.type_ ==
DOUBLE)
338 std::shared_ptr<std::vector<double>>(std::move(rhs.double_array_));
340 new (&
str_value_) std::shared_ptr<std::string>(std::move(rhs.str_value_));
343 std::shared_ptr<std::vector<unsigned char>>(std::move(rhs.file_value_));
344 else if (rhs.type_ ==
BUFFER)
345 new (&
buf_) std::shared_ptr<CircBuf>(std::move(rhs.buf_));
367 overwrite(std::move(rhs));
375 return !(*
this == rhs);
601 return ret_value *= rhs;
613 return ret_value /= rhs;
625 return ret_value %= rhs;
637 return ret_value += rhs;
671 return ret_value -= rhs;
796 buf_->emplace_back();
806 int64_t buffer_size(
sizeof(
type_) +
sizeof(uint32_t) +
sizeof(
toi_) + 0);
810 buffer_size +=
sizeof(
Integer);
814 buffer_size +=
sizeof(double);
844 int64_t buffer_size(
sizeof(uint32_t) * 1);
845 buffer_size += (key.size() + 1);
939 for (KnowledgeRecords::const_iterator i = records.begin(); i != records.end();
942 max = std::max<uint32_t>(i->second->quality, max);
952 for (KnowledgeMap::const_iterator i = records.begin(); i != records.end();
955 max = std::max<uint32_t>(i->second.quality, max);
968 if (type_ & ALL_CLEARABLES)
970 if (type_ == INTEGER_ARRAY)
972 else if (type_ == DOUBLE_ARRAY)
974 else if (is_string_type(type_))
976 else if (is_binary_file_type(type_))
978 else if (type_ == BUFFER)
992 const char* buffer, int64_t& buffer_remaining)
996 uint32_t buff_value_size(0);
1001 if (buffer_remaining >= (int64_t)
sizeof(
type))
1003 memcpy(&
type, buffer,
sizeof(
type));
1005 buffer +=
sizeof(
type);
1007 buffer_remaining -=
sizeof(
type);
1010 if (buffer_remaining >= (int64_t)
sizeof(
size))
1012 memcpy(&
size, buffer,
sizeof(
size));
1018 buff_value_size =
size *
sizeof(
double);
1020 buff_value_size =
size;
1022 buffer +=
sizeof(buff_value_size);
1026 buffer_remaining = -1;
1029 buffer_remaining -=
sizeof(buff_value_size);
1032 if (buffer_remaining >= (int64_t)
sizeof(
toi_))
1034 memcpy(&
toi_, buffer,
sizeof(
toi_));
1036 buffer +=
sizeof(
toi_);
1038 buffer_remaining -=
sizeof(
toi_);
1047 if (buffer_remaining >= int64_t(buff_value_size))
1051 if (buff_value_size >= 1)
1064 memcpy(&tmp, buffer,
sizeof(tmp));
1070 std::vector<Integer> tmp;
1073 for (uint32_t i = 0; i <
size; ++i)
1076 memcpy(&cur, buffer + i *
sizeof(cur),
sizeof(cur));
1086 memcpy(&tmp, buffer,
sizeof(tmp));
1092 std::vector<double> tmp;
1095 for (uint32_t i = 0; i <
size; ++i)
1098 memcpy(&cur, buffer + i *
sizeof(cur),
sizeof(cur));
1107 const unsigned char* b = (
const unsigned char*)buffer;
1112 buffer_remaining = -1;
1116 buffer += buff_value_size;
1117 buffer_remaining -=
sizeof(char) * buff_value_size;
1126 const char* buffer,
std::string& key, int64_t& buffer_remaining)
1130 uint32_t key_size(0);
1133 if (buffer_remaining >= (int64_t)
sizeof(key_size))
1135 memcpy(&key_size, buffer,
sizeof(key_size));
1137 buffer +=
sizeof(key_size);
1139 buffer_remaining -=
sizeof(key_size);
1142 if (buffer_remaining >= int64_t(
sizeof(
char) * int64_t(key_size)))
1147 key.assign(buffer, key_size - 1);
1154 buffer +=
sizeof(char) * key_size;
1156 buffer_remaining -=
sizeof(char) * int64_t(key_size);
1159 buffer =
read(buffer, buffer_remaining);
1165 const char* buffer, uint32_t& key_id, int64_t& buffer_remaining)
1170 if (buffer_remaining >= (int64_t)
sizeof(key_id))
1172 memcpy(&key_id, buffer,
sizeof(key_id));
1174 buffer +=
sizeof(key_id);
1175 buffer_remaining -=
sizeof(key_id);
1178 buffer =
read(buffer, buffer_remaining);
1212 emplace_shared_val<std::string, STRING, &KnowledgeRecord::str_value_>(
1213 std::move(new_value));
1247 emplace_shared_val<std::string, XML, &KnowledgeRecord::str_value_>(
1248 std::move(new_value));
1275 emplace_shared_val<std::string, TEXT_FILE, &KnowledgeRecord::str_value_>(
1276 std::move(new_value));
1281 const unsigned char* new_value,
size_t size)
1294 const std::vector<unsigned char>& new_value)
1301 std::unique_ptr<std::vector<unsigned char>> new_value)
1303 emplace_shared_vec<unsigned char, IMAGE_JPEG, &KnowledgeRecord::file_value_>(
1304 std::move(new_value));
1309 const unsigned char* new_value,
size_t size)
1322 const std::vector<unsigned char>& new_value)
1329 std::unique_ptr<std::vector<unsigned char>> new_value)
1447 std::unique_ptr<std::vector<Integer>> new_value)
1449 emplace_shared_vec<Integer, INTEGER_ARRAY, &KnowledgeRecord::int_array_>(
1450 std::move(new_value));
1473 std::unique_ptr<std::vector<double>> new_value)
1475 emplace_shared_vec<double, DOUBLE_ARRAY, &KnowledgeRecord::double_array_>(
1476 std::move(new_value));
1484 template<typename T, utility::enable_if_<utility::is_int_numeric<T>(),
int>>
1522 template<
typename T,
1523 typename std::enable_if<std::is_floating_point<T>::value,
void*>
::type>
1576 inline std::shared_ptr<const std::vector<KnowledgeRecord::Integer>>
1591 inline std::shared_ptr<const std::vector<double>>
1606 inline std::shared_ptr<const std::vector<unsigned char>>
1621 inline std::shared_ptr<KnowledgeRecord::CircBuf>
1632 inline KnowledgeRecord::operator bool(
void)
const
1638 char* buffer, int64_t& buffer_remaining)
const
1646 char* size_location = 0;
1647 uint32_t size_intermediate = 0;
1648 uint32_t uint32_temp;
1655 if (buffer_remaining >= encoded_size)
1658 "KnowledgeRecord::write:"
1659 " encoding %" PRId64
" byte message\n",
1663 if (buffer_remaining >= (int64_t)
sizeof(
type_))
1666 memcpy(buffer, &tmp,
sizeof(tmp));
1667 buffer +=
sizeof(tmp);
1669 buffer_remaining -=
sizeof(
type_);
1672 if (buffer_remaining >= (int64_t)
sizeof(
size))
1676 size_location = buffer;
1677 size_intermediate =
size;
1682 buffer +=
sizeof(
size);
1684 buffer_remaining -=
sizeof(
size);
1687 if (buffer_remaining >= (int64_t)
sizeof(
toi_))
1690 memcpy(buffer, &tmp,
sizeof(tmp));
1691 buffer +=
sizeof(tmp);
1693 buffer_remaining -=
sizeof(
toi_);
1699 if (buffer_remaining >= int64_t(
size))
1706 if (buffer_remaining >= int64_t(
sizeof(
Integer)))
1709 memcpy(buffer, &integer_temp,
sizeof(integer_temp));
1711 size_intermediate =
sizeof(
Integer);
1716 if (buffer_remaining >= int64_t(
size *
sizeof(
Integer)))
1719 const Integer* ptr_temp = &(*int_array_)[0];
1722 for (uint32_t i = 0; i <
size; ++i, ++ptr_temp, ++target_buffer)
1725 memcpy(target_buffer, &integer_temp,
sizeof(
Integer));
1733 if (buffer_remaining >= int64_t(
sizeof(
double)))
1736 memcpy(buffer, &double_temp,
sizeof(
double));
1738 size_intermediate =
sizeof(double);
1743 if (buffer_remaining >= int64_t(
size *
sizeof(
double)))
1746 const double* ptr_temp = &(*double_array_)[0];
1747 double* target_buffer = (
double*)buffer;
1749 for (uint32_t i = 0; i <
size; ++i, ++ptr_temp, ++target_buffer)
1752 memcpy(target_buffer, &double_temp,
sizeof(double_temp));
1755 size_intermediate =
size *
sizeof(double);
1772 if (buffer_remaining >=
size)
1780 buffer_remaining -= size_intermediate;
1781 buffer += size_intermediate;
1784 memcpy(size_location, &uint32_temp,
sizeof(uint32_temp));
1789 std::stringstream local_buffer;
1790 local_buffer <<
"KnowledgeRecord::write: ";
1791 local_buffer << encoded_size <<
" byte encoding cannot fit in ";
1792 local_buffer << buffer_remaining <<
" byte buffer\n";
1803 char* buffer,
const std::string& key, int64_t& buffer_remaining)
const
1808 uint32_t key_size = uint32_t(key.size() + 1);
1809 uint32_t uint32_temp;
1813 if (buffer_remaining >= encoded_size)
1816 "KnowledgeRecord::write:"
1817 " encoding %" PRId64
" byte message\n",
1821 if (buffer_remaining >= (int64_t)
sizeof(key_size))
1824 memcpy(buffer, &uint32_temp,
sizeof(uint32_temp));
1825 buffer +=
sizeof(key_size);
1827 buffer_remaining -=
sizeof(key_size);
1830 if (buffer_remaining >= (int64_t)
sizeof(char) * key_size)
1835 buffer +=
sizeof(char) * key_size;
1837 buffer_remaining -=
sizeof(char) * key_size;
1840 buffer =
write(buffer, buffer_remaining);
1844 std::stringstream local_buffer;
1845 local_buffer <<
"KnowledgeRecord::write: ";
1846 local_buffer << encoded_size <<
" byte encoding cannot fit in ";
1847 local_buffer << buffer_remaining <<
" byte buffer\n";
1857 char* buffer, uint32_t key_id, int64_t& buffer_remaining)
const
1861 uint32_t uint32_temp;
1865 if (buffer_remaining >= encoded_size)
1868 "KnowledgeRecord::write:"
1869 " encoding %" PRId64
" byte message\n",
1873 if (buffer_remaining >= (int64_t)
sizeof(key_id))
1876 memcpy(buffer, &uint32_temp,
sizeof(uint32_temp));
1877 buffer +=
sizeof(key_id);
1879 buffer_remaining -=
sizeof(key_id);
1882 buffer =
write(buffer, buffer_remaining);
1886 std::stringstream local_buffer;
1887 local_buffer <<
"KnowledgeRecord::write: ";
1888 local_buffer << encoded_size <<
" byte encoding cannot fit in ";
1889 local_buffer << buffer_remaining <<
" byte buffer\n";
#define madara_logger_ptr_log(loggering, level,...)
Fast version of the madara::logger::log method for Logger pointers.
madara::knowledge::KnowledgeRecord KnowledgeRecord
An exception for general memory errors like out-of-memory.
This class encapsulates an entry in a KnowledgeBase.
bool has_history() const
Return true if this record has a circular buffer history.
std::string to_string(const std::string &delimiter=", ") const
converts the value to a string.
std::shared_ptr< std::string > str_value_
KnowledgeRecord operator/(const KnowledgeRecord &rhs) const
Divides operator.
void set_xml(const char *new_value, size_t size)
sets the value to an xml string
bool set_type(uint32_t type)
Modify the type, but only if it's compatible with current type without changing any actual data store...
KnowledgeRecord operator%(const KnowledgeRecord &rhs) const
Modulus operator.
void emplace_file(Args &&... args)
Construct a file (vector of unsigned char) within this KnowledgeRecord.
uint32_t type(void) const
returns the type of the value
KnowledgeRecord & operator*=(const KnowledgeRecord &rhs)
In-place multiplication operator.
void set_full(const KnowledgeRecord &new_value)
Sets the value and meta data from another KnowledgeRecord.
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< std::vector< unsigned char > > file_value_
char * write(char *buffer, int64_t &buffer_remaining) const
Writes a KnowledgeRecord instance to a buffer and updates the amount of buffer room remaining.
KnowledgeRecord & operator/=(const KnowledgeRecord &rhs)
In-place division operator.
KnowledgeRecord & ref_newest()
void emplace_doubles(Args &&... args)
Construct a vector of doubles within this KnowledgeRecord.
int64_t get_encoded_size(void) const
Returns the encoded size of the record.
bool is_double_type(void) const
returns if the record is a double type (DOUBLE, DOUBLE_ARRAY)
std::shared_ptr< std::vector< double > > double_array_
void set_index(size_t index, T value)
sets the value at the index to the specified value.
bool is_image_type(void) const
returns true if the knowledge record has an image type
uint64_t clock
last modification lamport clock time
~KnowledgeRecord() noexcept
void set_value(const KnowledgeRecord &new_value)
Sets the value from another KnowledgeRecord, does not copy toi, clock, and write_quality.
double to_double(void) const
converts the value to a float/double.
uint32_t write_quality
write priority for any local updates
bool is_true(void) const
Checks to see if the record is true.
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 clear_union(void) noexcept
bool shared_
is this knowledge record's shared_ptr, if any, exposed to outside holders?
void overwrite(const KnowledgeRecord &new_value)
Clears everything including history, but excluding metadata (e.g., toi, clock) and copies value from ...
KnowledgeRecord & operator--(void)
Predecrement operator.
std::shared_ptr< const std::vector< double > > share_doubles() const
KnowledgeRecord operator-(void) const
Negate.
bool is_ref_counted(void) const
returns if the record has a reference-counted type
bool operator!(void) const
Logical not.
KnowledgeRecord() noexcept
bool operator!=(const KnowledgeRecord &rhs) const
Unequal to.
int status(void) const
returns the status of the record.
KnowledgeRecord deep_copy() const
Creates a deep copy of this knowledge record.
std::shared_ptr< CircBuf > share_circular_buffer() const
Get a shared_ptr to the history buffer inside this record.
void set_jpeg(const unsigned char *new_value, size_t size)
sets the value to a jpeg
uint32_t size(void) const
returns the size of the value
std::shared_ptr< const std::vector< unsigned char > > share_binary() const
std::shared_ptr< std::vector< Integer > > int_array_
bool exists(void) const
Checks if record exists (i.e., is not uncreated)
void set_text(const char *new_value, size_t size)
sets the value to a plaintext string
bool is_integer_type(void) const
returns if the record is a integer type (INTEGER, INTEGER_ARRAY)
KnowledgeRecord * clone(void) const
clones the record.
bool is_binary_file_type(void) const
returns true if the knowledge record has a binary file type
uint32_t type_
type of variable (INTEGER, DOUBLE, STRING, FILE, IMAGE)
Integer to_integer(void) const
converts the value to an integer.
KnowledgeRecord & operator%=(const KnowledgeRecord &rhs)
In-place modulus operator.
bool is_string_type(void) const
returns true if the record is a string type (STRING, XML, TEXT_FILE)
KnowledgeRecord & operator-=(const KnowledgeRecord &rhs)
In-place subtraction operator.
void set_modified(void)
sets the status to modified
std::shared_ptr< const std::vector< Integer > > share_integers() const
KnowledgeRecord get_newest() const
Return the newest stored history entry of this record.
void emplace_string(Args &&... args)
Construct a string within this KnowledgeRecord.
KnowledgeRecord operator+(const KnowledgeRecord &rhs) const
Plus operator.
KnowledgeRecord & operator=(const KnowledgeRecord &rhs)
Assignment.
std::shared_ptr< const std::vector< T > > emplace_shared_vec(Args &&... args)
KnowledgeRecord operator*(const KnowledgeRecord &rhs) const
Times operator.
void clear_value(void) noexcept
clears any dynamic values.
void emplace_integers(Args &&... args)
Construct a vector of integers within this KnowledgeRecord.
std::shared_ptr< CircBuf > buf_
KnowledgeRecord & operator++(void)
Preincrement operator.
logger::Logger * logger_
the logger used for any internal debugging information
uint32_t quality
priority of the update
KnowledgeRecord & operator+=(const KnowledgeRecord &rhs)
In-place addition operator.
void reset_value(void) noexcept
resets the variable to an integer
bool is_file_type(void) const
returns true if the knowledge record has a file type
bool is_array_type(void) const
returns if the record is an array type (DOUBLE_ARRAY, INTEGER_ARRAY)
KnowledgeRecord & emplace_hist(Args &&... args)
int64_t get_encoded_size(const std::string &key) const
Returns the encoded size of the record.
std::shared_ptr< const std::string > share_string() const
void overwrite_circular_buffer(Args &&... args)
Construct a CircularBuffer within this KnowledgeRecord directly.
void set_file(const unsigned char *new_value, size_t size)
sets the value to an unknown file type
bool is_false(void) const
Checks to see if the record is false.
const char * read(const char *buffer, int64_t &buffer_remaining)
Reads a KnowledgeRecord instance from a buffer and updates the amount of buffer room remaining.
void unshare(void)
If this record holds a shared_ptr, make a copy of the underlying value so it has an exclusive copy.
uint64_t toi_
last modification system clock time
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
uint32_t max_quality(const KnowledgeRecords &records)
Returns the maximum quality within the records.
std::ostream & operator<<(std::ostream &stream, const KnowledgeRecord &rhs)
output stream buffering
::std::map< std::string, KnowledgeRecord > KnowledgeMap
Provides knowledge logging services to files and terminals.
uint64_t endian_swap(uint64_t value)
Converts a host format uint64_t into big endian.
MADARA_EXPORT void strncpy_safe(char *dst, const char *src, size_t dst_size)
Performs a strncpy in a way that will compile without warnings.
Copyright(c) 2020 Galois.