Hazelcast C++ Client
Hazelcast C++ Client Library
All Classes Functions Variables Enumerations Enumerator Pages
replicated_map.h
1 /*
2  * Copyright (c) 2008-2021, Hazelcast, Inc. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <string>
19 #include <memory>
20 
21 #include "hazelcast/client/proxy/ReplicatedMapImpl.h"
22 #include "hazelcast/client/entry_listener.h"
23 #include "hazelcast/client/entry_event.h"
24 #include "hazelcast/client/map_event.h"
25 #include "hazelcast/client/query/predicates.h"
26 #include "hazelcast/logger.h"
27 
28 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
29 #pragma warning(push)
30 #pragma warning(disable: 4251) //for dll export
31 #endif
32 
33 namespace hazelcast {
34  namespace client {
46  class HAZELCAST_API replicated_map : public proxy::ReplicatedMapImpl {
47  friend class spi::ProxyManager;
48  public:
49  static constexpr const char *SERVICE_NAME = "hz:impl:replicatedMapService";
64  template<typename K, typename V, typename R = V>
65  boost::future<boost::optional<R>> put(const K &key, const V &value, std::chrono::milliseconds ttl) {
66  return to_object<R>(put_data(to_data(key), to_data(value), ttl));
67  }
68 
79  template<typename K, typename V>
80  boost::future<void> put_all(const std::unordered_map<K, V> &entries) {
81  return put_all_data(to_data_entries(entries));
82  }
83 
90  boost::future<boost::uuids::uuid> add_entry_listener(entry_listener &&listener) {
91  return proxy::ReplicatedMapImpl::add_entry_listener(
92  std::shared_ptr<impl::BaseEventHandler>(
93  new EntryEventHandler<protocol::codec::replicatedmap_addentrylistener_handler>(get_name(), get_context().get_client_cluster_service(),
94  get_context().get_serialization_service(), std::move(listener), get_context().get_logger())));
95  }
96 
109  template<typename K>
110  typename std::enable_if<!std::is_base_of<query::predicate, K>::value, boost::future<boost::uuids::uuid>>::type
111  add_entry_listener(entry_listener &&listener, const K &key) {
112  return proxy::ReplicatedMapImpl::add_entry_listener_to_key(
113  std::shared_ptr<impl::BaseEventHandler>(
114  new EntryEventHandler<protocol::codec::replicatedmap_addentrylistenertokey_handler>(get_name(), get_context().get_client_cluster_service(),
115  get_context().get_serialization_service(), std::move(listener),
116  get_context().get_logger())), to_data(key));
117  }
118 
126  template<typename P>
127  typename std::enable_if<std::is_base_of<query::predicate, P>::value, boost::future<boost::uuids::uuid>>::type
128  add_entry_listener(entry_listener &&listener, const P &predicate) {
129  return proxy::ReplicatedMapImpl::add_entry_listener(
130  std::shared_ptr<impl::BaseEventHandler>(
131  new EntryEventHandler<protocol::codec::replicatedmap_addentrylistenerwithpredicate_handler>(get_name(), get_context().get_client_cluster_service(),
132  get_context().get_serialization_service(), std::move(listener),
133  get_context().get_logger())), to_data(predicate));
134  }
135 
144  template<typename K, typename P>
145  typename std::enable_if<std::is_base_of<query::predicate, P>::value, boost::future<boost::uuids::uuid>>::type
146  add_entry_listener(entry_listener &&listener, const P &predicate, const K &key) {
147  return proxy::ReplicatedMapImpl::add_entry_listener(
148  std::shared_ptr<impl::BaseEventHandler>(
149  new EntryEventHandler<protocol::codec::replicatedmap_addentrylistenertokeywithpredicate_handler>(get_name(), get_context().get_client_cluster_service(),
150  get_context().get_serialization_service(), std::move(listener),
151  get_context().get_logger())), to_data(key), to_data(predicate));
152  }
153 
167  template<typename V>
168  boost::future<std::vector<V>> values() {
169  return to_object_vector<V>(values_data());
170  }
171 
184  template<typename K, typename V>
185  boost::future<std::vector<std::pair<K, V>>> entry_set() {
186  return to_entry_object_vector<K,V>(entry_set_data());
187  }
188 
201  template<typename K>
202  boost::future<std::vector<K>> key_set() {
203  return to_object_vector<K>(key_set_data());
204  }
205 
211  template<typename K>
212  boost::future<bool> contains_key(const K &key) {
213  return contains_key_data(to_data(key));
214  }
215 
221  template<typename V>
222  boost::future<bool> contains_value(const V &value) {
223  return contains_value_data(to_data(value));
224  }
225 
231  template<typename K, typename V>
232  boost::future<boost::optional<V>> get(const K &key) {
233  return to_object<V>(get_data(to_data(key)));
234  }
235 
242  template<typename K, typename V, typename R = V>
243  boost::future<boost::optional<R>> put(const K &key, const V &value) {
244  return put<K, V, R>(key, value, std::chrono::milliseconds(0));
245  }
246 
252  template<typename K, typename V>
253  boost::future<boost::optional<V>> remove(const K &key) {
254  return to_object<V>(remove_data(to_data(key)));
255  }
256  private:
257  replicated_map(const std::string &object_name, spi::ClientContext *context) : proxy::ReplicatedMapImpl(
258  SERVICE_NAME, object_name, context) {
259  }
260 
261  template<typename HANDLER>
262  class EntryEventHandler : public HANDLER {
263  public:
264  EntryEventHandler(const std::string &instance_name,
265  spi::impl::ClientClusterServiceImpl &cluster_service,
266  serialization::pimpl::SerializationService &serialization_service,
267  entry_listener &&listener, logger &lg)
268  : instance_name_(instance_name), cluster_service_(cluster_service),
269  serialization_service_(serialization_service), listener_(std::move(listener)), logger_(lg) {}
270 
271  void handle_entry(const boost::optional<serialization::pimpl::data> &key,
272  const boost::optional<serialization::pimpl::data> &value,
273  const boost::optional<serialization::pimpl::data> &old_value,
274  const boost::optional<serialization::pimpl::data> &merging_value,
275  int32_t event_type, boost::uuids::uuid uuid,
276  int32_t number_of_affected_entries) override {
277  if (event_type == static_cast<int32_t>(entry_event::type::CLEAR_ALL)) {
278  fire_map_wide_event(key, value, old_value, merging_value, event_type, uuid,
279  number_of_affected_entries);
280  return;
281  }
282 
283  fire_entry_event(key, value, old_value, merging_value, event_type, uuid,
284  number_of_affected_entries);
285  }
286 
287  private:
288  void fire_map_wide_event(const boost::optional<serialization::pimpl::data> &key,
289  const boost::optional<serialization::pimpl::data> &value,
290  const boost::optional<serialization::pimpl::data> &old_value,
291  const boost::optional<serialization::pimpl::data> &merging_value,
292  int32_t event_type, boost::uuids::uuid uuid,
293  int32_t number_of_affected_entries) {
294  auto member = cluster_service_.get_member(uuid);
295  auto mapEventType = static_cast<entry_event::type>(event_type);
296  map_event mapEvent(std::move(member).value(), mapEventType, instance_name_,
297  number_of_affected_entries);
298  listener_.map_cleared_(std::move(mapEvent));
299  }
300 
301  void fire_entry_event(const boost::optional<serialization::pimpl::data> &key,
302  const boost::optional<serialization::pimpl::data> &value,
303  const boost::optional<serialization::pimpl::data> &old_value,
304  const boost::optional<serialization::pimpl::data> &merging_value,
305  int32_t event_type, boost::uuids::uuid uuid,
306  int32_t number_of_affected_entries) {
307  typed_data eventKey, val, oldVal, mergingVal;
308  if (value) {
309  val = typed_data(std::move(*value), serialization_service_);
310  }
311  if (old_value) {
312  oldVal = typed_data(std::move(*old_value), serialization_service_);
313  }
314  if (merging_value) {
315  mergingVal = typed_data(std::move(*merging_value), serialization_service_);
316  }
317  if (key) {
318  eventKey = typed_data(std::move(*key), serialization_service_);
319  }
320  auto m = cluster_service_.get_member(uuid);
321  if (!m.has_value()) {
322  m = member(uuid);
323  }
324  auto type = static_cast<entry_event::type>(event_type);
325  entry_event entryEvent(instance_name_, std::move(m.value()), type, std::move(eventKey), std::move(val),
326  std::move(oldVal), std::move(mergingVal));
327  switch(type) {
328  case entry_event::type::ADDED:
329  listener_.added_(std::move(entryEvent));
330  break;
331  case entry_event::type::REMOVED:
332  listener_.removed_(std::move(entryEvent));
333  break;
334  case entry_event::type::UPDATED:
335  listener_.updated_(std::move(entryEvent));
336  break;
337  case entry_event::type::EVICTED:
338  listener_.evicted_(std::move(entryEvent));
339  break;
340  default:
341  HZ_LOG(logger_, warning,
342  boost::str(boost::format("Received unrecognized event with type: %1% "
343  "Dropping the event!!!")
344  % static_cast<int>(type))
345  );
346  }
347  }
348  private:
349  const std::string& instance_name_;
350  spi::impl::ClientClusterServiceImpl &cluster_service_;
351  serialization::pimpl::SerializationService& serialization_service_;
352  entry_listener listener_;
353  logger &logger_;
354  };
355  };
356  }
357 }
358 
359 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
360 #pragma warning(pop)
361 #endif
Map entry listener to get notified when a map entry is added, removed, updated, evicted,...
std::enable_if< std::is_base_of< query::predicate, P >::value, boost::future< boost::uuids::uuid > >::type add_entry_listener(entry_listener &&listener, const P &predicate)
Adds an continuous entry listener for this map.
boost::future< boost::uuids::uuid > add_entry_listener(entry_listener &&listener)
Adds an entry listener for this map.
boost::future< void > put_all(const std::unordered_map< K, V > &entries)
Copies all of the mappings from the specified map to this map (optional operation).
boost::future< bool > contains_value(const V &value)
boost::future< std::vector< K > > key_set()
Returns a view of the keys contained in this map.
boost::future< std::vector< V > > values()
Due to the lazy nature of the returned array, changes to the map (addition, removal,...
boost::future< boost::optional< R > > put(const K &key, const V &value)
std::enable_if<!std::is_base_of< query::predicate, K >::value, boost::future< boost::uuids::uuid > >::type add_entry_listener(entry_listener &&listener, const K &key)
Adds the specified entry listener for the specified key.
boost::future< boost::optional< V > > get(const K &key)
boost::future< bool > contains_key(const K &key)
boost::future< boost::optional< V > > remove(const K &key)
boost::future< boost::optional< R > > put(const K &key, const V &value, std::chrono::milliseconds ttl)
std::enable_if< std::is_base_of< query::predicate, P >::value, boost::future< boost::uuids::uuid > >::type add_entry_listener(entry_listener &&listener, const P &predicate, const K &key)
Adds an continuous entry listener for this map.
boost::future< std::vector< std::pair< K, V > > > entry_set()
Returns a view of the mappings contained in this map.