Hazelcast C++ Client
Hazelcast C++ Client Library
Loading...
Searching...
No Matches
replicated_map.h
1/*
2 * Copyright (c) 2008-2025, 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/spi/impl/ClientClusterServiceImpl.h"
23#include "hazelcast/client/entry_listener.h"
24#include "hazelcast/client/entry_event.h"
25#include "hazelcast/client/map_event.h"
26#include "hazelcast/client/query/predicates.h"
27#include "hazelcast/logger.h"
28
29#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
30#pragma warning(push)
31#pragma warning(disable : 4251) // for dll export
32#endif
33
34namespace hazelcast {
35namespace client {
47class HAZELCAST_API replicated_map : public proxy::ReplicatedMapImpl
48{
49 friend class spi::ProxyManager;
50
51public:
52 static constexpr const char* SERVICE_NAME = "hz:impl:replicatedMapService";
67 template<typename K, typename V, typename R = V>
68 boost::future<boost::optional<R>> put(const K& key,
69 const V& value,
70 std::chrono::milliseconds ttl)
71 {
72 return to_object<R>(put_data(to_data(key), to_data(value), ttl));
73 }
74
85 template<typename K, typename V>
86 boost::future<void> put_all(const std::unordered_map<K, V>& entries)
87 {
88 return put_all_data(to_data_entries(entries));
89 }
90
97 boost::future<boost::uuids::uuid> add_entry_listener(
98 entry_listener&& listener)
99 {
100 return proxy::ReplicatedMapImpl::add_entry_listener(
101 std::shared_ptr<impl::BaseEventHandler>(
102 new EntryEventHandler<
103 protocol::codec::replicatedmap_addentrylistener_handler>(
104 get_name(),
105 get_context().get_client_cluster_service(),
106 get_context().get_serialization_service(),
107 std::move(listener),
108 get_context().get_logger())));
109 }
110
123 template<typename K>
124 typename std::enable_if<!std::is_base_of<query::predicate, K>::value,
125 boost::future<boost::uuids::uuid>>::type
126 add_entry_listener(entry_listener&& listener, const K& key)
127 {
128 return proxy::ReplicatedMapImpl::add_entry_listener_to_key(
129 std::shared_ptr<impl::BaseEventHandler>(
130 new EntryEventHandler<
131 protocol::codec::replicatedmap_addentrylistenertokey_handler>(
132 get_name(),
133 get_context().get_client_cluster_service(),
134 get_context().get_serialization_service(),
135 std::move(listener),
136 get_context().get_logger())),
137 to_data(key));
138 }
139
148 template<typename P>
149 typename std::enable_if<std::is_base_of<query::predicate, P>::value,
150 boost::future<boost::uuids::uuid>>::type
151 add_entry_listener(entry_listener&& listener, const P& predicate)
152 {
153 return proxy::ReplicatedMapImpl::add_entry_listener(
154 std::shared_ptr<impl::BaseEventHandler>(
155 new EntryEventHandler<
156 protocol::codec::
157 replicatedmap_addentrylistenerwithpredicate_handler>(
158 get_name(),
159 get_context().get_client_cluster_service(),
160 get_context().get_serialization_service(),
161 std::move(listener),
162 get_context().get_logger())),
163 to_data(predicate));
164 }
165
175 template<typename K, typename P>
176 typename std::enable_if<std::is_base_of<query::predicate, P>::value,
177 boost::future<boost::uuids::uuid>>::type
179 const P& predicate,
180 const K& key)
181 {
182 return proxy::ReplicatedMapImpl::add_entry_listener(
183 std::shared_ptr<impl::BaseEventHandler>(
184 new EntryEventHandler<
185 protocol::codec::
186 replicatedmap_addentrylistenertokeywithpredicate_handler>(
187 get_name(),
188 get_context().get_client_cluster_service(),
189 get_context().get_serialization_service(),
190 std::move(listener),
191 get_context().get_logger())),
192 to_data(key),
193 to_data(predicate));
194 }
195
210 template<typename V>
211 boost::future<std::vector<V>> values()
212 {
213 return to_object_vector<V>(values_data());
214 }
215
227 template<typename K, typename V>
228 boost::future<std::vector<std::pair<K, V>>> entry_set()
229 {
230 return to_entry_object_vector<K, V>(entry_set_data());
231 }
232
244 template<typename K>
245 boost::future<std::vector<K>> key_set()
246 {
247 return to_object_vector<K>(key_set_data());
248 }
249
255 template<typename K>
256 boost::future<bool> contains_key(const K& key)
257 {
258 return contains_key_data(to_data(key));
259 }
260
266 template<typename V>
267 boost::future<bool> contains_value(const V& value)
268 {
269 return contains_value_data(to_data(value));
270 }
271
277 template<typename K, typename V>
278 boost::future<boost::optional<V>> get(const K& key)
279 {
280 return to_object<V>(get_data(to_data(key)));
281 }
282
290 template<typename K, typename V, typename R = V>
291 boost::future<boost::optional<R>> put(const K& key, const V& value)
292 {
293 return put<K, V, R>(key, value, std::chrono::milliseconds(0));
294 }
295
301 template<typename K, typename V>
302 boost::future<boost::optional<V>> remove(const K& key)
303 {
304 return to_object<V>(remove_data(to_data(key)));
305 }
306
307private:
308 replicated_map(const std::string& object_name, spi::ClientContext* context)
309 : proxy::ReplicatedMapImpl(SERVICE_NAME, object_name, context)
310 {}
311
312 template<typename HANDLER>
313 class EntryEventHandler : public HANDLER
314 {
315 public:
316 EntryEventHandler(
317 const std::string& instance_name,
318 spi::impl::ClientClusterServiceImpl& cluster_service,
319 serialization::pimpl::SerializationService& serialization_service,
320 entry_listener&& listener,
321 logger& lg)
322 : HANDLER(lg)
323 , instance_name_(instance_name)
324 , cluster_service_(cluster_service)
325 , serialization_service_(serialization_service)
326 , listener_(std::move(listener))
327 , logger_(lg)
328 {}
329
330 void handle_entry(
331 const boost::optional<serialization::pimpl::data>& key,
332 const boost::optional<serialization::pimpl::data>& value,
333 const boost::optional<serialization::pimpl::data>& old_value,
334 const boost::optional<serialization::pimpl::data>& merging_value,
335 int32_t event_type,
336 boost::uuids::uuid uuid,
337 int32_t number_of_affected_entries) override
338 {
339 if (event_type ==
340 static_cast<int32_t>(entry_event::type::CLEAR_ALL)) {
341 fire_map_wide_event(key,
342 value,
343 old_value,
344 merging_value,
345 event_type,
346 uuid,
347 number_of_affected_entries);
348 return;
349 }
350
351 fire_entry_event(key,
352 value,
353 old_value,
354 merging_value,
355 event_type,
356 uuid,
357 number_of_affected_entries);
358 }
359
360 private:
361 void fire_map_wide_event(
362 const boost::optional<serialization::pimpl::data>& /* key */,
363 const boost::optional<serialization::pimpl::data>& /* value */,
364 const boost::optional<serialization::pimpl::data>& /* old_value */,
365 const boost::optional<serialization::pimpl::data>& /* merging_value */,
366 int32_t event_type,
367 boost::uuids::uuid uuid,
368 int32_t number_of_affected_entries)
369 {
370 auto member = cluster_service_.get_member(uuid);
371 auto mapEventType = static_cast<entry_event::type>(event_type);
372 map_event mapEvent(std::move(member).value(),
373 mapEventType,
374 instance_name_,
375 number_of_affected_entries);
376 listener_.map_cleared_(std::move(mapEvent));
377 }
378
379 void fire_entry_event(
380 const boost::optional<serialization::pimpl::data>& key,
381 const boost::optional<serialization::pimpl::data>& value,
382 const boost::optional<serialization::pimpl::data>& old_value,
383 const boost::optional<serialization::pimpl::data>& merging_value,
384 int32_t event_type,
385 boost::uuids::uuid uuid,
386 int32_t /* number_of_affected_entries */)
387 {
388 typed_data eventKey, val, oldVal, mergingVal;
389 if (value) {
390 val = typed_data(std::move(*value), serialization_service_);
391 }
392 if (old_value) {
393 oldVal =
394 typed_data(std::move(*old_value), serialization_service_);
395 }
396 if (merging_value) {
397 mergingVal =
398 typed_data(std::move(*merging_value), serialization_service_);
399 }
400 if (key) {
401 eventKey = typed_data(std::move(*key), serialization_service_);
402 }
403 auto m = cluster_service_.get_member(uuid);
404 if (!m.has_value()) {
405 m = member(uuid);
406 }
407 auto type = static_cast<entry_event::type>(event_type);
408 entry_event entryEvent(instance_name_,
409 std::move(m.value()),
410 type,
411 std::move(eventKey),
412 std::move(val),
413 std::move(oldVal),
414 std::move(mergingVal));
415 switch (type) {
416 case entry_event::type::ADDED:
417 listener_.added_(std::move(entryEvent));
418 break;
419 case entry_event::type::REMOVED:
420 listener_.removed_(std::move(entryEvent));
421 break;
422 case entry_event::type::UPDATED:
423 listener_.updated_(std::move(entryEvent));
424 break;
425 case entry_event::type::EVICTED:
426 listener_.evicted_(std::move(entryEvent));
427 break;
428 default:
429 HZ_LOG(
430 logger_,
431 warning,
432 boost::str(boost::format(
433 "Received unrecognized event with type: %1% "
434 "Dropping the event!!!") %
435 static_cast<int>(type)));
436 }
437 }
438
439 private:
440 const std::string& instance_name_;
441 spi::impl::ClientClusterServiceImpl& cluster_service_;
442 serialization::pimpl::SerializationService& serialization_service_;
443 entry_listener listener_;
444 logger& logger_;
445 };
446};
447} // namespace client
448} // namespace hazelcast
449
450#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
451#pragma warning(pop)
452#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, const K &key)
Adds an continuous 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< std::vector< V > > values()
Due to the lazy nature of the returned array, changes to the map (addition, removal,...
boost::future< boost::optional< V > > remove(const K &key)
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::optional< R > > put(const K &key, const V &value)
boost::future< bool > contains_value(const V &value)
boost::future< boost::optional< V > > get(const K &key)
boost::future< boost::optional< R > > put(const K &key, const V &value, std::chrono::milliseconds ttl)
boost::future< bool > contains_key(const K &key)
boost::future< std::vector< K > > key_set()
Returns a view of the keys contained in this map.
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::uuids::uuid > add_entry_listener(entry_listener &&listener)
Adds an 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.
STL namespace.