/* * Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hazelcast.map.impl.proxy; import com.hazelcast.aggregation.Aggregator; import com.hazelcast.config.MapConfig; import com.hazelcast.core.EntryListener; import com.hazelcast.core.EntryView; import com.hazelcast.core.ExecutionCallback; import com.hazelcast.core.HazelcastException; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.ICompletableFuture; import com.hazelcast.core.IMap; import com.hazelcast.map.EntryProcessor; import com.hazelcast.map.MapInterceptor; import com.hazelcast.map.QueryCache; import com.hazelcast.map.impl.MapService; import com.hazelcast.map.impl.SimpleEntryView; import com.hazelcast.map.impl.iterator.MapPartitionIterator; import com.hazelcast.map.impl.query.AggregationResult; import com.hazelcast.map.impl.query.MapQueryEngine; import com.hazelcast.map.impl.query.Query; import com.hazelcast.map.impl.query.QueryResult; import com.hazelcast.map.impl.query.Target; import com.hazelcast.map.impl.querycache.QueryCacheContext; import com.hazelcast.map.impl.querycache.subscriber.InternalQueryCache; import com.hazelcast.map.impl.querycache.subscriber.NodeQueryCacheEndToEndConstructor; import com.hazelcast.map.impl.querycache.subscriber.QueryCacheEndToEndProvider; import com.hazelcast.map.impl.querycache.subscriber.QueryCacheRequest; import com.hazelcast.map.impl.querycache.subscriber.SubscriberContext; import com.hazelcast.map.listener.MapListener; import com.hazelcast.map.listener.MapPartitionLostListener; import com.hazelcast.mapreduce.Collator; import com.hazelcast.mapreduce.CombinerFactory; import com.hazelcast.mapreduce.Job; import com.hazelcast.mapreduce.JobTracker; import com.hazelcast.mapreduce.KeyValueSource; import com.hazelcast.mapreduce.Mapper; import com.hazelcast.mapreduce.MappingJob; import com.hazelcast.mapreduce.ReducerFactory; import com.hazelcast.mapreduce.ReducingSubmittableJob; import com.hazelcast.mapreduce.aggregation.Aggregation; import com.hazelcast.mapreduce.aggregation.Supplier; import com.hazelcast.nio.serialization.Data; import com.hazelcast.projection.Projection; import com.hazelcast.query.PagingPredicate; import com.hazelcast.query.PartitionPredicate; import com.hazelcast.query.Predicate; import com.hazelcast.query.TruePredicate; import com.hazelcast.spi.InternalCompletableFuture; import com.hazelcast.spi.NodeEngine; import com.hazelcast.spi.Operation; import com.hazelcast.util.CollectionUtil; import com.hazelcast.util.ConstructorFunction; import com.hazelcast.util.IterationType; import com.hazelcast.util.UuidUtil; import com.hazelcast.util.executor.DelegatingFuture; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import static com.hazelcast.config.InMemoryFormat.NATIVE; import static com.hazelcast.map.impl.MapService.SERVICE_NAME; import static com.hazelcast.map.impl.query.QueryResultUtils.transformToSet; import static com.hazelcast.map.impl.querycache.subscriber.QueryCacheRequests.newQueryCacheRequest; import static com.hazelcast.util.MapUtil.createHashMap; import static com.hazelcast.util.Preconditions.checkNotInstanceOf; import static com.hazelcast.util.Preconditions.checkNotNull; import static com.hazelcast.util.Preconditions.checkPositive; import static com.hazelcast.util.Preconditions.checkTrue; import static com.hazelcast.util.Preconditions.isNotNull; import static java.util.Collections.emptyMap; /** * Proxy implementation of {@link com.hazelcast.core.IMap} interface. * * @param <K> the key type of map. * @param <V> the value type of map. */ @SuppressWarnings("checkstyle:classfanoutcomplexity") public class MapProxyImpl<K, V> extends MapProxySupport<K, V> { public MapProxyImpl(String name, MapService mapService, NodeEngine nodeEngine, MapConfig mapConfig) { super(name, mapService, nodeEngine, mapConfig); } @Override public V get(Object key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return toObject(getInternal(keyData)); } @Override public V put(K key, V value) { return put(key, value, -1, TimeUnit.MILLISECONDS); } @Override public V put(K key, V value, long ttl, TimeUnit timeunit) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data valueData = toData(value); Data result = putInternal(keyData, valueData, ttl, timeunit); return toObject(result); } @Override public boolean tryPut(K key, V value, long timeout, TimeUnit timeunit) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data valueData = toData(value); return tryPutInternal(keyData, valueData, timeout, timeunit); } @Override public V putIfAbsent(K key, V value) { return putIfAbsent(key, value, -1, TimeUnit.MILLISECONDS); } @Override public V putIfAbsent(K key, V value, long ttl, TimeUnit timeunit) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data valueData = toData(value); Data result = putIfAbsentInternal(keyData, valueData, ttl, timeunit); return toObject(result); } @Override public void putTransient(K key, V value, long ttl, TimeUnit timeunit) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data valueData = toData(value); putTransientInternal(keyData, valueData, ttl, timeunit); } @Override public boolean replace(K key, V oldValue, V newValue) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkNotNull(oldValue, NULL_VALUE_IS_NOT_ALLOWED); checkNotNull(newValue, NULL_VALUE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data oldValueData = toData(oldValue); Data newValueData = toData(newValue); return replaceInternal(keyData, oldValueData, newValueData); } @Override public V replace(K key, V value) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data valueData = toData(value); return toObject(replaceInternal(keyData, valueData)); } @Override public void set(K key, V value) { set(key, value, -1, TimeUnit.MILLISECONDS); } @Override public void set(K key, V value, long ttl, TimeUnit timeunit) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data valueData = toData(value); setInternal(keyData, valueData, ttl, timeunit); } @Override public V remove(Object key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data result = removeInternal(keyData); return toObject(result); } @Override public boolean remove(Object key, Object value) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data valueData = toData(value); return removeInternal(keyData, valueData); } @Override public void removeAll(Predicate<K, V> predicate) { checkNotNull(predicate, "predicate cannot be null"); removeAllInternal(predicate); } @Override public void delete(Object key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); deleteInternal(keyData); } @Override public boolean containsKey(Object key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return containsKeyInternal(keyData); } @Override public boolean containsValue(Object value) { checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED); Data valueData = toData(value); return containsValueInternal(valueData); } @Override public void lock(K key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); lockSupport.lock(getNodeEngine(), keyData); } @Override public void lock(Object key, long leaseTime, TimeUnit timeUnit) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkPositive(leaseTime, "leaseTime should be positive"); Data keyData = toDataWithStrategy(key); lockSupport.lock(getNodeEngine(), keyData, timeUnit.toMillis(leaseTime)); } @Override public void unlock(K key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); lockSupport.unlock(getNodeEngine(), keyData); } @Override public boolean tryRemove(K key, long timeout, TimeUnit timeunit) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return tryRemoveInternal(keyData, timeout, timeunit); } @Override public ICompletableFuture<V> getAsync(K key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return new DelegatingFuture<V>(getAsyncInternal(keyData), serializationService); } @Override public boolean isLocked(K key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return lockSupport.isLocked(getNodeEngine(), keyData); } @Override public ICompletableFuture<V> putAsync(K key, V value) { return putAsync(key, value, -1, TimeUnit.MILLISECONDS); } @Override public ICompletableFuture<V> putAsync(K key, V value, long ttl, TimeUnit timeunit) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data valueData = toData(value); return new DelegatingFuture<V>(putAsyncInternal(keyData, valueData, ttl, timeunit), serializationService); } @Override public ICompletableFuture<Void> setAsync(K key, V value) { return setAsync(key, value, -1, TimeUnit.MILLISECONDS); } @Override public ICompletableFuture<Void> setAsync(K key, V value, long ttl, TimeUnit timeunit) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); checkNotNull(value, NULL_VALUE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); Data valueData = toData(value); return new DelegatingFuture<Void>(setAsyncInternal(keyData, valueData, ttl, timeunit), serializationService); } @Override public ICompletableFuture<V> removeAsync(K key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return new DelegatingFuture<V>(removeAsyncInternal(keyData), serializationService); } @Override public Map<K, V> getAll(Set<K> keys) { if (CollectionUtil.isEmpty(keys)) { return emptyMap(); } List<Data> requestedKeys = new ArrayList<Data>(keys.size()); for (K key : keys) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); requestedKeys.add(keyData); } List<Object> resultingKeyValuePairs = new ArrayList<Object>(2 * keys.size()); getAllObjectInternal(requestedKeys, resultingKeyValuePairs); Map<K, V> result = createHashMap(keys.size()); for (int i = 0; i < resultingKeyValuePairs.size(); ) { K key = toObject(resultingKeyValuePairs.get(i++)); V value = toObject(resultingKeyValuePairs.get(i++)); result.put(key, value); } return result; } @Override public void putAll(Map<? extends K, ? extends V> map) { putAllInternal(map); } @Override public boolean tryLock(K key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return lockSupport.tryLock(getNodeEngine(), keyData); } @Override public boolean tryLock(K key, long time, TimeUnit timeunit) throws InterruptedException { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return lockSupport.tryLock(getNodeEngine(), keyData, time, timeunit); } @Override public boolean tryLock(K key, long time, TimeUnit timeunit, long leaseTime, TimeUnit leaseTimeUnit) throws InterruptedException { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return lockSupport.tryLock(getNodeEngine(), keyData, time, timeunit, leaseTime, leaseTimeUnit); } @Override public void forceUnlock(K key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); lockSupport.forceUnlock(getNodeEngine(), keyData); } @Override public String addInterceptor(MapInterceptor interceptor) { checkNotNull(interceptor, "Interceptor should not be null!"); return addMapInterceptorInternal(interceptor); } @Override public void removeInterceptor(String id) { checkNotNull(id, "Interceptor id should not be null!"); removeMapInterceptorInternal(id); } @Override public String addLocalEntryListener(MapListener listener) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); return addLocalEntryListenerInternal(listener); } @Override public String addLocalEntryListener(EntryListener listener) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); return addLocalEntryListenerInternal(listener); } @Override public String addLocalEntryListener(MapListener listener, Predicate<K, V> predicate, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); return addLocalEntryListenerInternal(listener, predicate, null, includeValue); } @Override public String addLocalEntryListener(EntryListener listener, Predicate<K, V> predicate, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); return addLocalEntryListenerInternal(listener, predicate, null, includeValue); } @Override public String addLocalEntryListener(MapListener listener, Predicate<K, V> predicate, K key, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return addLocalEntryListenerInternal(listener, predicate, keyData, includeValue); } @Override public String addLocalEntryListener(EntryListener listener, Predicate<K, V> predicate, K key, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); return addLocalEntryListenerInternal(listener, predicate, keyData, includeValue); } @Override public String addEntryListener(MapListener listener, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); return addEntryListenerInternal(listener, null, includeValue); } @Override public String addEntryListener(EntryListener listener, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); return addEntryListenerInternal(listener, null, includeValue); } @Override public String addEntryListener(MapListener listener, K key, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); return addEntryListenerInternal(listener, toDataWithStrategy(key), includeValue); } @Override public String addEntryListener(EntryListener listener, K key, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); return addEntryListenerInternal(listener, toDataWithStrategy(key), includeValue); } @Override public String addEntryListener(MapListener listener, Predicate<K, V> predicate, K key, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); return addEntryListenerInternal(listener, predicate, toDataWithStrategy(key), includeValue); } @Override public String addEntryListener(EntryListener listener, Predicate<K, V> predicate, K key, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); return addEntryListenerInternal(listener, predicate, toDataWithStrategy(key), includeValue); } @Override public String addEntryListener(MapListener listener, Predicate<K, V> predicate, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); return addEntryListenerInternal(listener, predicate, null, includeValue); } @Override public String addEntryListener(EntryListener listener, Predicate<K, V> predicate, boolean includeValue) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); return addEntryListenerInternal(listener, predicate, null, includeValue); } @Override public boolean removeEntryListener(String id) { checkNotNull(id, "Listener id should not be null!"); return removeEntryListenerInternal(id); } @Override public String addPartitionLostListener(MapPartitionLostListener listener) { checkNotNull(listener, NULL_LISTENER_IS_NOT_ALLOWED); return addPartitionLostListenerInternal(listener); } @Override public boolean removePartitionLostListener(String id) { checkNotNull(id, "Listener id should not be null!"); return removePartitionLostListenerInternal(id); } @Override @SuppressWarnings("unchecked") public EntryView<K, V> getEntryView(K key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); SimpleEntryView<K, V> entryViewInternal = (SimpleEntryView<K, V>) getEntryViewInternal(toDataWithStrategy(key)); if (entryViewInternal == null) { return null; } Data value = (Data) entryViewInternal.getValue(); entryViewInternal.setKey(key); entryViewInternal.setValue((V) toObject(value)); return entryViewInternal; } @Override public boolean evict(Object key) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); return evictInternal(toDataWithStrategy(key)); } @Override public void evictAll() { evictAllInternal(); } @Override public void loadAll(boolean replaceExistingValues) { checkTrue(isMapStoreEnabled(), "First you should configure a map store"); loadAllInternal(replaceExistingValues); } @Override public void loadAll(Set<K> keys, boolean replaceExistingValues) { checkTrue(isMapStoreEnabled(), "First you should configure a map store"); checkNotNull(keys, "Parameter keys should not be null."); loadInternal(convertToData(keys), replaceExistingValues); } /** * This method clears the map and calls deleteAll on MapStore which if connected to a database, * will delete the records from that database. * <p> * If you wish to clear the map only without calling deleteAll, use #clearMapOnly. * * @see #clearMapOnly */ @Override public void clear() { clearInternal(); } /** * This method clears the map. It does not invoke deleteAll on any associated MapStore. * * @see #clear */ //TODO: why is this not tested? //TODO: how come the implementation is the same as clear? I think this code is broken //TODO: This method also isn't part of the IMap API public void clearMapOnly() { // TODO: need a different method here that does not call deleteAll() clearInternal(); } @Override public Set<K> keySet() { return keySet(TruePredicate.INSTANCE); } @Override @SuppressWarnings("unchecked") public Set<K> keySet(Predicate predicate) { return executePredicate(predicate, IterationType.KEY, true); } @Override public Set entrySet() { return entrySet(TruePredicate.INSTANCE); } @Override public Set entrySet(Predicate predicate) { return executePredicate(predicate, IterationType.ENTRY, true); } @Override public Collection<V> values() { return values(TruePredicate.INSTANCE); } @Override @SuppressWarnings("unchecked") public Collection<V> values(Predicate predicate) { return executePredicate(predicate, IterationType.VALUE, false); } private Set executePredicate(Predicate predicate, IterationType iterationType, boolean uniqueResult) { checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); MapQueryEngine queryEngine = getMapQueryEngine(); QueryResult result; if (predicate instanceof PartitionPredicate) { PartitionPredicate partitionPredicate = (PartitionPredicate) predicate; Data key = toData(partitionPredicate.getPartitionKey()); int partitionId = partitionService.getPartitionId(key); Query query = Query.of() .mapName(getName()) .predicate(partitionPredicate.getTarget()) .iterationType(iterationType) .build(); result = queryEngine.execute(query, Target.of().partitionOwner(partitionId).build()); } else { Query query = Query.of() .mapName(getName()) .predicate(predicate) .iterationType(iterationType) .build(); result = queryEngine.execute(query, Target.ALL_NODES); } return transformToSet(serializationService, result, predicate, iterationType, uniqueResult); } @Override public Set<K> localKeySet() { return localKeySet(TruePredicate.INSTANCE); } @Override @SuppressWarnings("unchecked") public Set<K> localKeySet(Predicate predicate) { checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); MapQueryEngine queryEngine = getMapQueryEngine(); Query query = Query.of() .mapName(getName()) .predicate(predicate) .iterationType(IterationType.KEY) .build(); QueryResult result = queryEngine.execute(query, Target.LOCAL_NODE); return transformToSet(serializationService, result, predicate, IterationType.KEY, false); } @Override public Object executeOnKey(K key, EntryProcessor entryProcessor) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data result = executeOnKeyInternal(toDataWithStrategy(key), entryProcessor); return toObject(result); } @Override public Map<K, Object> executeOnKeys(Set<K> keys, EntryProcessor entryProcessor) { if (keys == null || keys.contains(null)) { throw new NullPointerException(NULL_KEY_IS_NOT_ALLOWED); } if (keys.isEmpty()) { return emptyMap(); } Set<Data> dataKeys = new HashSet<Data>(keys.size()); for (K key : keys) { dataKeys.add(toDataWithStrategy(key)); } return executeOnKeysInternal(dataKeys, entryProcessor); } @Override public void submitToKey(K key, EntryProcessor entryProcessor, ExecutionCallback callback) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); executeOnKeyInternal(keyData, entryProcessor, callback); } @Override public ICompletableFuture submitToKey(K key, EntryProcessor entryProcessor) { checkNotNull(key, NULL_KEY_IS_NOT_ALLOWED); Data keyData = toDataWithStrategy(key); InternalCompletableFuture future = executeOnKeyInternal(keyData, entryProcessor, null); return new DelegatingFuture(future, serializationService); } @Override public Map<K, Object> executeOnEntries(EntryProcessor entryProcessor) { return executeOnEntries(entryProcessor, TruePredicate.INSTANCE); } @Override public Map<K, Object> executeOnEntries(EntryProcessor entryProcessor, Predicate predicate) { List<Data> result = new ArrayList<Data>(); executeOnEntriesInternal(entryProcessor, predicate, result); if (result.isEmpty()) { return emptyMap(); } Map<K, Object> resultingMap = createHashMap(result.size() / 2); for (int i = 0; i < result.size(); ) { Data key = result.get(i++); Data value = result.get(i++); resultingMap.put((K) toObject(key), toObject(value)); } return resultingMap; } @Override public <R> R aggregate(Aggregator<Map.Entry<K, V>, R> aggregator) { checkNotNull(aggregator, NULL_AGGREGATOR_IS_NOT_ALLOWED); MapQueryEngine queryEngine = getMapQueryEngine(); aggregator = serializationService.toObject(serializationService.toData(aggregator)); Query query = Query.of() .mapName(getName()) .predicate(TruePredicate.INSTANCE) .iterationType(IterationType.ENTRY) .aggregator(aggregator) .build(); AggregationResult result = queryEngine.execute(query, Target.ALL_NODES); return result.<R>getAggregator().aggregate(); } @Override public <R> R aggregate(Aggregator<Map.Entry<K, V>, R> aggregator, Predicate<K, V> predicate) { checkNotNull(aggregator, NULL_AGGREGATOR_IS_NOT_ALLOWED); checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); aggregator = serializationService.toObject(serializationService.toData(aggregator)); MapQueryEngine queryEngine = getMapQueryEngine(); if (predicate instanceof PagingPredicate) { throw new IllegalArgumentException("PagingPredicate now allowed with EntryAggregator."); } Query query = Query.of() .mapName(getName()) .predicate(predicate) .iterationType(IterationType.ENTRY) .aggregator(aggregator) .build(); AggregationResult result = queryEngine.execute(query, Target.ALL_NODES); return result.<R>getAggregator().aggregate(); } @Override public <R> Collection<R> project(Projection<Map.Entry<K, V>, R> projection) { checkNotNull(projection, NULL_PROJECTION_IS_NOT_ALLOWED); MapQueryEngine queryEngine = getMapQueryEngine(); projection = serializationService.toObject(serializationService.toData(projection)); Query query = Query.of() .mapName(getName()) .predicate(TruePredicate.INSTANCE) .iterationType(IterationType.VALUE) .projection(projection) .build(); QueryResult result = queryEngine.execute(query, Target.ALL_NODES); return transformToSet(serializationService, result, TruePredicate.INSTANCE, IterationType.VALUE, false); } @Override public <R> Collection<R> project(Projection<Map.Entry<K, V>, R> projection, Predicate<K, V> predicate) { checkNotNull(projection, NULL_PROJECTION_IS_NOT_ALLOWED); checkNotNull(predicate, NULL_PREDICATE_IS_NOT_ALLOWED); projection = serializationService.toObject(serializationService.toData(projection)); MapQueryEngine queryEngine = getMapQueryEngine(); Query query = Query.of() .mapName(getName()) .predicate(predicate) .iterationType(IterationType.VALUE) .projection(projection) .build(); queryEngine.execute(query, Target.ALL_NODES); QueryResult result = queryEngine.execute(query, Target.ALL_NODES); return transformToSet(serializationService, result, predicate, IterationType.VALUE, false); } @Override public <SuppliedValue, Result> Result aggregate(Supplier<K, V, SuppliedValue> supplier, Aggregation<K, SuppliedValue, Result> aggregation) { checkTrue(NATIVE != mapConfig.getInMemoryFormat(), "NATIVE storage format is not supported for MapReduce"); HazelcastInstance hazelcastInstance = getNodeEngine().getHazelcastInstance(); JobTracker jobTracker = hazelcastInstance.getJobTracker("hz::aggregation-map-" + getName()); return aggregate(supplier, aggregation, jobTracker); } @Override public <SuppliedValue, Result> Result aggregate(Supplier<K, V, SuppliedValue> supplier, Aggregation<K, SuppliedValue, Result> aggregation, JobTracker jobTracker) { checkTrue(NATIVE != mapConfig.getInMemoryFormat(), "NATIVE storage format is not supported for MapReduce"); try { isNotNull(jobTracker, "jobTracker"); KeyValueSource<K, V> keyValueSource = KeyValueSource.fromMap(this); Job<K, V> job = jobTracker.newJob(keyValueSource); Mapper mapper = aggregation.getMapper(supplier); CombinerFactory combinerFactory = aggregation.getCombinerFactory(); ReducerFactory reducerFactory = aggregation.getReducerFactory(); Collator collator = aggregation.getCollator(); MappingJob mappingJob = job.mapper(mapper); ReducingSubmittableJob reducingJob; if (combinerFactory == null) { reducingJob = mappingJob.reducer(reducerFactory); } else { reducingJob = mappingJob.combiner(combinerFactory).reducer(reducerFactory); } ICompletableFuture<Result> future = reducingJob.submit(collator); return future.get(); } catch (Exception e) { // TODO: not what we want, because it can lead to wrapping of HazelcastException throw new HazelcastException(e); } } protected Object invoke(Operation operation, int partitionId) throws Throwable { Future future = operationService.invokeOnPartition(SERVICE_NAME, operation, partitionId); Object response = future.get(); Object result = toObject(response); if (result instanceof Throwable) { throw (Throwable) result; } return result; } public Iterator<Entry<K, V>> iterator(int fetchSize, int partitionId, boolean prefetchValues) { return new MapPartitionIterator<K, V>(this, fetchSize, partitionId, prefetchValues); } @Override public String toString() { return "IMap{name='" + name + '\'' + '}'; } @Override public QueryCache<K, V> getQueryCache(String name) { checkNotNull(name, "name cannot be null"); return getQueryCacheInternal(name, null, null, null, this); } @Override public QueryCache<K, V> getQueryCache(String name, Predicate<K, V> predicate, boolean includeValue) { checkNotNull(name, "name cannot be null"); checkNotNull(predicate, "predicate cannot be null"); checkNotInstanceOf(PagingPredicate.class, predicate, "predicate"); return getQueryCacheInternal(name, null, predicate, includeValue, this); } @Override public QueryCache<K, V> getQueryCache(String name, MapListener listener, Predicate<K, V> predicate, boolean includeValue) { checkNotNull(name, "name cannot be null"); checkNotNull(predicate, "predicate cannot be null"); checkNotInstanceOf(PagingPredicate.class, predicate, "predicate"); return getQueryCacheInternal(name, listener, predicate, includeValue, this); } private QueryCache<K, V> getQueryCacheInternal(String name, MapListener listener, Predicate<K, V> predicate, Boolean includeValue, IMap<K, V> map) { QueryCacheContext queryCacheContext = mapServiceContext.getQueryCacheContext(); QueryCacheRequest request = newQueryCacheRequest() .forMap(map) .withCacheName(UuidUtil.newUnsecureUuidString()) .withUserGivenCacheName(name) .withListener(listener) .withPredicate(predicate) .withIncludeValue(includeValue) .withContext(queryCacheContext); return createQueryCache(request); } private QueryCache<K, V> createQueryCache(QueryCacheRequest request) { ConstructorFunction<String, InternalQueryCache> constructorFunction = new NodeQueryCacheEndToEndConstructor(request); QueryCacheContext queryCacheContext = request.getContext(); SubscriberContext subscriberContext = queryCacheContext.getSubscriberContext(); QueryCacheEndToEndProvider queryCacheEndToEndProvider = subscriberContext.getEndToEndQueryCacheProvider(); return queryCacheEndToEndProvider.getOrCreateQueryCache(request.getMapName(), request.getUserGivenCacheName(), constructorFunction); } }