Hazelcast C++ Client
Hazelcast C++ Client Library
imap.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 <unordered_map>
20 #include <unordered_set>
21 #include <vector>
22 #include <stdexcept>
23 #include <climits>
24 #include <assert.h>
25 
26 #include <boost/container/vector.hpp>
27 
28 #include "hazelcast/client/monitor/local_map_stats.h"
29 #include "hazelcast/client/monitor/impl/NearCacheStatsImpl.h"
30 #include "hazelcast/client/monitor/impl/LocalMapStatsImpl.h"
31 #include "hazelcast/client/proxy/IMapImpl.h"
32 #include "hazelcast/client/impl/EntryEventHandler.h"
33 #include "hazelcast/client/entry_listener.h"
34 #include "hazelcast/client/entry_view.h"
35 #include "hazelcast/client/serialization/serialization.h"
36 #include "hazelcast/util/exception_util.h"
37 #include "hazelcast/client/protocol/codec/codecs.h"
38 #include "hazelcast/client/spi/ClientContext.h"
39 
40 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
41 #pragma warning(push)
42 #pragma warning(disable: 4251) //for dll export
43 #endif
44 
45 namespace hazelcast {
46  namespace client {
47  class hazelcast_client;
48 
49  namespace spi {
50  class ProxyManager;
51  }
52 
63  class HAZELCAST_API imap : public proxy::IMapImpl {
64  friend class spi::ProxyManager;
65  public:
66  static constexpr const char *SERVICE_NAME = "hz:impl:mapService";
67 
68  imap(const std::string &instance_name, spi::ClientContext *context) : proxy::IMapImpl(instance_name,
69  context) {}
70 
76  template<typename K>
77  boost::future<bool> contains_key(const K &key) {
78  return contains_key_internal(to_data(key));
79  }
80 
86  template<typename V>
87  boost::future<bool> contains_value(const V &value) {
88  return proxy::IMapImpl::contains_value(to_data(value));
89  }
90 
96  template<typename K, typename V>
97  boost::future<boost::optional<V>> get(const K &key) {
98  return to_object<V>(get_internal(to_data(key)));
99  }
100 
107  template<typename K, typename V, typename R=V>
108  boost::future<boost::optional<R>> put(const K &key, const V &value) {
109  return put<K, V, R>(key, value, UNSET);
110  }
111 
122  template<typename K, typename V, typename R=V>
123  boost::future<boost::optional<R>> put(const K &key, const V &value, std::chrono::milliseconds ttl) {
124  return to_object<R>(put_internal(to_data(key), to_data(value), ttl));
125  }
126 
132  template<typename K, typename V>
133  boost::future<boost::optional<V>> remove(const K &key) {
134  return to_object<V>(remove_internal(to_data(key)));
135  }
136 
143  template<typename K, typename V>
144  boost::future<bool> remove(const K &key, const V &value) {
145  return remove_internal(to_data(key), to_data(value));
146  }
147 
157  template <typename P>
158  boost::future<void> remove_all(const P &predicate) {
159  return to_void_future(remove_all_internal(to_data<P>(predicate)));
160  }
161 
167  template <typename K>
168  boost::future<void> delete_entry(const K &key) {
169  return to_void_future(delete_internal(to_data(key)));
170  }
171 
181  template<typename K>
182  boost::future<bool> try_remove(const K &key, std::chrono::milliseconds timeout) {
183  return try_remove_internal(to_data(key), timeout);
184  }
185 
198  template<typename K, typename V>
199  boost::future<bool> try_put(const K &key, const V &value, std::chrono::milliseconds timeout) {
200  return try_put_internal(to_data(key), to_data(value), timeout);
201  }
202 
212  template<typename K, typename V>
213  boost::future<void> put_transient(const K &key, const V &value, std::chrono::milliseconds ttl) {
214  return to_void_future(try_put_transient_internal(to_data(key), to_data(value), ttl));
215  }
216 
225  template<typename K, typename V, typename R=V>
226  boost::future<boost::optional<V>> put_if_absent(const K &key, const V &value) {
227  return put_if_absent(key, value, UNSET);
228  }
229 
241  template<typename K, typename V, typename R=V>
242  boost::future<boost::optional<V>> put_if_absent(const K &key, const V &value, std::chrono::milliseconds ttl) {
243  return to_object<R>(put_if_absent_internal(to_data(key), to_data(value), ttl));
244  }
245 
253  template<typename K, typename V, typename N = V>
254  boost::future<bool> replace(const K &key, const V &old_value, const N &new_value) {
255  return replace_if_same_internal(to_data(key), to_data(old_value), to_data(new_value));
256  }
257 
265  template<typename K, typename V, typename R=V>
266  boost::future<boost::optional<R>> replace(const K &key, const V &value) {
267  return to_object<R>(replace_internal(to_data(key), to_data(value)));
268  }
269 
277  template<typename K, typename V, typename R=V>
278  boost::future<void> set(const K &key, const V &value) {
279  return to_void_future(set(key, value, UNSET));
280  }
281 
291  template<typename K, typename V>
292  boost::future<void> set(const K &key, const V &value, std::chrono::milliseconds ttl) {
293  return to_void_future(set_internal(to_data(key), to_data(value), ttl));
294  }
295 
310  template<typename K>
311  boost::future<void> lock(const K &key) {
312  return to_void_future(lock(key, UNSET));
313  }
314 
333  template<typename K>
334  boost::future<void> lock(const K &key, std::chrono::milliseconds lease_time) {
335  return to_void_future(proxy::IMapImpl::lock(to_data(key), lease_time));
336  }
337 
346  template<typename K>
347  boost::future<bool> is_locked(const K &key) {
348  return proxy::IMapImpl::is_locked(to_data(key));
349  }
350 
360  template<typename K>
361  boost::future<bool> try_lock(const K &key) {
362  return try_lock(key, std::chrono::milliseconds(0));
363  }
364 
381  template<typename K>
382  boost::future<bool> try_lock(const K &key, std::chrono::milliseconds timeout) {
383  return proxy::IMapImpl::try_lock(to_data(key), timeout);
384  }
385 
386 
405  template <typename K>
406  boost::future<bool> try_lock(const K &key, std::chrono::milliseconds timeout, std::chrono::milliseconds lease_time) {
407  return proxy::IMapImpl::try_lock(to_data(key), timeout, lease_time);
408  }
409 
423  template<typename K>
424  boost::future<void> unlock(const K &key) {
425  return to_void_future(proxy::IMapImpl::unlock(to_data(key)));
426  }
427 
436  template<typename K>
437  boost::future<void> force_unlock(const K &key) {
438  return to_void_future(proxy::IMapImpl::force_unlock(to_data(key)));
439  }
440 
452  template<typename MapInterceptor>
453  boost::future<std::string> add_interceptor(const MapInterceptor &interceptor) {
454  return proxy::IMapImpl::add_interceptor(to_data(interceptor));
455  }
456 
471  boost::future<boost::uuids::uuid> add_entry_listener(entry_listener &&listener, bool include_value) {
472  const auto listener_flags = listener.flags_;
473  return proxy::IMapImpl::add_entry_listener(
474  std::unique_ptr<impl::BaseEventHandler>(
475  new impl::EntryEventHandler<protocol::codec::map_addentrylistener_handler>(
476  get_name(), get_context().get_client_cluster_service(),
477  get_context().get_serialization_service(),
478  std::move(listener),
479  include_value, get_context().get_logger())), include_value, listener_flags);
480  }
481 
497  template<typename P>
498  boost::future<boost::uuids::uuid>
499  add_entry_listener(entry_listener &&listener, const P &predicate, bool include_value) {
500  const auto listener_flags = listener.flags_;
501  return proxy::IMapImpl::add_entry_listener(
502  std::unique_ptr<impl::BaseEventHandler>(
503  new impl::EntryEventHandler<protocol::codec::map_addentrylistenerwithpredicate_handler>(
504  get_name(), get_context().get_client_cluster_service(),
505  get_context().get_serialization_service(),
506  std::move(listener),
507  include_value, get_context().get_logger())), to_data<P>(predicate), include_value, listener_flags);
508  }
509 
523  template<typename K>
524  boost::future<boost::uuids::uuid> add_entry_listener(entry_listener &&listener, bool include_value, const K &key) {
525  const auto listener_flags = listener.flags_;
526  return proxy::IMapImpl::add_entry_listener(
527  std::shared_ptr<impl::BaseEventHandler>(
528  new impl::EntryEventHandler<protocol::codec::map_addentrylistenertokey_handler>(
529  get_name(), get_context().get_client_cluster_service(),
530  get_context().get_serialization_service(),
531  std::move(listener),
532  include_value, get_context().get_logger())), include_value, to_data<K>(key), listener_flags);
533  }
534 
543  template<typename K, typename V>
544  boost::future<boost::optional<entry_view<K, V>>> get_entry_view(const K &key) {
545  return proxy::IMapImpl::get_entry_view_data(to_data(key)).then([=] (boost::future<boost::optional<map::data_entry_view>> f) {
546  auto dataView = f.get();
547  if (!dataView) {
548  return boost::optional<entry_view<K, V>>();
549  }
550  auto v = to_object<V>(dataView->get_value());
551  return boost::make_optional(entry_view<K, V>(key, std::move(v).value(), *std::move(dataView)));
552  });
553  }
554 
565  template<typename K>
566  boost::future<bool> evict(const K &key) {
567  return evict_internal(to_data(key));
568  }
569 
576  template<typename K, typename V>
577  boost::future<std::unordered_map<K, V>> get_all(const std::unordered_set<K> &keys) {
578  if (keys.empty()) {
579  return boost::make_ready_future(std::unordered_map<K, V>());
580  }
581 
582  std::unordered_map<int, std::vector<serialization::pimpl::data>> partition_to_key_data;
583  // group the request per server
584  for (auto &key : keys) {
585  auto key_data = to_data<K>(key);
586 
587  auto partitionId = get_partition_id(key_data);
588  partition_to_key_data[partitionId].push_back(std::move(key_data));
589  }
590 
591  std::vector<boost::future<EntryVector>> futures;
592  futures.reserve(partition_to_key_data.size());
593  for (auto &entry : partition_to_key_data) {
594  futures.push_back(get_all_internal(entry.first, entry.second));
595  }
596 
597  return boost::when_all(futures.begin(), futures.end()).then(boost::launch::sync,
598  [=](boost::future<boost::csbl::vector<boost::future<EntryVector>>> results_data) {
599  std::unordered_map<K, V> result;
600  for (auto &entryVectorFuture : results_data.get()) {
601  for (auto &entry : entryVectorFuture.get()) {
602  auto val = to_object<V>(
603  entry.second);
604  // it is guaranteed that all values are non-null
605  assert(val.has_value());
606  result[to_object<K>(
607  entry.first).value()] = std::move(
608  val.value());
609  }
610  }
611  return result;
612  });
613  }
614 
622  template<typename K>
623  boost::future<std::vector<K>> key_set() {
624  return to_object_vector<K>(proxy::IMapImpl::key_set_data());
625  }
626 
638  template<typename K, typename P, class = typename std::enable_if<!std::is_base_of<query::paging_predicate_marker, P>::value>::type>
639  boost::future<std::vector<K>> key_set(const P &predicate) {
640  return to_object_vector<K>(proxy::IMapImpl::key_set_data(to_data(predicate)));
641  }
642 
654  template<typename K, typename V>
655  boost::future<std::vector<K>> key_set(query::paging_predicate<K, V> &predicate) {
656  predicate.set_iteration_type(query::iteration_type::KEY);
657  return key_set_for_paging_predicate_data(
658  protocol::codec::holder::paging_predicate_holder::of(predicate, serialization_service_)).then(
659  [=, &predicate](
660  boost::future<std::pair<std::vector<serialization::pimpl::data>, query::anchor_data_list>> f) {
661  auto result = f.get();
662  predicate.set_anchor_data_list(std::move(result.second));
663  const auto &entries = result.first;
664  std::vector<K> values;
665  values.reserve(entries.size());
666  for(const auto &e : entries) {
667  values.emplace_back(*to_object<K>(e));
668  }
669  return values;
670  });
671  }
672 
680  template<typename V>
681  boost::future<std::vector<V>> values() {
682  return to_object_vector<V>(proxy::IMapImpl::values_data());
683  }
684 
693  template<typename V, typename P, class = typename std::enable_if<!std::is_base_of<query::paging_predicate_marker, P>::value>::type>
694  boost::future<std::vector<V>> values(const P &predicate) {
695  return to_object_vector<V>(proxy::IMapImpl::values_data(to_data(predicate)));
696  }
697 
707  template<typename K, typename V>
708  boost::future<std::vector<V>> values(query::paging_predicate<K, V> &predicate) {
709  predicate.set_iteration_type(query::iteration_type::VALUE);
710  return values_for_paging_predicate_data(
711  protocol::codec::holder::paging_predicate_holder::of(predicate, serialization_service_)).then(
712  [=, &predicate](boost::future<std::pair<std::vector<serialization::pimpl::data>, query::anchor_data_list>> f) {
713  auto result = f.get();
714  predicate.set_anchor_data_list(std::move(result.second));
715  const auto &entries = result.first;
716  std::vector<V> values;
717  values.reserve(entries.size());
718  for(const auto &e : entries) {
719  values.emplace_back(*to_object<V>(e));
720  }
721  return values;
722  });
723  }
724 
732  template<typename K, typename V>
733  boost::future<std::vector<std::pair<K, V>>> entry_set() {
734  return to_entry_object_vector<K,V>(proxy::IMapImpl::entry_set_data());
735  }
736 
747  template<typename K, typename V, typename P, class = typename std::enable_if<!std::is_base_of<query::paging_predicate_marker, P>::value>::type>
748  boost::future<std::vector<std::pair<K, V>>> entry_set(const P &predicate) {
749  return to_entry_object_vector<K,V>(proxy::IMapImpl::entry_set_data(to_data(predicate)));
750  }
751 
762  template<typename K, typename V>
763  boost::future<std::vector<std::pair<K, V>>> entry_set(query::paging_predicate<K, V> &predicate) {
764  predicate.set_iteration_type(query::iteration_type::ENTRY);
765  return entry_set_for_paging_predicate_data(
766  protocol::codec::holder::paging_predicate_holder::of(predicate, serialization_service_)).then(
767  [=, &predicate](boost::future<std::pair<EntryVector, query::anchor_data_list>> f) {
768  auto result = f.get();
769  predicate.set_anchor_data_list(std::move(result.second));
770  const auto &entries_data = result.first;
771  std::vector<std::pair<K, V>> entries;
772  entries.reserve(entries_data.size());
773  for(const auto &e : entries_data) {
774  entries.emplace_back(*to_object<K>(e.first), *to_object<V>(e.second));
775  }
776  return entries;
777  });
778  }
779 
819  boost::future<void> add_index(const config::index_config &config) {
820  return to_void_future(proxy::IMapImpl::add_index_data(config));
821  }
822 
831  template<typename ...T>
832  boost::future<void> add_index(config::index_config::index_type type, T... attributes) {
833  return add_index(config::index_config(type, std::forward<T>(attributes)...));
834  }
835 
836  boost::future<void> clear() {
837  return to_void_future(proxy::IMapImpl::clear_data());
838  }
839 
854  template<typename K, typename ResultType, typename EntryProcessor>
855  boost::future<boost::optional<ResultType>> execute_on_key(const K &key, const EntryProcessor &entry_processor) {
856  return to_object<ResultType>(execute_on_key_internal(to_data(key), to_data(entry_processor)));
857  }
858 
859 
869  template<typename K, typename ResultType, typename EntryProcessor>
870  boost::future<boost::optional<ResultType>>
871  submit_to_key(const K &key, const EntryProcessor &entry_processor) {
872  return to_object<ResultType>(submit_to_key_internal(to_data(key), to_data(entry_processor)));
873  }
874 
887  template<typename K, typename ResultType, typename EntryProcessor>
888  boost::future<std::unordered_map<K, boost::optional<ResultType>>>
889  execute_on_keys(const std::unordered_set<K> &keys, const EntryProcessor &entry_processor) {
890  return to_object_map<K, ResultType>(execute_on_keys_internal<K, EntryProcessor>(keys, entry_processor));
891  }
892 
906  template<typename K, typename ResultType, typename EntryProcessor>
907  boost::future<std::unordered_map<K, boost::optional<ResultType>>> execute_on_entries(const EntryProcessor &entry_processor) {
908  return to_object_map<K, ResultType>(proxy::IMapImpl::execute_on_entries_data(to_data(entry_processor)));
909  }
910 
925  template<typename K, typename ResultType, typename EntryProcessor, typename P>
926  boost::future<std::unordered_map<K, boost::optional<ResultType>>>
927  execute_on_entries(const EntryProcessor &entry_processor, const P &predicate) {
928  return to_object_map<K, ResultType>(proxy::IMapImpl::execute_on_entries_data(to_data(entry_processor),
929  to_data(predicate)));
930  }
931 
942  template<typename K, typename V>
943  boost::future<void> put_all(const std::unordered_map<K, V> &entries) {
944  std::unordered_map<int, EntryVector> entryMap;
945  for (auto &entry : entries) {
946  serialization::pimpl::data key_data = to_data(entry.first);
947  int partitionId = get_partition_id(key_data);
948  entryMap[partitionId].push_back(std::make_pair(key_data, to_data(entry.second)));
949  }
950 
951  std::vector<boost::future<protocol::ClientMessage>> resultFutures;
952  for (auto &&partitionEntry : entryMap) {
953  auto partitionId = partitionEntry.first;
954  resultFutures.push_back(put_all_internal(partitionId, std::move(partitionEntry.second)));
955  }
956  return boost::when_all(resultFutures.begin(), resultFutures.end()).then(boost::launch::sync,
957  [](boost::future<boost::csbl::vector<boost::future<protocol::ClientMessage>>> futures) {
958  for (auto &f : futures.get()) {
959  f.get();
960  }
961  });
962  }
963 
977  return local_map_stats_;
978  }
979 
980  template<typename K, typename V>
981  query::paging_predicate<K, V> new_paging_predicate(size_t predicate_page_size) {
982  return query::paging_predicate<K, V>(get_serialization_service(), predicate_page_size);
983  }
984 
985  template<typename K, typename V, typename INNER_PREDICATE>
986  query::paging_predicate<K, V> new_paging_predicate(size_t predicate_page_size, const INNER_PREDICATE &predicate) {
987  return query::paging_predicate<K, V>(get_serialization_service(), predicate_page_size, predicate);
988  }
989 
990  template<typename K, typename V, typename COMPARATOR>
991  query::paging_predicate<K, V> new_paging_predicate(COMPARATOR &&comparator, size_t predicate_page_size) {
992  return query::paging_predicate<K, V>(get_serialization_service(), std::move(comparator), predicate_page_size);
993  }
994 
995  template<typename K, typename V, typename INNER_PREDICATE, typename COMPARATOR>
996  query::paging_predicate<K, V> new_paging_predicate(const INNER_PREDICATE &predicate, COMPARATOR &&comparator, size_t predicate_page_size) {
997  return query::paging_predicate<K, V>(get_serialization_service(), predicate, std::move(comparator), predicate_page_size);
998  }
999 
1000  protected:
1004  static constexpr std::chrono::milliseconds UNSET{-1};
1005 
1006  monitor::impl::LocalMapStatsImpl local_map_stats_;
1007 
1008  virtual boost::future<boost::optional<serialization::pimpl::data>> get_internal(const serialization::pimpl::data &key_data) {
1009  return proxy::IMapImpl::get_data(key_data);
1010  }
1011 
1012  virtual boost::future<bool> contains_key_internal(const serialization::pimpl::data &key_data) {
1013  return proxy::IMapImpl::contains_key(key_data);
1014  }
1015 
1016  virtual boost::future<boost::optional<serialization::pimpl::data>> remove_internal(
1017  const serialization::pimpl::data &key_data) {
1018  return proxy::IMapImpl::remove_data(key_data);
1019  }
1020 
1021  virtual boost::future<bool> remove_internal(
1022  const serialization::pimpl::data &key_data, const serialization::pimpl::data &value_data) {
1023  return proxy::IMapImpl::remove(key_data, value_data);
1024  }
1025 
1026  virtual boost::future<protocol::ClientMessage> remove_all_internal(const serialization::pimpl::data &predicate_data) {
1027  return proxy::IMapImpl::remove_all(predicate_data);
1028  }
1029 
1030  virtual boost::future<protocol::ClientMessage> delete_internal(const serialization::pimpl::data &key_data) {
1031  return proxy::IMapImpl::delete_entry(key_data);
1032  }
1033 
1034  virtual boost::future<bool> try_remove_internal(const serialization::pimpl::data &key_data, std::chrono::milliseconds timeout) {
1035  return proxy::IMapImpl::try_remove(key_data, timeout);
1036  }
1037 
1038  virtual boost::future<bool> try_put_internal(const serialization::pimpl::data &key_data,
1039  const serialization::pimpl::data &value_data, std::chrono::milliseconds timeout) {
1040  return proxy::IMapImpl::try_put(key_data, value_data, timeout);
1041  }
1042 
1043  virtual boost::future<boost::optional<serialization::pimpl::data>> put_internal(const serialization::pimpl::data &key_data,
1044  const serialization::pimpl::data &value_data,
1045  std::chrono::milliseconds ttl) {
1046  return proxy::IMapImpl::put_data(key_data, value_data, ttl);
1047  }
1048 
1049  virtual boost::future<protocol::ClientMessage> try_put_transient_internal(const serialization::pimpl::data &key_data,
1050  const serialization::pimpl::data &value_data, std::chrono::milliseconds ttl) {
1051  return proxy::IMapImpl::put_transient(key_data, value_data, ttl);
1052  }
1053 
1054  virtual boost::future<boost::optional<serialization::pimpl::data>>
1055  put_if_absent_internal(const serialization::pimpl::data &key_data,
1056  const serialization::pimpl::data &value_data,
1057  std::chrono::milliseconds ttl) {
1058  return proxy::IMapImpl::put_if_absent_data(key_data, value_data, ttl);
1059  }
1060 
1061  virtual boost::future<bool> replace_if_same_internal(const serialization::pimpl::data &key_data,
1062  const serialization::pimpl::data &value_data,
1063  const serialization::pimpl::data &new_value_data) {
1064  return proxy::IMapImpl::replace(key_data, value_data, new_value_data);
1065  }
1066 
1067  virtual boost::future<boost::optional<serialization::pimpl::data>>
1068  replace_internal(const serialization::pimpl::data &key_data,
1069  const serialization::pimpl::data &value_data) {
1070  return proxy::IMapImpl::replace_data(key_data, value_data);
1071  }
1072 
1073  virtual boost::future<protocol::ClientMessage>
1074  set_internal(const serialization::pimpl::data &key_data, const serialization::pimpl::data &value_data,
1075  std::chrono::milliseconds ttl) {
1076  return proxy::IMapImpl::set(key_data, value_data, ttl);
1077  }
1078 
1079  virtual boost::future<bool> evict_internal(const serialization::pimpl::data &key_data) {
1080  return proxy::IMapImpl::evict(key_data);
1081  }
1082 
1083  virtual boost::future<EntryVector>
1084  get_all_internal(int partition_id, const std::vector<serialization::pimpl::data> &partition_keys) {
1085  return proxy::IMapImpl::get_all_data(partition_id, partition_keys);
1086  }
1087 
1088  virtual boost::future<boost::optional<serialization::pimpl::data>>
1089  execute_on_key_internal(const serialization::pimpl::data &key_data,
1090  const serialization::pimpl::data &processor) {
1091  return proxy::IMapImpl::execute_on_key_data(key_data, processor);
1092  }
1093 
1094  boost::future<boost::optional<serialization::pimpl::data>>
1095  submit_to_key_internal(const serialization::pimpl::data &key_data,
1096  const serialization::pimpl::data &processor) {
1097  return submit_to_key_data(key_data, processor);
1098  }
1099 
1100  template<typename K, typename EntryProcessor>
1101  boost::future<EntryVector> execute_on_keys_internal(const std::unordered_set<K> &keys, const EntryProcessor &entry_processor) {
1102  if (keys.empty()) {
1103  return boost::make_ready_future(EntryVector());
1104  }
1105  std::vector<serialization::pimpl::data> keysData;
1106  for (const auto &k : keys) {
1107  keysData.push_back(to_data<K>(k));
1108  }
1109  return proxy::IMapImpl::execute_on_keys_data(keysData, to_data<EntryProcessor>(entry_processor));
1110  }
1111 
1112  virtual boost::future<protocol::ClientMessage>
1113  put_all_internal(int partition_id, const EntryVector &entries) {
1114  return proxy::IMapImpl::put_all_data(partition_id, entries);
1115  }
1116 
1117  private:
1118 
1119  template<typename K, typename V>
1120  std::vector<std::pair<K, boost::optional<V>>> sort_and_get(query::paging_predicate<K, V> &predicate, query::iteration_type iteration_type, std::vector<std::pair<K, V>> entries) {
1121  std::vector<std::pair<K, boost::optional<V>>> optionalEntries;
1122  optionalEntries.reserve(entries.size());
1123  for(auto &&pair : entries) {
1124  optionalEntries.emplace_back(pair.first, boost::make_optional(pair.second));
1125  }
1126  return sortAndGet(predicate, iteration_type, optionalEntries);
1127  }
1128 
1129  template<typename K, typename V>
1130  std::vector<std::pair<K, boost::optional<V>>> sort_and_get(query::paging_predicate<K, V> &predicate, query::iteration_type iteration_type, std::vector<std::pair<K, boost::optional<V>>> entries) {
1131  std::sort(entries.begin(), entries.end(), [&] (const std::pair<K, boost::optional<V>> &lhs, const std::pair<K, boost::optional<V>> &rhs) {
1132  auto comparator = predicate.getComparator();
1133  if (!comparator) {
1134  switch(predicate.getIterationType()) {
1135  case query::iteration_type::VALUE:
1136  return lhs.second < rhs.second;
1137  default:
1138  return lhs.first < rhs.first;
1139  }
1140  }
1141 
1142  std::pair<const K *, const V *> leftVal(&lhs.first, lhs.second.get_ptr());
1143  std::pair<const K *, const V *> rightVal(&rhs.first, rhs.second.get_ptr());
1144  int result = comparator->compare(&leftVal, &rightVal);
1145  if (0 != result) {
1146  // std sort: comparison function object returns ​true if the first argument is less
1147  // than (i.e. is ordered before) the second.
1148  return result < 0;
1149  }
1150 
1151  return lhs.first < rhs.first;
1152  });
1153 
1154  std::pair<size_t, size_t> range = update_anchor<K, V>(entries, predicate, iteration_type);
1155 
1156  std::vector<std::pair<K, boost::optional<V>>> result;
1157  for (size_t i = range.first; i < range.second; ++i) {
1158  auto entry = entries[i];
1159  result.push_back(std::make_pair(entry.first, entry.second));
1160  }
1161  return result;
1162  }
1163  };
1164  }
1165 }
1166 
1167 #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
1168 #pragma warning(pop)
1169 #endif
Map entry listener to get notified when a map entry is added, removed, updated, evicted,...
EntryView represents a readonly view of a map entry.
Definition: entry_view.h:32
Concurrent, distributed, observable and queryable map client.
Definition: imap.h:63
boost::future< std::vector< std::pair< K, V > > > entry_set()
Returns a std::vector< std::pair<K, V> > clone of the mappings contained in this map.
Definition: imap.h:733
boost::future< boost::optional< V > > put_if_absent(const K &key, const V &value, std::chrono::milliseconds ttl)
Puts an entry into this map with a given ttl (time to live) value if the specified key is not already...
Definition: imap.h:242
boost::future< void > lock(const K &key, std::chrono::milliseconds lease_time)
Acquires the lock for the specified key for the specified lease time.
Definition: imap.h:334
boost::future< bool > try_lock(const K &key, std::chrono::milliseconds timeout, std::chrono::milliseconds lease_time)
Tries to acquire the lock for the specified key for the specified lease time.
Definition: imap.h:406
boost::future< boost::uuids::uuid > add_entry_listener(entry_listener &&listener, bool include_value)
Adds an entry listener for this map.
Definition: imap.h:471
boost::future< bool > remove(const K &key, const V &value)
removes entry from map if there is an entry with same key and value.
Definition: imap.h:144
boost::future< boost::uuids::uuid > add_entry_listener(entry_listener &&listener, bool include_value, const K &key)
Adds the specified entry listener for the specified key.
Definition: imap.h:524
boost::future< boost::optional< V > > get(const K &key)
get the value.
Definition: imap.h:97
boost::future< std::vector< std::pair< K, V > > > entry_set(const P &predicate)
Queries the map based on the specified predicate and returns the matching entries.
Definition: imap.h:748
boost::future< void > remove_all(const P &predicate)
Removes all entries which match with the supplied predicate.
Definition: imap.h:158
boost::future< boost::optional< R > > replace(const K &key, const V &value)
Replaces the entry for a key only if currently mapped to some value.
Definition: imap.h:266
boost::future< std::vector< V > > values(const P &predicate)
Returns a vector clone of the values contained in this map.
Definition: imap.h:694
boost::future< boost::optional< ResultType > > submit_to_key(const K &key, const EntryProcessor &entry_processor)
Applies the user defined EntryProcessor to the entry mapped by the key.
Definition: imap.h:871
boost::future< boost::optional< R > > put(const K &key, const V &value)
put new entry into map.
Definition: imap.h:108
boost::future< boost::optional< V > > remove(const K &key)
remove entry form map
Definition: imap.h:133
boost::future< void > set(const K &key, const V &value)
Puts an entry into this map.
Definition: imap.h:278
boost::future< std::unordered_map< K, boost::optional< ResultType > > > execute_on_entries(const EntryProcessor &entry_processor, const P &predicate)
Applies the user defined EntryProcessor to the all entries in the map.
Definition: imap.h:927
boost::future< std::unordered_map< K, V > > get_all(const std::unordered_set< K > &keys)
Returns the entries for the given keys.
Definition: imap.h:577
boost::future< void > add_index(config::index_config::index_type type, T... attributes)
Convenient method to add an index to this map with the given type and attributes.
Definition: imap.h:832
boost::future< std::vector< std::pair< K, V > > > entry_set(query::paging_predicate< K, V > &predicate)
Queries the map based on the specified predicate and returns the matching entries.
Definition: imap.h:763
boost::future< bool > replace(const K &key, const V &old_value, const N &new_value)
Replaces the entry for a key only if currently mapped to a given value.
Definition: imap.h:254
boost::future< void > force_unlock(const K &key)
Releases the lock for the specified key regardless of the lock owner.
Definition: imap.h:437
boost::future< boost::uuids::uuid > add_entry_listener(entry_listener &&listener, const P &predicate, bool include_value)
Adds an entry listener for this map.
Definition: imap.h:499
boost::future< bool > contains_key(const K &key)
check if this map contains key.
Definition: imap.h:77
boost::future< bool > try_remove(const K &key, std::chrono::milliseconds timeout)
Tries to remove the entry with the given key from this map within specified timeout value.
Definition: imap.h:182
boost::future< void > lock(const K &key)
Acquires the lock for the specified key.
Definition: imap.h:311
boost::future< std::string > add_interceptor(const MapInterceptor &interceptor)
Adds an interceptor for this map.
Definition: imap.h:453
boost::future< std::vector< V > > values()
Returns a vector clone of the values contained in this map.
Definition: imap.h:681
boost::future< std::vector< K > > key_set(query::paging_predicate< K, V > &predicate)
Queries the map based on the specified predicate and returns the keys of matching entries.
Definition: imap.h:655
boost::future< boost::optional< ResultType > > execute_on_key(const K &key, const EntryProcessor &entry_processor)
Applies the user defined EntryProcessor to the entry mapped by the key.
Definition: imap.h:855
monitor::local_map_stats & get_local_map_stats()
Returns LocalMapStats for this map.
Definition: imap.h:976
boost::future< std::vector< V > > values(query::paging_predicate< K, V > &predicate)
Returns a vector clone of the values contained in this map.
Definition: imap.h:708
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).
Definition: imap.h:943
boost::future< std::vector< K > > key_set()
Returns a vector clone of the keys contained in this map.
Definition: imap.h:623
boost::future< std::unordered_map< K, boost::optional< ResultType > > > execute_on_keys(const std::unordered_set< K > &keys, const EntryProcessor &entry_processor)
Applies the user defined EntryProcessor to the entries mapped by the collection of keys.
Definition: imap.h:889
boost::future< bool > contains_value(const V &value)
check if this map contains value.
Definition: imap.h:87
boost::future< boost::optional< R > > put(const K &key, const V &value, std::chrono::milliseconds ttl)
Puts an entry into this map with a given ttl (time to live) value.
Definition: imap.h:123
boost::future< bool > is_locked(const K &key)
Checks the lock for the specified key.
Definition: imap.h:347
boost::future< void > add_index(const config::index_config &config)
Adds an index to this map for the specified entries so that queries can run faster.
Definition: imap.h:819
boost::future< std::vector< K > > key_set(const P &predicate)
Queries the map based on the specified predicate and returns the keys of matching entries.
Definition: imap.h:639
boost::future< bool > try_lock(const K &key, std::chrono::milliseconds timeout)
Tries to acquire the lock for the specified key.
Definition: imap.h:382
boost::future< boost::optional< V > > put_if_absent(const K &key, const V &value)
Puts an entry into this map, if the specified key is not already associated with a value.
Definition: imap.h:226
boost::future< std::unordered_map< K, boost::optional< ResultType > > > execute_on_entries(const EntryProcessor &entry_processor)
Applies the user defined EntryProcessor to the all entries in the map.
Definition: imap.h:907
boost::future< void > delete_entry(const K &key)
removes entry from map.
Definition: imap.h:168
boost::future< bool > try_lock(const K &key)
Tries to acquire the lock for the specified key.
Definition: imap.h:361
boost::future< bool > evict(const K &key)
Evicts the specified key from this map.
Definition: imap.h:566
boost::future< bool > try_put(const K &key, const V &value, std::chrono::milliseconds timeout)
Tries to put the given key, value into this map within specified timeout value.
Definition: imap.h:199
boost::future< boost::optional< entry_view< K, V > > > get_entry_view(const K &key)
Returns the EntryView for the specified key.
Definition: imap.h:544
boost::future< void > set(const K &key, const V &value, std::chrono::milliseconds ttl)
Puts an entry into this map.
Definition: imap.h:292
boost::future< void > unlock(const K &key)
Releases the lock for the specified key.
Definition: imap.h:424
boost::future< void > put_transient(const K &key, const V &value, std::chrono::milliseconds ttl)
Same as put(K, V, int64_t, TimeUnit) but MapStore, if defined, will not be called to store/persist th...
Definition: imap.h:213
NOTE: paging_predicate can only be used with values(), keySet() and entries() methods!...
Configuration of an index.
Definition: index_config.h:40