3#ifndef DATASTORM_DATASTORM_H
4#define DATASTORM_DATASTORM_H
7#include "DataStorm/SampleEvent.h"
17# pragma clang diagnostic push
18# pragma clang diagnostic ignored "-Wshadow-field-in-constructor"
19#elif defined(__GNUC__)
20# pragma GCC diagnostic push
21# pragma GCC diagnostic ignored "-Wshadow"
30 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
class Sample
49 [[nodiscard]] const Key&
getKey() const noexcept;
55 [[nodiscard]] const Value&
getValue() const noexcept;
65 [[nodiscard]] std::chrono::time_point<std::chrono::system_clock>
getTimeStamp() const noexcept;
72 [[nodiscard]] const std::
string&
getOrigin() const noexcept;
77 [[nodiscard]] const std::
string&
getSession() const noexcept;
80 Sample(const std::shared_ptr<DataStormI::Sample>&) noexcept;
83 std::shared_ptr<DataStormI::SampleT<Key, Value, UpdateTag>> _impl;
90 inline std::ostream& operator<<(std::ostream& os, const
SampleEventSeq& types)
100 template<
typename K,
typename V,
typename U>
109 template<
typename Key,
typename Value,
typename UpdateTag>
class Reader
133 [[nodiscard]]
bool hasWriters() const noexcept;
162 [[nodiscard]]
bool hasUnread() const noexcept;
177 std::function<
void(std::vector<Key>)> init,
187 std::function<
void(std::vector<std::
string>)> init,
188 std::function<
void(
CallbackReason, std::
string)> update) noexcept;
198 std::function<
void(std::vector<
Sample<Key, Value, UpdateTag>>)> init,
199 std::function<
void(
Sample<Key, Value, UpdateTag>)> queue) noexcept;
203 Reader(const std::shared_ptr<DataStormI::DataReader>& impl) noexcept : _impl(impl) {}
206 std::shared_ptr<DataStormI::DataReader> _impl;
211 template<
typename Key,
typename Value,
typename UpdateTag>
class Writer
235 [[nodiscard]]
bool hasReaders() const noexcept;
261 [[nodiscard]] std::vector<
Sample<Key, Value, UpdateTag>>
getAll();
271 std::function<
void(std::vector<Key>)> init,
281 std::function<
void(std::vector<std::
string>)> init,
282 std::function<
void(
CallbackReason, std::
string)> update) noexcept;
286 Writer(const std::shared_ptr<DataStormI::DataWriter>& impl) noexcept : _impl(impl) {}
289 std::shared_ptr<DataStormI::DataWriter> _impl;
296 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
class Topic
320 Topic(
const Node& node, std::string name)
noexcept;
325 : _name(std::move(topic._name)),
326 _topicFactory(std::move(topic._topicFactory)),
327 _keyFactory(std::move(topic._keyFactory)),
328 _tagFactory(std::move(topic._tagFactory)),
329 _keyFilterFactories(std::move(topic._keyFilterFactories)),
330 _sampleFilterFactories(std::move(topic._sampleFilterFactories)),
331 _reader(std::move(topic._reader)),
332 _writer(std::move(topic._writer)),
333 _updaters(std::move(topic._updaters))
348 [[nodiscard]]
bool hasWriters() const noexcept;
353 void waitForWriters(
unsigned int count = 1) const;
357 void waitForNoWriters() const;
361 void setWriterDefaultConfig(const
WriterConfig& config) noexcept;
365 [[nodiscard]]
bool hasReaders() const noexcept;
370 void waitForReaders(
unsigned int count = 1) const;
374 void waitForNoReaders() const;
378 void setReaderDefaultConfig(const
ReaderConfig& config) noexcept;
387 template<typename UpdateValue>
388 void setUpdater(const UpdateTag& tag, std::function<
void(Value&, UpdateValue)> updater) noexcept;
397 template<typename Criteria>
400 std::function<std::function<
bool(const Key&)>(const Criteria&)> factory) noexcept;
415 template<typename Criteria>
416 void setSampleFilter(
418 std::function<std::function<
bool(const SampleType&)>(const Criteria&)> factory) noexcept;
421 [[nodiscard]] std::shared_ptr<DataStormI::TopicReader> getReader() const;
422 [[nodiscard]] std::shared_ptr<DataStormI::TopicWriter> getWriter() const;
423 [[nodiscard]]
Ice::CommunicatorPtr getCommunicator() const noexcept;
426 template<typename, typename, typename> friend class
MultiKeyWriter;
428 template<typename, typename, typename> friend class
MultiKeyReader;
433 std::shared_ptr<DataStormI::TopicFactory> _topicFactory;
434 std::shared_ptr<DataStormI::KeyFactoryT<Key>> _keyFactory;
435 std::shared_ptr<DataStormI::TagFactoryT<UpdateTag>> _tagFactory;
436 std::shared_ptr<DataStormI::FilterManagerT<DataStormI::KeyT<Key>>> _keyFilterFactories;
437 std::shared_ptr<DataStormI::FilterManagerT<DataStormI::SampleT<Key, Value, UpdateTag>>> _sampleFilterFactories;
439 mutable std::mutex _mutex;
440 mutable std::shared_ptr<DataStormI::TopicReader> _reader;
441 mutable std::shared_ptr<DataStormI::TopicWriter> _writer;
442 mutable std::map<std::shared_ptr<DataStormI::Tag>, DataStormI::
Topic::Updater> _updaters;
452 template<
typename TT>
467 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
480 std::string name = std::string(),
491 template<
typename SampleFilterCriteria>
496 std::string name = std::string(),
517 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
530 const std::vector<Key>& keys,
531 std::string name = std::string(),
543 template<
typename SampleFilterCriteria>
546 const std::vector<Key>& keys,
548 std::string name = std::string(),
567 template<
typename K,
typename V,
typename UT>
571 std::string name = std::string(),
584 template<
typename SFC,
typename K,
typename V,
typename UT>
589 std::string name = std::string(),
602 template<
typename K,
typename V,
typename UT>
606 std::string name = std::string(),
620 template<
typename SFC,
typename K,
typename V,
typename UT>
625 std::string name = std::string(),
637 template<
typename K,
typename V,
typename UT>
640 std::string name = std::string(),
653 template<
typename SFC,
typename K,
typename V,
typename UT>
657 std::string name = std::string(),
670 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
682 template<
typename KeyFilterCriteria>
686 std::string name = std::string(),
698 template<
typename KeyFilterCriteria,
typename SampleFilterCriteria>
703 std::string name = std::string(),
722 template<
typename KFC,
typename K,
typename V,
typename UT>
726 std::string name = std::string(),
739 template<
typename KFC,
typename SFC,
typename K,
typename V,
typename UT>
744 std::string name = std::string(),
752 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
765 std::string name = std::string(),
779 void add(
const Value& value);
783 void update(
const Value& value);
797 template<
typename UpdateValue>
798 [[nodiscard]] std::function<void(
const UpdateValue&)>
partialUpdate(
const UpdateTag& tag);
806 const std::shared_ptr<DataStormI::TagFactoryT<UpdateTag>> _tagFactory;
818 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
831 const std::vector<Key>& keys,
832 std::string name = std::string(),
847 void add(
const Key& key,
const Value& value);
852 void update(
const Key& key,
const Value& value);
866 template<
typename UpdateValue>
867 [[nodiscard]] std::function<void(
const Key&,
const UpdateValue&)>
partialUpdate(
const UpdateTag& tag);
873 void remove(
const Key& key)
noexcept;
876 const std::shared_ptr<DataStormI::KeyFactoryT<Key>> _keyFactory;
877 const std::shared_ptr<DataStormI::TagFactoryT<UpdateTag>> _tagFactory;
886 template<
typename K,
typename V,
typename UT>
890 std::string name = std::string(),
902 template<
typename K,
typename V,
typename UT>
906 std::string name = std::string(),
917 template<
typename K,
typename V,
typename UT>
920 std::string name = std::string(),
933 template<
typename Key,
typename Value,
typename UpdateTag>
939 template<
typename Key,
typename Value,
typename UpdateTag>
942 return _impl->getKey();
945 template<
typename Key,
typename Value,
typename UpdateTag>
948 return _impl->getValue();
951 template<
typename Key,
typename Value,
typename UpdateTag>
954 return _impl->getTag();
957 template<
typename Key,
typename Value,
typename UpdateTag>
960 return _impl->timestamp;
963 template<
typename Key,
typename Value,
typename UpdateTag>
966 return _impl->origin;
969 template<
typename Key,
typename Value,
typename UpdateTag>
972 return _impl->session;
975 template<
typename Key,
typename Value,
typename UpdateTag>
976 Sample<Key, Value, UpdateTag>::Sample(
const std::shared_ptr<DataStormI::Sample>& impl) noexcept
977 : _impl(std::static_pointer_cast<DataStormI::SampleT<Key, Value, UpdateTag>>(impl))
984 template<
typename Key,
typename Value,
typename UpdateTag>
986 : _impl(std::move(reader._impl))
998 template<
typename Key,
typename Value,
typename UpdateTag>
1005 _impl = std::move(reader._impl);
1009 template<
typename Key,
typename Value,
typename UpdateTag>
1012 return _impl->hasWriters();
1015 template<
typename Key,
typename Value,
typename UpdateTag>
1018 _impl->waitForWriters(
static_cast<int>(count));
1021 template<
typename Key,
typename Value,
typename UpdateTag>
1024 _impl->waitForWriters(-1);
1027 template<
typename Key,
typename Value,
typename UpdateTag>
1030 return _impl->getConnectedElements();
1033 template<
typename Key,
typename Value,
typename UpdateTag>
1036 std::vector<Key> keys;
1037 auto connectedKeys = _impl->getConnectedKeys();
1038 keys.reserve(connectedKeys.size());
1039 for (
const auto& k : connectedKeys)
1041 keys.push_back(std::static_pointer_cast<DataStormI::KeyT<Key>>(k)->get());
1046 template<
typename Key,
typename Value,
typename UpdateTag>
1049 auto unread = _impl->getAllUnread();
1050 std::vector<Sample<Key, Value, UpdateTag>> samples;
1051 samples.reserve(unread.size());
1052 for (
const auto& sample : unread)
1054 samples.push_back(sample);
1059 template<
typename Key,
typename Value,
typename UpdateTag>
1062 _impl->waitForUnread(count);
1065 template<
typename Key,
typename Value,
typename UpdateTag>
1068 return _impl->hasUnread();
1071 template<
typename Key,
typename Value,
typename UpdateTag>
1077 template<
typename Key,
typename Value,
typename UpdateTag>
1079 std::function<
void(std::vector<Key>)> init,
1082 _impl->onConnectedKeys(
1084 [init = std::move(init)](
const std::vector<std::shared_ptr<DataStormI::Key>>& connectedKeys)
1086 std::vector<Key> keys;
1087 keys.reserve(connectedKeys.size());
1088 for(
const auto& k : connectedKeys)
1090 keys.push_back(std::static_pointer_cast<DataStormI::KeyT<Key>>(k)->get());
1092 init(std::move(keys));
1093 } : std::function<void(std::vector<std::shared_ptr<DataStormI::Key>>)>{},
1095 [update = std::move(update)](
CallbackReason action,
const std::shared_ptr<DataStormI::Key>& key)
1097 update(action, std::static_pointer_cast<DataStormI::KeyT<Key>>(key)->get());
1098 } : std::function<void(
CallbackReason, std::shared_ptr<DataStormI::Key>)>{});
1101 template<
typename Key,
typename Value,
typename UpdateTag>
1103 std::function<
void(std::vector<std::string>)> init,
1104 std::function<
void(
CallbackReason, std::string)> update)
noexcept
1106 _impl->onConnectedElements(std::move(init), std::move(update));
1109 template<
typename Key,
typename Value,
typename UpdateTag>
1114 auto communicator = _impl->getCommunicator();
1117 [communicator, init = std::move(init)](
const std::vector<std::shared_ptr<DataStormI::Sample>>& samplesI)
1119 std::vector<Sample<Key, Value, UpdateTag>> samples;
1120 samples.reserve(samplesI.size());
1121 for(
const auto& s : samplesI)
1123 samples.emplace_back(s);
1125 init(std::move(samples));
1126 } : std::function<void(
const std::vector<std::shared_ptr<DataStormI::Sample>>&)>(),
1128 [communicator, update = std::move(update)](
const std::shared_ptr<DataStormI::Sample>& sampleI)
1131 } : std::function<void(
const std::shared_ptr<DataStormI::Sample>&)>{});
1134 template<
typename Key,
typename Value,
typename UpdateTag>
1140 :
Reader<Key, Value, UpdateTag>(
1141 topic.getReader()->create({topic._keyFactory->create(key)}, std::move(name), config))
1145 template<
typename Key,
typename Value,
typename UpdateTag>
1146 template<
typename SampleFilterCriteria>
1153 :
Reader<Key, Value, UpdateTag>(topic.getReader()->create(
1154 {topic._keyFactory->create(key)},
1158 DataStormI::EncoderT<SampleFilterCriteria>::encode(topic.getCommunicator(), sampleFilter.
criteria)))
1162 template<
typename Key,
typename Value,
typename UpdateTag>
1168 template<
typename Key,
typename Value,
typename UpdateTag>
1176 template<
typename Key,
typename Value,
typename UpdateTag>
1179 const std::vector<Key>& keys,
1182 :
Reader<Key, Value, UpdateTag>(
1183 topic.getReader()->create(topic._keyFactory->create(keys), std::move(name), config))
1187 template<
typename Key,
typename Value,
typename UpdateTag>
1188 template<
typename SampleFilterCriteria>
1191 const std::vector<Key>& keys,
1195 :
Reader<Key, Value, UpdateTag>(topic.getReader()->create(
1196 topic._keyFactory->create(keys),
1200 DataStormI::EncoderT<SampleFilterCriteria>::encode(topic.getCommunicator(), sampleFilter.criteria)))
1204 template<
typename Key,
typename Value,
typename UpdateTag>
1210 template<
typename Key,
typename Value,
typename UpdateTag>
1218 template<
typename Key,
typename Value,
typename UpdateTag>
1219 template<
typename KeyFilterCriteria>
1225 :
Reader<Key, Value, UpdateTag>(topic.getReader()->createFiltered(
1226 topic._keyFilterFactories->create(filter.name, filter.criteria),
1232 template<
typename Key,
typename Value,
typename UpdateTag>
1233 template<
typename KeyFilterCriteria,
typename SampleFilterCriteria>
1240 :
Reader<Key, Value, UpdateTag>(topic.getReader()->createFiltered(
1241 topic._keyFilterFactories->create(keyFilter.name, keyFilter.criteria),
1245 DataStormI::EncoderT<SampleFilterCriteria>::encode(topic.getCommunicator(), sampleFilter.criteria)))
1249 template<
typename Key,
typename Value,
typename UpdateTag>
1256 template<
typename Key,
typename Value,
typename UpdateTag>
1267 template<
typename Key,
typename Value,
typename UpdateTag>
1280 template<
typename Key,
typename Value,
typename UpdateTag>
1287 _impl = std::move(writer._impl);
1291 template<
typename Key,
typename Value,
typename UpdateTag>
1297 template<
typename Key,
typename Value,
typename UpdateTag>
1300 return _impl->waitForReaders(
static_cast<int>(count));
1303 template<
typename Key,
typename Value,
typename UpdateTag>
1306 return _impl->waitForReaders(-1);
1309 template<
typename Key,
typename Value,
typename UpdateTag>
1312 return _impl->getConnectedElements();
1315 template<
typename Key,
typename Value,
typename UpdateTag>
1318 std::vector<Key> keys;
1319 auto connectedKeys = _impl->getConnectedKeys();
1320 keys.reserve(connectedKeys.size());
1321 for (
const auto& k : connectedKeys)
1323 keys.push_back(std::static_pointer_cast<DataStormI::KeyT<Key>>(k)->get());
1328 template<
typename Key,
typename Value,
typename UpdateTag>
1331 auto sample = _impl->getLast();
1334 throw std::logic_error(
"no sample");
1339 template<
typename Key,
typename Value,
typename UpdateTag>
1342 auto all = _impl->getAll();
1343 std::vector<Sample<Key, Value, UpdateTag>> samples;
1344 samples.reserve(all.size());
1345 for (
const auto& sample : all)
1347 samples.push_back(sample);
1352 template<
typename Key,
typename Value,
typename UpdateTag>
1354 std::function<
void(std::vector<Key>)> init,
1357 _impl->onConnectedKeys(
1359 [init = std::move(init)](
const std::vector<std::shared_ptr<DataStormI::Key>>& connectedKeys)
1361 std::vector<Key> keys;
1362 keys.reserve(connectedKeys.size());
1363 for(
const auto& k : connectedKeys)
1365 keys.push_back(std::static_pointer_cast<DataStormI::KeyT<Key>>(k)->get());
1367 init(std::move(keys));
1368 } : std::function<void(std::vector<std::shared_ptr<DataStormI::Key>>)>{},
1370 [update = std::move(update)](
CallbackReason action,
const std::shared_ptr<DataStormI::Key>& key)
1372 update(action, std::static_pointer_cast<DataStormI::KeyT<Key>>(key)->get());
1373 } : std::function<void(
CallbackReason, std::shared_ptr<DataStormI::Key>)>{});
1376 template<
typename Key,
typename Value,
typename UpdateTag>
1378 std::function<
void(std::vector<std::string>)> init,
1379 std::function<
void(
CallbackReason, std::string)> update)
noexcept
1381 _impl->onConnectedElements(std::move(init), std::move(update));
1384 template<
typename Key,
typename Value,
typename UpdateTag>
1390 :
Writer<Key, Value, UpdateTag>(
1391 topic.getWriter()->create({topic._keyFactory->create(key)}, std::move(name), config)),
1392 _tagFactory(topic._tagFactory)
1396 template<
typename Key,
typename Value,
typename UpdateTag>
1399 _tagFactory(std::move(writer._tagFactory))
1403 template<
typename Key,
typename Value,
typename UpdateTag>
1411 template<
typename Key,
typename Value,
typename UpdateTag>
1414 Writer<Key, Value, UpdateTag>::_impl->publish(
1416 std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(
SampleEvent::Add, value));
1419 template<
typename Key,
typename Value,
typename UpdateTag>
1422 Writer<Key, Value, UpdateTag>::_impl->publish(
1424 std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(
SampleEvent::Update, value));
1427 template<
typename Key,
typename Value,
typename UpdateTag>
1428 template<
typename UpdateValue>
1431 auto impl = Writer<Key, Value, UpdateTag>::_impl;
1432 auto updateTag = _tagFactory->create(tag);
1433 return [impl, updateTag](
const UpdateValue& value)
1435 auto encoded = DataStormI::EncoderT<UpdateValue>::encode(impl->getCommunicator(), value);
1436 impl->publish(
nullptr, std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(encoded, updateTag));
1440 template<
typename Key,
typename Value,
typename UpdateTag>
1443 Writer<Key, Value, UpdateTag>::_impl->publish(
1448 template<
typename Key,
typename Value,
typename UpdateTag>
1451 const std::vector<Key>& keys,
1454 :
Writer<Key, Value, UpdateTag>(
1455 topic.getWriter()->create(topic._keyFactory->create(keys), std::move(name), config)),
1456 _keyFactory(topic._keyFactory),
1457 _tagFactory(topic._tagFactory)
1461 template<
typename Key,
typename Value,
typename UpdateTag>
1464 _keyFactory(std::move(writer._keyFactory)),
1465 _tagFactory(std::move(writer._tagFactory))
1469 template<
typename Key,
typename Value,
typename UpdateTag>
1477 template<
typename Key,
typename Value,
typename UpdateTag>
1480 Writer<Key, Value, UpdateTag>::_impl->publish(
1481 _keyFactory->create(key),
1482 std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(
SampleEvent::Add, value));
1485 template<
typename Key,
typename Value,
typename UpdateTag>
1488 Writer<Key, Value, UpdateTag>::_impl->publish(
1489 _keyFactory->create(key),
1490 std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(
SampleEvent::Update, value));
1493 template<
typename Key,
typename Value,
typename UpdateTag>
1494 template<
typename UpdateValue>
1495 std::function<void(
const Key&,
const UpdateValue&)>
1498 auto impl = Writer<Key, Value, UpdateTag>::_impl;
1499 auto updateTag = _tagFactory->create(tag);
1500 auto keyFactory = _keyFactory;
1501 return [impl, updateTag, keyFactory](
const Key& key,
const UpdateValue& value)
1503 auto encoded = DataStormI::EncoderT<UpdateValue>::encode(impl->getCommunicator(), value);
1505 keyFactory->create(key),
1506 std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(encoded, updateTag));
1510 template<
typename Key,
typename Value,
typename UpdateTag>
1513 Writer<Key, Value, UpdateTag>::_impl->publish(
1514 _keyFactory->create(key),
1519 template<
typename Value> std::function<std::function<bool(const Value&)>(
const std::string&)> makeRegexFilter()
1522 return [](
const std::string& criteria)
1524 std::regex expr(criteria);
1525 return [expr = std::move(expr)](
const Value& value)
1527 std::ostringstream os;
1529 return std::regex_match(os.str(), expr);
1535 template<
typename Key,
typename Value,
typename UpdateTag>
1542 {
return std::find(criteria.begin(), criteria.end(), sample.getEvent()) != criteria.end(); };
1547 template<
typename T,
typename V,
typename Enabler =
void>
struct RegexFilter
1549 template<
typename F>
static void add(
const F&) {}
1553 template<
typename T,
typename V>
struct RegexFilter<T, V, std::enable_if_t<DataStormI::is_streamable<V>::value>>
1555 template<
typename F>
static void add(
const F& factory)
1557 factory->set(
"_regex", makeRegexFilter<T>());
1564 template<
typename Key,
typename Value,
typename UpdateTag>
1566 : _name(std::move(name)),
1567 _topicFactory(node._factory),
1568 _keyFactory(DataStormI::KeyFactoryT<Key>::createFactory()),
1569 _tagFactory(DataStormI::TagFactoryT<UpdateTag>::createFactory()),
1570 _keyFilterFactories(std::make_shared<DataStormI::FilterManagerT<DataStormI::KeyT<Key>>>()),
1571 _sampleFilterFactories(
1572 std::make_shared<DataStormI::FilterManagerT<DataStormI::SampleT<Key, Value, UpdateTag>>>())
1574 RegexFilter<Key, Key>::add(_keyFilterFactories);
1575 RegexFilter<Sample<Key, Value, UpdateTag>, Value>::add(_sampleFilterFactories);
1576 _sampleFilterFactories->set(
"_event", makeSampleEventFilter(*
this));
1581 std::lock_guard<std::mutex> lock(_mutex);
1592 template<
typename Key,
typename Value,
typename UpdateTag>
1595 std::lock_guard<std::mutex> lock(_mutex);
1604 _name = std::move(topic._name);
1605 _topicFactory = std::move(topic._topicFactory);
1606 _keyFactory = std::move(topic._keyFactory);
1607 _tagFactory = std::move(topic._tagFactory);
1608 _keyFilterFactories = std::move(topic._keyFilterFactories);
1609 _sampleFilterFactories = std::move(topic._sampleFilterFactories);
1610 _reader = std::move(topic._reader);
1611 _writer = std::move(topic._writer);
1612 _updaters = std::move(topic._updaters);
1616 template<
typename Key,
typename Value,
typename UpdateTag>
1622 template<
typename Key,
typename Value,
typename UpdateTag>
1625 getReader()->waitForWriters(
static_cast<int>(count));
1628 template<
typename Key,
typename Value,
typename UpdateTag>
1631 getReader()->waitForWriters(-1);
1634 template<
typename Key,
typename Value,
typename UpdateTag>
1637 getReader()->setDefaultConfig(config);
1640 template<
typename Key,
typename Value,
typename UpdateTag>
1643 return getWriter()->hasReaders();
1646 template<
typename Key,
typename Value,
typename UpdateTag>
1649 getWriter()->waitForReaders(
static_cast<int>(count));
1652 template<
typename Key,
typename Value,
typename UpdateTag>
1655 getWriter()->waitForReaders(-1);
1658 template<
typename Key,
typename Value,
typename UpdateTag>
1661 getWriter()->setDefaultConfig(config);
1664 template<
typename Key,
typename Value,
typename UpdateTag>
1665 template<
typename UpdateValue>
1667 const UpdateTag& tag,
1668 std::function<
void(Value&, UpdateValue)> updater)
noexcept
1670 std::lock_guard<std::mutex> lock(_mutex);
1671 auto tagI = _tagFactory->create(std::move(tag));
1674 [updater = std::move(updater)](
const std::shared_ptr<DataStormI::Sample>& previous,
1675 const std::shared_ptr<DataStormI::Sample>& next,
1683 assert(previous && previous->hasValue());
1685 if (previous && previous->hasValue())
1688 std::static_pointer_cast<DataStormI::SampleT<Key, Value, UpdateTag>>(previous)->getValue());
1690 updater(value, DataStormI::DecoderT<UpdateValue>::decode(communicator, next->getEncodedValue()));
1691 std::static_pointer_cast<DataStormI::SampleT<Key, Value, UpdateTag>>(next)->setValue(std::move(value));
1692 } : std::function<void(
const std::shared_ptr<DataStormI::Sample>&,
1693 const std::shared_ptr<DataStormI::Sample>&,
1696 if (_reader && !_writer)
1698 _reader->setUpdater(tagI, updaterImpl);
1700 else if (_writer && !_reader)
1702 _writer->setUpdater(tagI, updaterImpl);
1704 else if (_reader && _writer)
1706 _reader->setUpdater(tagI, updaterImpl);
1707 _writer->setUpdater(tagI, updaterImpl);
1711 _updaters[tagI] = updaterImpl;
1715 template<
typename Key,
typename Value,
typename UpdateTag>
1716 template<
typename Criteria>
1719 std::function<std::function<
bool(
const Key&)>(
const Criteria&)> factory)
noexcept
1721 std::lock_guard<std::mutex> lock(_mutex);
1722 _keyFilterFactories->set(std::move(name), std::move(factory));
1725 template<
typename Key,
typename Value,
typename UpdateTag>
1726 template<
typename Criteria>
1729 std::function<std::function<
bool(
const SampleType&)>(
const Criteria&)> factory)
noexcept
1731 std::lock_guard<std::mutex> lock(_mutex);
1732 _sampleFilterFactories->set(std::move(name), std::move(factory));
1735 template<
typename Key,
typename Value,
typename UpdateTag>
1736 std::shared_ptr<DataStormI::TopicReader> Topic<Key, Value, UpdateTag>::getReader()
const
1738 std::lock_guard<std::mutex> lock(_mutex);
1741 auto sampleFactory = std::make_shared<DataStormI::SampleFactoryT<Key, Value, UpdateTag>>();
1742 _reader = _topicFactory->createTopicReader(
1746 std::move(sampleFactory),
1747 _keyFilterFactories,
1748 _sampleFilterFactories);
1749 _reader->setUpdaters(_writer ? _writer->getUpdaters() : _updaters);
1755 template<
typename Key,
typename Value,
typename UpdateTag>
1756 std::shared_ptr<DataStormI::TopicWriter> Topic<Key, Value, UpdateTag>::getWriter()
const
1758 std::lock_guard<std::mutex> lock(_mutex);
1761 _writer = _topicFactory->createTopicWriter(
1766 _keyFilterFactories,
1767 _sampleFilterFactories);
1768 _writer->setUpdaters(_reader ? _reader->getUpdaters() : _updaters);
1774 template<
typename Key,
typename Value,
typename UpdateTag>
1777 return _topicFactory->getCommunicator();
1781#if defined(__clang__)
1782# pragma clang diagnostic pop
1783#elif defined(__GNUC__)
1784# pragma GCC diagnostic pop
FilteredKeyReader & operator=(FilteredKeyReader &&reader) noexcept
Move assignment operator.
FilteredKeyReader(const Topic< Key, Value, UpdateTag > &topic, const Filter< KeyFilterCriteria > &keyFilter, std::string name=std::string(), const ReaderConfig &config=ReaderConfig())
Constructs a new reader for the given key filter.
The filtered reader to read data elements whose key match a given filter.
MultiKeyReader(const Topic< Key, Value, UpdateTag > &topic, const std::vector< Key > &keys, std::string name=std::string(), const ReaderConfig &config=ReaderConfig())
Constructs a new reader for the given keys.
MultiKeyReader & operator=(MultiKeyReader &&reader) noexcept
Move assignment operator.
The key reader to read the data element associated with a given set of keys.
std::function< void(const Key &, const UpdateValue &)> partialUpdate(const UpdateTag &tag)
Gets a partial update generator function for the given partial update tag.
void add(const Key &key, const Value &value)
Adds the data element.
MultiKeyWriter(const Topic< Key, Value, UpdateTag > &topic, const std::vector< Key > &keys, std::string name=std::string(), const WriterConfig &config=WriterConfig())
Constructs a new writer for the given keys.
void remove(const Key &key) noexcept
Removes the data element.
void update(const Key &key, const Value &value)
Updates the data element.
MultiKeyWriter & operator=(MultiKeyWriter &&writer) noexcept
Move assignment operator.
The key writer to write data elements associated with a given set of keys.
The Node class allows creating topic readers and writers.
The ReaderConfig class specifies configuration options specific to readers.
std::vector< Key > getConnectedKeys() const
Gets the keys for which writers are connected to this reader.
void onConnectedWriters(std::function< void(std::vector< std::string >)> init, std::function< void(CallbackReason, std::string)> update) noexcept
Calls the given functions to provide the initial set of connected writers and when a new writer conne...
std::vector< std::string > getConnectedWriters() const
Gets the connected writers.
Reader & operator=(Reader &&reader) noexcept
Move assignment operator.
void waitForNoWriters() const
Waits for writers to be offline.
Value ValueType
The value type.
Reader(Reader &&reader) noexcept
Move constructor.
void waitForWriters(unsigned int count=1) const
Waits for the given number of writers to be online.
bool hasUnread() const noexcept
Returns whether or not unread samples are available.
void onConnectedKeys(std::function< void(std::vector< Key >)> init, std::function< void(CallbackReason, Key)> update) noexcept
Calls the given functions to provide the initial set of connected keys and when a key is added or rem...
std::vector< Sample< Key, Value, UpdateTag > > getAllUnread()
Returns all the unread samples.
Sample< Key, Value, UpdateTag > getNextUnread()
Returns the next unread sample.
bool hasWriters() const noexcept
Indicates whether or not writers are online.
void waitForUnread(unsigned int count=1) const
Waits for the given number of unread samples to be available.
void onSamples(std::function< void(std::vector< Sample< Key, Value, UpdateTag > >)> init, std::function< void(Sample< Key, Value, UpdateTag >)> queue) noexcept
Calls the given function to provide the initial set of unread samples and when new samples are queued...
The Reader class is used to retrieve samples for a data element.
const Value & getValue() const noexcept
Value ValueType
The type of the sample value.
const std::string & getSession() const noexcept
UpdateTag getUpdateTag() const
const std::string & getOrigin() const noexcept
UpdateTag UpdateTagType
The type of the update tag.
Key KeyType
The type of the sample key.
SampleEvent getEvent() const noexcept
Gets the event associated with the sample.
std::chrono::time_point< std::chrono::system_clock > getTimeStamp() const noexcept
const Key & getKey() const noexcept
A sample provides information about a data element update.
SingleKeyReader & operator=(SingleKeyReader &&reader) noexcept
Move assignment operator.
SingleKeyReader(const Topic< Key, Value, UpdateTag > &topic, const Key &key, std::string name=std::string(), const ReaderConfig &config=ReaderConfig())
Constructs a new reader for the given key.
The key reader to read the data element associated with a given key.
std::function< void(const UpdateValue &)> partialUpdate(const UpdateTag &tag)
Gets a partial update generator function for the given partial update tag.
void add(const Value &value)
Adds the data element.
void update(const Value &value)
Updates the data element.
void remove() noexcept
Removes the data element.
SingleKeyWriter & operator=(SingleKeyWriter &&writer) noexcept
Move assignment operator.
SingleKeyWriter(const Topic< Key, Value, UpdateTag > &topic, const Key &key, std::string name=std::string(), const WriterConfig &config=WriterConfig())
Constructs a new writer for the given key.
The key writer to write the data element associated with a given key.
void setUpdater(const UpdateTag &tag, std::function< void(Value &, UpdateValue)> updater) noexcept
Sets an updater function for the given update tag.
Topic(const Node &node, std::string name) noexcept
Constructs a new Topic for the topic with the given name.
void setKeyFilter(std::string name, std::function< std::function< bool(const Key &)>(const Criteria &)> factory) noexcept
Sets a key filter factory.
UpdateTag UpdateTagType
The topic's update tag type (defaults to std::string if not specified).
Key KeyType
The topic's key type.
void waitForReaders(unsigned int count=1) const
Waits for the given number of data readers to be online.
void waitForNoWriters() const
Waits for data writers to be offline.
Value ValueType
The topic's value type.
bool hasReaders() const noexcept
Indicates whether or not data readers are online.
Sample< Key, Value, UpdateTag > SampleType
The topic's sample type.
void setSampleFilter(std::string name, std::function< std::function< bool(const SampleType &)>(const Criteria &)> factory) noexcept
Sets a sample filter factory.
Reader< Key, Value, UpdateTag > ReaderType
The topic's reader type.
bool hasWriters() const noexcept
Indicates whether or not data writers are online.
void setWriterDefaultConfig(const WriterConfig &config) noexcept
Sets the default configuration used to construct writers.
Topic & operator=(Topic &&topic) noexcept
Move assignment operator.
Writer< Key, Value, UpdateTag > WriterType
The topic's writer type.
void setReaderDefaultConfig(const ReaderConfig &config) noexcept
Sets the default configuration used to construct readers.
Topic(Topic &&topic) noexcept
Move constructor.
void waitForWriters(unsigned int count=1) const
Waits for the given number of data writers to be online.
void waitForNoReaders() const
Waits for data readers to be offline.
The WriterConfig class specifies configuration options specific to writers.
Sample< Key, Value, UpdateTag > getLast()
Gets the last written sample.
Writer & operator=(Writer &&writer) noexcept
Move assignment operator.
std::vector< Sample< Key, Value, UpdateTag > > getAll()
Gets all the written sample kept in the writer history.
std::vector< std::string > getConnectedReaders() const
Gets the connected readers.
void onConnectedReaders(std::function< void(std::vector< std::string >)> init, std::function< void(CallbackReason, std::string)> update) noexcept
Calls the given functions to provide the initial set of connected readers and when a new reader conne...
void waitForReaders(unsigned int count=1) const
Waits for the given number of readers to be online.
void onConnectedKeys(std::function< void(std::vector< Key >)> init, std::function< void(CallbackReason, Key)> update) noexcept
Calls the given functions to provide the initial set of connected keys and when a key is added or rem...
bool hasReaders() const noexcept
Indicates whether or not readers are online.
std::vector< Key > getConnectedKeys() const
Gets the keys for which readers are connected to this writer.
Value ValueType
The value type.
Writer(Writer &&writer) noexcept
Move constructor.
void waitForNoReaders() const
Waits for readers to be offline.
The Writer class is used to write samples for a data element.
SampleEvent
Describes the operation used by a data writer to update a data element.
@ Update
The data writer updated the element.
@ Remove
The data writer removed the element.
@ Add
The data writer added the element.
SingleKeyReader< K, V, UT > makeSingleKeyReader(const Topic< K, V, UT > &topic, const typename Topic< K, V, UT >::KeyType &key, std::string name=std::string(), const ReaderConfig &config=ReaderConfig())
Creates a key reader for the given topic and key.
FilteredKeyReader< K, V, UT > makeFilteredKeyReader(const Topic< K, V, UT > &topic, const Filter< KFC > &filter, std::string name=std::string(), const ReaderConfig &config=ReaderConfig())
Creates a new filtered reader for the given topic and key filter.
MultiKeyReader< K, V, UT > makeAnyKeyReader(const Topic< K, V, UT > &topic, std::string name=std::string(), const ReaderConfig &config=ReaderConfig())
Creates an any-key reader for the given topic.
std::vector< SampleEvent > SampleEventSeq
A sequence of sample events.
MultiKeyWriter< K, V, UT > makeMultiKeyWriter(const Topic< K, V, UT > &topic, const std::vector< typename Topic< K, V, UT >::KeyType > &keys, std::string name=std::string(), const WriterConfig &config=WriterConfig())
Creates a multi-key writer for the given topic and keys.
SingleKeyWriter< K, V, UT > makeSingleKeyWriter(const Topic< K, V, UT > &topic, const typename Topic< K, V, UT >::KeyType &key, std::string name=std::string(), const WriterConfig &config=WriterConfig())
Creates a key writer for the given topic and key.
MultiKeyReader< K, V, UT > makeMultiKeyReader(const Topic< K, V, UT > &topic, const std::vector< typename Topic< K, V, UT >::KeyType > &keys, std::string name=std::string(), const ReaderConfig &config=ReaderConfig())
Creates a multi-key reader for the given topic.
std::ostream & operator<<(std::ostream &os, const SampleEventSeq &types)
Converts the given sample type vector to a string and add it to the stream.
MultiKeyWriter< K, V, UT > makeAnyKeyWriter(const Topic< K, V, UT > &topic, std::string name=std::string(), const WriterConfig &config=WriterConfig())
Creates an any-key writer for the given topic.
CallbackReason
The callback action enumerator specifies the reason why a callback is called.
Data-centric, broker-less publish/subscribe framework. C++ only.
std::shared_ptr< Communicator > CommunicatorPtr
A shared pointer to a Communicator.
void print(std::ostream &stream, T v)
Prints a value to a stream.
static T clone(const T &value) noexcept
Clones the given value.
Filter(std::string name, TT &&criteria) noexcept
Constructs a filter structure with the given name and criteria.
std::string name
The filter name.
T criteria
The filter criteria value.
Filter structure to specify the filter name and criteria value.