6#include "Ice/Demangle.h"
12# pragma clang diagnostic push
13# pragma clang diagnostic ignored "-Wshadow-field-in-constructor"
14#elif defined(__GNUC__)
15# pragma GCC diagnostic push
16# pragma GCC diagnostic ignored "-Wshadow"
21 template<
typename K,
typename V,
typename U>
class Sample;
26 template<
typename T>
class has_communicator_parameter
28 template<
typename TT,
typename SS>
29 static auto testE(
int)
noexcept
30 ->
decltype(TT::encode(std::declval<Ice::CommunicatorPtr&>(), std::declval<SS&>()), std::true_type());
32 template<
typename,
typename>
static auto testE(...) -> std::false_type;
34 template<
typename TT,
typename SS>
35 static auto testD(
int)
noexcept
36 ->
decltype(TT::decode(std::declval<Ice::CommunicatorPtr&>(),
Ice::ByteSeq()), std::true_type());
38 template<
typename,
typename>
static auto testD(...) -> std::false_type;
41 static constexpr bool value =
42 decltype(testE<DataStorm::Encoder<T>, T>(0))::value &&
decltype(testD<DataStorm::Decoder<T>, T>(0))::value;
45 template<
typename T,
typename Enabler =
void>
struct EncoderT
53 template<
typename T,
typename Enabler =
void>
struct DecoderT
61 template<
typename T>
struct EncoderT<T, std::enable_if_t<has_communicator_parameter<T>::value>>
69 template<
typename T>
struct DecoderT<T, std::enable_if_t<has_communicator_parameter<T>::value>>
77 template<
typename T>
class is_streamable
79 template<
typename TT,
typename SS>
80 static auto test(
int)
noexcept ->
decltype(std::declval<SS&>() << std::declval<TT>(), std::true_type());
82 template<
typename,
typename>
static auto test(...) noexcept -> std::false_type;
85 static constexpr
bool value = decltype(test<T, std::ostream>(0))::value;
88 template<typename T, typename Enabler =
void> struct Stringifier
90 static std::string toString(
const T& value)
92 std::ostringstream os;
93 os << IceInternal::demangle(
typeid(value).name()) <<
'(' << &value <<
')';
98 template<
typename T>
struct Stringifier<T, std::enable_if_t<is_streamable<T>::value>>
100 static std::string toString(
const T& value)
102 std::ostringstream os;
108 template<
typename T>
class AbstractElementT :
public virtual Element
111 template<
typename TT> AbstractElementT(TT&& v, std::int64_t
id) : _value(std::forward<TT>(v)), _id(id) {}
113 [[nodiscard]] std::string toString()
const override
115 std::ostringstream os;
116 os << _id <<
':' << Stringifier<T>::toString(_value);
122 return EncoderT<T>::encode(communicator, _value);
125 [[nodiscard]] std::int64_t getId()
const override {
return _id; }
127 [[nodiscard]]
const T& get()
const {
return _value; }
131 const std::int64_t _id;
134 template<
typename K,
typename V>
135 class AbstractFactoryT :
public std::enable_shared_from_this<AbstractFactoryT<K, V>>
141 void operator()(V* obj)
143 if (
auto factory = _factory.lock())
145 factory->remove(obj);
150 std::weak_ptr<AbstractFactoryT<K, V>> _factory;
155 AbstractFactoryT() =
default;
157 void init() { _deleter = Deleter{std::enable_shared_from_this<AbstractFactoryT<K, V>>::shared_from_this()}; }
159 template<
typename F,
typename... Args>
160 [[nodiscard]] std::shared_ptr<typename V::BaseClassType> create(F&& value, Args&&... args)
162 std::lock_guard<std::mutex> lock(_mutex);
163 return createImpl(std::forward<F>(value), std::forward<Args>(args)...);
166 [[nodiscard]] std::vector<std::shared_ptr<typename V::BaseClassType>> create(std::vector<K> values)
168 std::lock_guard<std::mutex> lock(_mutex);
169 std::vector<std::shared_ptr<typename V::BaseClassType>> seq;
170 seq.reserve(values.size());
171 for (
auto& v : values)
173 seq.push_back(createImpl(std::move(v)));
179 friend struct Deleter;
181 [[nodiscard]] std::shared_ptr<typename V::BaseClassType> getImpl(std::int64_t
id)
const
183 std::lock_guard<std::mutex> lock(_mutex);
184 auto p = _elementsById.find(
id);
185 if (p != _elementsById.end())
187 return p->second.lock();
192 template<
typename F,
typename... Args> [[nodiscard]] std::shared_ptr<V> createImpl(F&& value, Args&&... args)
196 auto p = _elements.find(value);
197 if (p != _elements.end())
199 auto k = p->second.lock();
211 std::shared_ptr<V>(
new V(std::forward<F>(value), std::forward<Args>(args)..., ++_nextId), _deleter);
212 _elements[k->get()] = k;
213 _elementsById[k->getId()] = k;
221 std::shared_ptr<V> e;
222 std::lock_guard<std::mutex> lock(_mutex);
223 auto p = _elements.find(v->get());
224 if (p != _elements.end())
228 e = p->second.lock();
234 _elementsById.erase(v->getId());
237 mutable std::mutex _mutex;
238 std::map<K, std::weak_ptr<V>> _elements;
239 std::map<std::int64_t, std::weak_ptr<V>> _elementsById;
240 std::int64_t _nextId{1};
243 template<
typename K>
class KeyT final :
public Key,
public AbstractElementT<K>
246 [[nodiscard]] std::string toString() const final {
return "k" + AbstractElementT<K>::toString(); }
248 using AbstractElementT<K>::AbstractElementT;
249 using BaseClassType = Key;
252 template<
typename K>
class KeyFactoryT final :
public KeyFactory,
public AbstractFactoryT<K, KeyT<K>>
255 using AbstractFactoryT<K, KeyT<K>>::AbstractFactoryT;
257 [[nodiscard]] std::shared_ptr<Key> get(std::int64_t
id)
const final
259 return AbstractFactoryT<K, KeyT<K>>::getImpl(
id);
262 [[nodiscard]] std::shared_ptr<Key>
265 return AbstractFactoryT<K, KeyT<K>>::create(DecoderT<K>::decode(communicator, data));
268 [[nodiscard]]
static std::shared_ptr<KeyFactoryT<K>> createFactory()
270 auto f = std::make_shared<KeyFactoryT<K>>();
276 template<
typename T>
class TagT final :
public Tag,
public AbstractElementT<T>
279 [[nodiscard]] std::string toString() const final {
return "t" + AbstractElementT<T>::toString(); }
281 using AbstractElementT<T>::AbstractElementT;
282 using BaseClassType = Tag;
285 template<
typename T>
class TagFactoryT final :
public TagFactory,
public AbstractFactoryT<T, TagT<T>>
288 using AbstractFactoryT<T, TagT<T>>::AbstractFactoryT;
290 [[nodiscard]] std::shared_ptr<Tag> get(std::int64_t
id)
const final
292 return AbstractFactoryT<T, TagT<T>>::getImpl(
id);
295 [[nodiscard]] std::shared_ptr<Tag>
298 return AbstractFactoryT<T, TagT<T>>::create(DecoderT<T>::decode(communicator, data));
301 [[nodiscard]]
static std::shared_ptr<TagFactoryT<T>> createFactory()
303 auto f = std::make_shared<TagFactoryT<T>>();
309 template<
typename Key,
typename Value,
typename UpdateTag>
310 class SampleT final :
public Sample,
public std::enable_shared_from_this<SampleT<Key, Value, UpdateTag>>
318 const std::shared_ptr<DataStormI::Key>& key,
319 const std::shared_ptr<DataStormI::Tag>& tag,
321 std::int64_t timestamp)
322 : Sample(std::move(session), std::move(origin), id, event, key, tag, std::move(value), timestamp),
329 SampleT(
DataStorm::SampleEvent event, Value value) : Sample(event), _hasValue(true), _value(std::move(value)) {}
331 SampleT(
Ice::ByteSeq value,
const std::shared_ptr<Tag>& tag)
335 _encodedValue = std::move(value);
338 [[nodiscard]] DataStorm::Sample<Key, Value, UpdateTag> get()
340 auto impl = std::enable_shared_from_this<SampleT<Key, Value, UpdateTag>>::shared_from_this();
341 return DataStorm::Sample<Key, Value, UpdateTag>(impl);
344 [[nodiscard]]
const Key& getKey()
347 return std::static_pointer_cast<KeyT<Key>>(key)->get();
350 [[nodiscard]]
const Value& getValue()
const {
return _value; }
352 [[nodiscard]] UpdateTag getTag()
const
354 return tag ? std::static_pointer_cast<TagT<UpdateTag>>(tag)->get() : UpdateTag();
357 void setValue(Value value)
359 _value = std::move(value);
363 [[nodiscard]]
bool hasValue() const final {
return _hasValue; }
365 void setValue(
const std::shared_ptr<Sample>& sample)
final
370 std::static_pointer_cast<DataStormI::SampleT<Key, Value, UpdateTag>>(sample)->getValue());
381 if (_encodedValue.empty())
383 _encodedValue = encodeValue(communicator);
385 return _encodedValue;
397 return EncoderT<Value>::encode(communicator, _value);
409 _value = DecoderT<Value>::decode(communicator, _encodedValue);
411 _encodedValue.clear();
421 template<
typename Key,
typename Value,
typename UpdateTag>
class SampleFactoryT final :
public SampleFactory
424 [[nodiscard]] std::shared_ptr<Sample> create(
429 const std::shared_ptr<DataStormI::Key>& key,
430 const std::shared_ptr<DataStormI::Tag>& tag,
432 std::int64_t timestamp)
final
434 return std::make_shared<SampleT<Key, Value, UpdateTag>>(
446 template<
typename C,
typename V>
class FilterT final :
public Filter,
public AbstractElementT<C>
449 template<
typename CC,
typename FF>
450 FilterT(CC&& criteria, std::string name, FF lambda, std::int64_t
id)
451 : AbstractElementT<C>::AbstractElementT(std::forward<CC>(criteria), id),
452 _name(std::move(name)),
453 _lambda(std::move(lambda))
457 [[nodiscard]] std::string toString() const final {
return "f" + AbstractElementT<C>::toString(); }
459 [[nodiscard]]
bool match(
const std::shared_ptr<Filterable>& value)
const final
461 return _lambda(std::static_pointer_cast<V>(value)->get());
464 [[nodiscard]]
const std::string& getName() const final {
return _name; }
466 using BaseClassType = Filter;
470 std::function<bool(const typename std::remove_reference<decltype(std::declval<V>().get())>::type&)> _lambda;
473 template<
typename C,
typename V>
474 class FilterFactoryT final :
public FilterFactory,
public AbstractFactoryT<C, FilterT<C, V>>
477 FilterFactoryT() =
default;
479 [[nodiscard]] std::shared_ptr<Filter> get(std::int64_t
id)
const final
481 return AbstractFactoryT<C, FilterT<C, V>>::getImpl(
id);
484 [[nodiscard]]
static std::shared_ptr<FilterFactoryT<C, V>> createFactory()
486 auto f = std::make_shared<FilterFactoryT<C, V>>();
492 template<
typename ValueT>
class FilterManagerT final :
public FilterManager
494 using Value = std::remove_reference_t<decltype(std::declval<ValueT>().get())>;
498 virtual ~Factory() =
default;
500 [[nodiscard]]
virtual std::shared_ptr<Filter> get(std::int64_t)
const = 0;
505 template<
typename Criteria>
struct FactoryT final : Factory
507 FactoryT(std::string name, std::function<std::function<
bool(
const Value&)>(
const Criteria&)> lambda)
508 : name(std::move(name)),
509 lambda(std::move(lambda))
513 [[nodiscard]] std::shared_ptr<Filter> create(
const Criteria& criteria)
515 return std::static_pointer_cast<FilterT<Criteria, ValueT>>(
516 filterFactory.create(criteria, name, lambda(criteria)));
519 [[nodiscard]] std::shared_ptr<Filter> get(std::int64_t
id)
const final {
return filterFactory.get(
id); }
521 [[nodiscard]] std::shared_ptr<Filter>
524 return create(DecoderT<Criteria>::decode(communicator, data));
527 const std::string name;
528 std::function<std::function<bool(const Value&)>(
const Criteria&)> lambda;
529 FilterFactoryT<Criteria, ValueT> filterFactory;
533 template<
typename Criteria>
534 [[nodiscard]] std::shared_ptr<Filter> create(
const std::string& name,
const Criteria& criteria)
536 auto p = _factories.find(name);
537 if (p == _factories.end())
539 throw std::invalid_argument(
"unknown filter '" + name +
"'");
542 auto factory =
dynamic_cast<FactoryT<Criteria>*
>(p->second.get());
545 throw std::invalid_argument(
"filter '" + name +
"' type doesn't match");
548 return factory->create(criteria);
551 [[nodiscard]] std::shared_ptr<Filter>
554 auto p = _factories.find(name);
555 if (p == _factories.end())
560 return p->second->decode(communicator, data);
563 [[nodiscard]] std::shared_ptr<Filter> get(
const std::string& name, std::int64_t
id)
const final
565 auto p = _factories.find(name);
566 if (p == _factories.end())
571 return p->second->get(
id);
574 template<
typename Criteria>
575 void set(std::string name, std::function<std::function<
bool(
const Value&)>(
const Criteria&)> lambda)
579 auto factory = std::make_unique<FactoryT<Criteria>>(name, std::move(lambda));
580 _factories.emplace(std::move(name), std::move(factory));
584 _factories.erase(name);
590 std::map<std::string, std::unique_ptr<Factory>> _factories;
594#if defined(__clang__)
595# pragma clang diagnostic pop
596#elif defined(__GNUC__)
597# pragma GCC diagnostic pop
A sample provides information about a data element update.
SampleEvent
Describes the operation used by a data writer to update a data element.
@ Remove
The data writer removed the element.
@ PartialUpdate
The data writer partially updated the element.
Data-centric, broker-less publish/subscribe framework. C++ only.
std::shared_ptr< Communicator > CommunicatorPtr
A shared pointer to a Communicator.
std::vector< std::byte > ByteSeq
A sequence of bytes.
static T clone(const T &value) noexcept
Clones the given value.
static T decode(const Ice::CommunicatorPtr &communicator, const Ice::ByteSeq &value)
Decodes a value.
static Ice::ByteSeq encode(const Ice::CommunicatorPtr &communicator, const T &value) noexcept
Encodes the given value.