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;
78 [[nodiscard]] const std::
string& getSession() const noexcept;
81 Sample(const std::shared_ptr<DataStormI::Sample>&) noexcept;
84 std::shared_ptr<DataStormI::SampleT<Key, Value, UpdateTag>> _impl;
91 inline std::ostream& operator<<(std::ostream& os, const
SampleEventSeq& types)
101 template<
typename K,
typename V,
typename U>
110 template<
typename Key,
typename Value,
typename UpdateTag>
class Reader
134 [[nodiscard]]
bool hasWriters() const noexcept;
163 [[nodiscard]]
bool hasUnread() const noexcept;
178 std::function<
void(std::vector<Key>)> init,
188 std::function<
void(std::vector<std::
string>)> init,
189 std::function<
void(
CallbackReason, std::
string)> update) noexcept;
199 std::function<
void(std::vector<
Sample<Key, Value, UpdateTag>>)> init,
200 std::function<
void(
Sample<Key, Value, UpdateTag>)> queue) noexcept;
204 Reader(const std::shared_ptr<DataStormI::DataReader>& impl) noexcept : _impl(impl) {}
207 std::shared_ptr<DataStormI::DataReader> _impl;
212 template<
typename Key,
typename Value,
typename UpdateTag>
class Writer
236 [[nodiscard]]
bool hasReaders() const noexcept;
262 [[nodiscard]] std::vector<
Sample<Key, Value, UpdateTag>>
getAll();
272 std::function<
void(std::vector<Key>)> init,
282 std::function<
void(std::vector<std::
string>)> init,
283 std::function<
void(
CallbackReason, std::
string)> update) noexcept;
287 Writer(const std::shared_ptr<DataStormI::DataWriter>& impl) noexcept : _impl(impl) {}
290 std::shared_ptr<DataStormI::DataWriter> _impl;
297 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
class Topic
321 Topic(
const Node& node, std::string name)
noexcept;
326 : _name(std::move(topic._name)),
327 _topicFactory(std::move(topic._topicFactory)),
328 _keyFactory(std::move(topic._keyFactory)),
329 _tagFactory(std::move(topic._tagFactory)),
330 _keyFilterFactories(std::move(topic._keyFilterFactories)),
331 _sampleFilterFactories(std::move(topic._sampleFilterFactories)),
332 _reader(std::move(topic._reader)),
333 _writer(std::move(topic._writer)),
334 _updaters(std::move(topic._updaters))
349 [[nodiscard]]
bool hasWriters() const noexcept;
354 void waitForWriters(
unsigned int count = 1) const;
358 void waitForNoWriters() const;
362 void setWriterDefaultConfig(const
WriterConfig& config) noexcept;
366 [[nodiscard]]
bool hasReaders() const noexcept;
371 void waitForReaders(
unsigned int count = 1) const;
375 void waitForNoReaders() const;
379 void setReaderDefaultConfig(const
ReaderConfig& config) noexcept;
386 template<typename UpdateValue>
387 void setUpdater(const UpdateTag& tag, std::function<
void(Value&, UpdateValue)> updater) noexcept;
396 template<typename Criteria>
399 std::function<std::function<
bool(const Key&)>(const Criteria&)> factory) noexcept;
414 template<typename Criteria>
415 void setSampleFilter(
417 std::function<std::function<
bool(const SampleType&)>(const Criteria&)> factory) noexcept;
420 [[nodiscard]] std::shared_ptr<DataStormI::TopicReader> getReader() const;
421 [[nodiscard]] std::shared_ptr<DataStormI::TopicWriter> getWriter() const;
422 [[nodiscard]]
Ice::CommunicatorPtr getCommunicator() const noexcept;
425 template<typename, typename, typename> friend class
MultiKeyWriter;
427 template<typename, typename, typename> friend class
MultiKeyReader;
432 std::shared_ptr<DataStormI::TopicFactory> _topicFactory;
433 std::shared_ptr<DataStormI::KeyFactoryT<Key>> _keyFactory;
434 std::shared_ptr<DataStormI::TagFactoryT<UpdateTag>> _tagFactory;
435 std::shared_ptr<DataStormI::FilterManagerT<DataStormI::KeyT<Key>>> _keyFilterFactories;
436 std::shared_ptr<DataStormI::FilterManagerT<DataStormI::SampleT<Key, Value, UpdateTag>>> _sampleFilterFactories;
438 mutable std::mutex _mutex;
439 mutable std::shared_ptr<DataStormI::TopicReader> _reader;
440 mutable std::shared_ptr<DataStormI::TopicWriter> _writer;
441 mutable std::map<std::shared_ptr<DataStormI::Tag>, DataStormI::
Topic::Updater> _updaters;
451 template<
typename TT>
466 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
479 std::string name = std::string(),
490 template<
typename SampleFilterCriteria>
495 std::string name = std::string(),
516 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
529 const std::vector<Key>& keys,
530 std::string name = std::string(),
542 template<
typename SampleFilterCriteria>
545 const std::vector<Key>& keys,
547 std::string name = std::string(),
566 template<
typename K,
typename V,
typename UT>
570 std::string name = std::string(),
583 template<
typename SFC,
typename K,
typename V,
typename UT>
588 std::string name = std::string(),
601 template<
typename K,
typename V,
typename UT>
605 std::string name = std::string(),
619 template<
typename SFC,
typename K,
typename V,
typename UT>
624 std::string name = std::string(),
636 template<
typename K,
typename V,
typename UT>
639 std::string name = std::string(),
652 template<
typename SFC,
typename K,
typename V,
typename UT>
656 std::string name = std::string(),
669 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
681 template<
typename KeyFilterCriteria>
685 std::string name = std::string(),
697 template<
typename KeyFilterCriteria,
typename SampleFilterCriteria>
702 std::string name = std::string(),
721 template<
typename KFC,
typename K,
typename V,
typename UT>
725 std::string name = std::string(),
738 template<
typename KFC,
typename SFC,
typename K,
typename V,
typename UT>
743 std::string name = std::string(),
751 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
764 std::string name = std::string(),
778 void add(
const Value& value);
782 void update(
const Value& value);
796 template<
typename UpdateValue>
797 [[nodiscard]] std::function<void(
const UpdateValue&)>
partialUpdate(
const UpdateTag& tag);
805 const std::shared_ptr<DataStormI::TagFactoryT<UpdateTag>> _tagFactory;
817 template<
typename Key,
typename Value,
typename UpdateTag = std::
string>
830 const std::vector<Key>& keys,
831 std::string name = std::string(),
846 void add(
const Key& key,
const Value& value);
851 void update(
const Key& key,
const Value& value);
865 template<
typename UpdateValue>
866 [[nodiscard]] std::function<void(
const Key&,
const UpdateValue&)>
partialUpdate(
const UpdateTag& tag);
872 void remove(
const Key& key)
noexcept;
875 const std::shared_ptr<DataStormI::KeyFactoryT<Key>> _keyFactory;
876 const std::shared_ptr<DataStormI::TagFactoryT<UpdateTag>> _tagFactory;
885 template<
typename K,
typename V,
typename UT>
889 std::string name = std::string(),
901 template<
typename K,
typename V,
typename UT>
905 std::string name = std::string(),
916 template<
typename K,
typename V,
typename UT>
919 std::string name = std::string(),
932 template<
typename Key,
typename Value,
typename UpdateTag>
938 template<
typename Key,
typename Value,
typename UpdateTag>
941 return _impl->getKey();
944 template<
typename Key,
typename Value,
typename UpdateTag>
947 return _impl->getValue();
950 template<
typename Key,
typename Value,
typename UpdateTag>
953 return _impl->getTag();
956 template<
typename Key,
typename Value,
typename UpdateTag>
959 return _impl->timestamp;
962 template<
typename Key,
typename Value,
typename UpdateTag>
965 return _impl->origin;
968 template<
typename Key,
typename Value,
typename UpdateTag>
969 const std::string& Sample<Key, Value, UpdateTag>::getSession() const noexcept
971 return _impl->session;
974 template<
typename Key,
typename Value,
typename UpdateTag>
975 Sample<Key, Value, UpdateTag>::Sample(
const std::shared_ptr<DataStormI::Sample>& impl) noexcept
976 : _impl(std::static_pointer_cast<DataStormI::SampleT<Key, Value, UpdateTag>>(impl))
983 template<
typename Key,
typename Value,
typename UpdateTag>
985 : _impl(std::move(reader._impl))
997 template<
typename Key,
typename Value,
typename UpdateTag>
1004 _impl = std::move(reader._impl);
1008 template<
typename Key,
typename Value,
typename UpdateTag>
1011 return _impl->hasWriters();
1014 template<
typename Key,
typename Value,
typename UpdateTag>
1017 _impl->waitForWriters(
static_cast<int>(count));
1020 template<
typename Key,
typename Value,
typename UpdateTag>
1023 _impl->waitForWriters(-1);
1026 template<
typename Key,
typename Value,
typename UpdateTag>
1029 return _impl->getConnectedElements();
1032 template<
typename Key,
typename Value,
typename UpdateTag>
1035 std::vector<Key> keys;
1036 auto connectedKeys = _impl->getConnectedKeys();
1037 keys.reserve(connectedKeys.size());
1038 for (
const auto& k : connectedKeys)
1040 keys.push_back(std::static_pointer_cast<DataStormI::KeyT<Key>>(k)->get());
1045 template<
typename Key,
typename Value,
typename UpdateTag>
1048 auto unread = _impl->getAllUnread();
1049 std::vector<Sample<Key, Value, UpdateTag>> samples;
1050 samples.reserve(unread.size());
1051 for (
const auto& sample : unread)
1053 samples.push_back(sample);
1058 template<
typename Key,
typename Value,
typename UpdateTag>
1061 _impl->waitForUnread(count);
1064 template<
typename Key,
typename Value,
typename UpdateTag>
1067 return _impl->hasUnread();
1070 template<
typename Key,
typename Value,
typename UpdateTag>
1076 template<
typename Key,
typename Value,
typename UpdateTag>
1078 std::function<
void(std::vector<Key>)> init,
1081 _impl->onConnectedKeys(
1083 [init = std::move(init)](
const std::vector<std::shared_ptr<DataStormI::Key>>& connectedKeys)
1085 std::vector<Key> keys;
1086 keys.reserve(connectedKeys.size());
1087 for(
const auto& k : connectedKeys)
1089 keys.push_back(std::static_pointer_cast<DataStormI::KeyT<Key>>(k)->get());
1091 init(std::move(keys));
1092 } : std::function<void(std::vector<std::shared_ptr<DataStormI::Key>>)>{},
1094 [update = std::move(update)](
CallbackReason action,
const std::shared_ptr<DataStormI::Key>& key)
1096 update(action, std::static_pointer_cast<DataStormI::KeyT<Key>>(key)->get());
1097 } : std::function<void(
CallbackReason, std::shared_ptr<DataStormI::Key>)>{});
1100 template<
typename Key,
typename Value,
typename UpdateTag>
1102 std::function<
void(std::vector<std::string>)> init,
1103 std::function<
void(
CallbackReason, std::string)> update)
noexcept
1105 _impl->onConnectedElements(std::move(init), std::move(update));
1108 template<
typename Key,
typename Value,
typename UpdateTag>
1113 auto communicator = _impl->getCommunicator();
1116 [communicator, init = std::move(init)](
const std::vector<std::shared_ptr<DataStormI::Sample>>& samplesI)
1118 std::vector<Sample<Key, Value, UpdateTag>> samples;
1119 samples.reserve(samplesI.size());
1120 for(
const auto& s : samplesI)
1122 samples.emplace_back(s);
1124 init(std::move(samples));
1125 } : std::function<void(
const std::vector<std::shared_ptr<DataStormI::Sample>>&)>(),
1127 [communicator, update = std::move(update)](
const std::shared_ptr<DataStormI::Sample>& sampleI)
1130 } : std::function<void(
const std::shared_ptr<DataStormI::Sample>&)>{});
1133 template<
typename Key,
typename Value,
typename UpdateTag>
1139 :
Reader<Key, Value, UpdateTag>(
1140 topic.getReader()->create({topic._keyFactory->create(key)}, std::move(name), config))
1144 template<
typename Key,
typename Value,
typename UpdateTag>
1145 template<
typename SampleFilterCriteria>
1152 :
Reader<Key, Value, UpdateTag>(topic.getReader()->create(
1153 {topic._keyFactory->create(key)},
1157 DataStormI::EncoderT<SampleFilterCriteria>::encode(topic.getCommunicator(), sampleFilter.
criteria)))
1161 template<
typename Key,
typename Value,
typename UpdateTag>
1167 template<
typename Key,
typename Value,
typename UpdateTag>
1175 template<
typename Key,
typename Value,
typename UpdateTag>
1178 const std::vector<Key>& keys,
1181 :
Reader<Key, Value, UpdateTag>(
1182 topic.getReader()->create(topic._keyFactory->create(keys), std::move(name), config))
1186 template<
typename Key,
typename Value,
typename UpdateTag>
1187 template<
typename SampleFilterCriteria>
1190 const std::vector<Key>& keys,
1194 :
Reader<Key, Value, UpdateTag>(topic.getReader()->create(
1195 topic._keyFactory->create(keys),
1199 DataStormI::EncoderT<SampleFilterCriteria>::encode(topic.getCommunicator(), sampleFilter.criteria)))
1203 template<
typename Key,
typename Value,
typename UpdateTag>
1209 template<
typename Key,
typename Value,
typename UpdateTag>
1217 template<
typename Key,
typename Value,
typename UpdateTag>
1218 template<
typename KeyFilterCriteria>
1224 :
Reader<Key, Value, UpdateTag>(topic.getReader()->createFiltered(
1225 topic._keyFilterFactories->create(filter.name, filter.criteria),
1231 template<
typename Key,
typename Value,
typename UpdateTag>
1232 template<
typename KeyFilterCriteria,
typename SampleFilterCriteria>
1239 :
Reader<Key, Value, UpdateTag>(topic.getReader()->createFiltered(
1240 topic._keyFilterFactories->create(keyFilter.name, keyFilter.criteria),
1244 DataStormI::EncoderT<SampleFilterCriteria>::encode(topic.getCommunicator(), sampleFilter.criteria)))
1248 template<
typename Key,
typename Value,
typename UpdateTag>
1255 template<
typename Key,
typename Value,
typename UpdateTag>
1266 template<
typename Key,
typename Value,
typename UpdateTag>
1279 template<
typename Key,
typename Value,
typename UpdateTag>
1286 _impl = std::move(writer._impl);
1290 template<
typename Key,
typename Value,
typename UpdateTag>
1296 template<
typename Key,
typename Value,
typename UpdateTag>
1299 return _impl->waitForReaders(
static_cast<int>(count));
1302 template<
typename Key,
typename Value,
typename UpdateTag>
1305 return _impl->waitForReaders(-1);
1308 template<
typename Key,
typename Value,
typename UpdateTag>
1311 return _impl->getConnectedElements();
1314 template<
typename Key,
typename Value,
typename UpdateTag>
1317 std::vector<Key> keys;
1318 auto connectedKeys = _impl->getConnectedKeys();
1319 keys.reserve(connectedKeys.size());
1320 for (
const auto& k : connectedKeys)
1322 keys.push_back(std::static_pointer_cast<DataStormI::KeyT<Key>>(k)->get());
1327 template<
typename Key,
typename Value,
typename UpdateTag>
1330 auto sample = _impl->getLast();
1333 throw std::logic_error(
"no sample");
1338 template<
typename Key,
typename Value,
typename UpdateTag>
1341 auto all = _impl->getAll();
1342 std::vector<Sample<Key, Value, UpdateTag>> samples;
1343 samples.reserve(all.size());
1344 for (
const auto& sample : all)
1346 samples.push_back(sample);
1351 template<
typename Key,
typename Value,
typename UpdateTag>
1353 std::function<
void(std::vector<Key>)> init,
1356 _impl->onConnectedKeys(
1358 [init = std::move(init)](
const std::vector<std::shared_ptr<DataStormI::Key>>& connectedKeys)
1360 std::vector<Key> keys;
1361 keys.reserve(connectedKeys.size());
1362 for(
const auto& k : connectedKeys)
1364 keys.push_back(std::static_pointer_cast<DataStormI::KeyT<Key>>(k)->get());
1366 init(std::move(keys));
1367 } : std::function<void(std::vector<std::shared_ptr<DataStormI::Key>>)>{},
1369 [update = std::move(update)](
CallbackReason action,
const std::shared_ptr<DataStormI::Key>& key)
1371 update(action, std::static_pointer_cast<DataStormI::KeyT<Key>>(key)->get());
1372 } : std::function<void(
CallbackReason, std::shared_ptr<DataStormI::Key>)>{});
1375 template<
typename Key,
typename Value,
typename UpdateTag>
1377 std::function<
void(std::vector<std::string>)> init,
1378 std::function<
void(
CallbackReason, std::string)> update)
noexcept
1380 _impl->onConnectedElements(std::move(init), std::move(update));
1383 template<
typename Key,
typename Value,
typename UpdateTag>
1389 :
Writer<Key, Value, UpdateTag>(
1390 topic.getWriter()->create({topic._keyFactory->create(key)}, std::move(name), config)),
1391 _tagFactory(topic._tagFactory)
1395 template<
typename Key,
typename Value,
typename UpdateTag>
1398 _tagFactory(std::move(writer._tagFactory))
1402 template<
typename Key,
typename Value,
typename UpdateTag>
1410 template<
typename Key,
typename Value,
typename UpdateTag>
1413 Writer<Key, Value, UpdateTag>::_impl->publish(
1415 std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(
SampleEvent::Add, value));
1418 template<
typename Key,
typename Value,
typename UpdateTag>
1421 Writer<Key, Value, UpdateTag>::_impl->publish(
1423 std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(
SampleEvent::Update, value));
1426 template<
typename Key,
typename Value,
typename UpdateTag>
1427 template<
typename UpdateValue>
1430 auto impl = Writer<Key, Value, UpdateTag>::_impl;
1431 auto updateTag = _tagFactory->create(tag);
1432 return [impl, updateTag](
const UpdateValue& value)
1434 auto encoded = DataStormI::EncoderT<UpdateValue>::encode(impl->getCommunicator(), value);
1435 impl->publish(
nullptr, std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(encoded, updateTag));
1439 template<
typename Key,
typename Value,
typename UpdateTag>
1442 Writer<Key, Value, UpdateTag>::_impl->publish(
1447 template<
typename Key,
typename Value,
typename UpdateTag>
1450 const std::vector<Key>& keys,
1453 :
Writer<Key, Value, UpdateTag>(
1454 topic.getWriter()->create(topic._keyFactory->create(keys), std::move(name), config)),
1455 _keyFactory(topic._keyFactory),
1456 _tagFactory(topic._tagFactory)
1460 template<
typename Key,
typename Value,
typename UpdateTag>
1463 _keyFactory(std::move(writer._keyFactory)),
1464 _tagFactory(std::move(writer._tagFactory))
1468 template<
typename Key,
typename Value,
typename UpdateTag>
1476 template<
typename Key,
typename Value,
typename UpdateTag>
1479 Writer<Key, Value, UpdateTag>::_impl->publish(
1480 _keyFactory->create(key),
1481 std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(
SampleEvent::Add, value));
1484 template<
typename Key,
typename Value,
typename UpdateTag>
1487 Writer<Key, Value, UpdateTag>::_impl->publish(
1488 _keyFactory->create(key),
1489 std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(
SampleEvent::Update, value));
1492 template<
typename Key,
typename Value,
typename UpdateTag>
1493 template<
typename UpdateValue>
1494 std::function<void(
const Key&,
const UpdateValue&)>
1497 auto impl = Writer<Key, Value, UpdateTag>::_impl;
1498 auto updateTag = _tagFactory->create(tag);
1499 auto keyFactory = _keyFactory;
1500 return [impl, updateTag, keyFactory](
const Key& key,
const UpdateValue& value)
1502 auto encoded = DataStormI::EncoderT<UpdateValue>::encode(impl->getCommunicator(), value);
1504 keyFactory->create(key),
1505 std::make_shared<DataStormI::SampleT<Key, Value, UpdateTag>>(encoded, updateTag));
1509 template<
typename Key,
typename Value,
typename UpdateTag>
1512 Writer<Key, Value, UpdateTag>::_impl->publish(
1513 _keyFactory->create(key),
1518 template<
typename Value> std::function<std::function<bool(const Value&)>(
const std::string&)> makeRegexFilter()
1521 return [](
const std::string& criteria)
1523 std::regex expr(criteria);
1524 return [expr = std::move(expr)](
const Value& value)
1526 std::ostringstream os;
1528 return std::regex_match(os.str(), expr);
1534 template<
typename Key,
typename Value,
typename UpdateTag>
1541 {
return std::find(criteria.begin(), criteria.end(), sample.getEvent()) != criteria.end(); };
1546 template<
typename T,
typename V,
typename Enabler =
void>
struct RegexFilter
1548 template<
typename F>
static void add(
const F&) {}
1552 template<
typename T,
typename V>
struct RegexFilter<T, V, std::enable_if_t<DataStormI::is_streamable<V>::value>>
1554 template<
typename F>
static void add(
const F& factory)
1556 factory->set(
"_regex", makeRegexFilter<T>());
1563 template<
typename Key,
typename Value,
typename UpdateTag>
1565 : _name(std::move(name)),
1566 _topicFactory(node._factory),
1567 _keyFactory(DataStormI::KeyFactoryT<Key>::createFactory()),
1568 _tagFactory(DataStormI::TagFactoryT<UpdateTag>::createFactory()),
1569 _keyFilterFactories(std::make_shared<DataStormI::FilterManagerT<DataStormI::KeyT<Key>>>()),
1570 _sampleFilterFactories(
1571 std::make_shared<DataStormI::FilterManagerT<DataStormI::SampleT<Key, Value, UpdateTag>>>())
1573 RegexFilter<Key, Key>::add(_keyFilterFactories);
1574 RegexFilter<Sample<Key, Value, UpdateTag>, Value>::add(_sampleFilterFactories);
1575 _sampleFilterFactories->set(
"_event", makeSampleEventFilter(*
this));
1580 std::lock_guard<std::mutex> lock(_mutex);
1591 template<
typename Key,
typename Value,
typename UpdateTag>
1594 std::lock_guard<std::mutex> lock(_mutex);
1603 _name = std::move(topic._name);
1604 _topicFactory = std::move(topic._topicFactory);
1605 _keyFactory = std::move(topic._keyFactory);
1606 _tagFactory = std::move(topic._tagFactory);
1607 _keyFilterFactories = std::move(topic._keyFilterFactories);
1608 _sampleFilterFactories = std::move(topic._sampleFilterFactories);
1609 _reader = std::move(topic._reader);
1610 _writer = std::move(topic._writer);
1611 _updaters = std::move(topic._updaters);
1615 template<
typename Key,
typename Value,
typename UpdateTag>
1621 template<
typename Key,
typename Value,
typename UpdateTag>
1624 getReader()->waitForWriters(
static_cast<int>(count));
1627 template<
typename Key,
typename Value,
typename UpdateTag>
1630 getReader()->waitForWriters(-1);
1633 template<
typename Key,
typename Value,
typename UpdateTag>
1636 getReader()->setDefaultConfig(config);
1639 template<
typename Key,
typename Value,
typename UpdateTag>
1642 return getWriter()->hasReaders();
1645 template<
typename Key,
typename Value,
typename UpdateTag>
1648 getWriter()->waitForReaders(
static_cast<int>(count));
1651 template<
typename Key,
typename Value,
typename UpdateTag>
1654 getWriter()->waitForReaders(-1);
1657 template<
typename Key,
typename Value,
typename UpdateTag>
1660 getWriter()->setDefaultConfig(config);
1663 template<
typename Key,
typename Value,
typename UpdateTag>
1664 template<
typename UpdateValue>
1666 const UpdateTag& tag,
1667 std::function<
void(Value&, UpdateValue)> updater)
noexcept
1669 std::lock_guard<std::mutex> lock(_mutex);
1670 auto tagI = _tagFactory->create(std::move(tag));
1673 [updater = std::move(updater)](
const std::shared_ptr<DataStormI::Sample>& previous,
1674 const std::shared_ptr<DataStormI::Sample>& next,
1682 assert(previous && previous->hasValue());
1684 if (previous && previous->hasValue())
1687 std::static_pointer_cast<DataStormI::SampleT<Key, Value, UpdateTag>>(previous)->getValue());
1689 updater(value, DataStormI::DecoderT<UpdateValue>::decode(communicator, next->getEncodedValue()));
1690 std::static_pointer_cast<DataStormI::SampleT<Key, Value, UpdateTag>>(next)->setValue(std::move(value));
1691 } : std::function<void(
const std::shared_ptr<DataStormI::Sample>&,
1692 const std::shared_ptr<DataStormI::Sample>&,
1695 if (_reader && !_writer)
1697 _reader->setUpdater(tagI, updaterImpl);
1699 else if (_writer && !_reader)
1701 _writer->setUpdater(tagI, updaterImpl);
1703 else if (_reader && _writer)
1705 _reader->setUpdater(tagI, updaterImpl);
1706 _writer->setUpdater(tagI, updaterImpl);
1710 _updaters[tagI] = updaterImpl;
1714 template<
typename Key,
typename Value,
typename UpdateTag>
1715 template<
typename Criteria>
1718 std::function<std::function<
bool(
const Key&)>(
const Criteria&)> factory)
noexcept
1720 std::lock_guard<std::mutex> lock(_mutex);
1721 _keyFilterFactories->set(std::move(name), std::move(factory));
1724 template<
typename Key,
typename Value,
typename UpdateTag>
1725 template<
typename Criteria>
1728 std::function<std::function<
bool(
const SampleType&)>(
const Criteria&)> factory)
noexcept
1730 std::lock_guard<std::mutex> lock(_mutex);
1731 _sampleFilterFactories->set(std::move(name), std::move(factory));
1734 template<
typename Key,
typename Value,
typename UpdateTag>
1735 std::shared_ptr<DataStormI::TopicReader> Topic<Key, Value, UpdateTag>::getReader()
const
1737 std::lock_guard<std::mutex> lock(_mutex);
1740 auto sampleFactory = std::make_shared<DataStormI::SampleFactoryT<Key, Value, UpdateTag>>();
1741 _reader = _topicFactory->createTopicReader(
1745 std::move(sampleFactory),
1746 _keyFilterFactories,
1747 _sampleFilterFactories);
1748 _reader->setUpdaters(_writer ? _writer->getUpdaters() : _updaters);
1754 template<
typename Key,
typename Value,
typename UpdateTag>
1755 std::shared_ptr<DataStormI::TopicWriter> Topic<Key, Value, UpdateTag>::getWriter()
const
1757 std::lock_guard<std::mutex> lock(_mutex);
1760 _writer = _topicFactory->createTopicWriter(
1765 _keyFilterFactories,
1766 _sampleFilterFactories);
1767 _writer->setUpdaters(_reader ? _reader->getUpdaters() : _updaters);
1773 template<
typename Key,
typename Value,
typename UpdateTag>
1776 return _topicFactory->getCommunicator();
1780#if defined(__clang__)
1781# pragma clang diagnostic pop
1782#elif defined(__GNUC__)
1783# 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.
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.