All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.map.impl.MapServiceContextImpl Maven / Gradle / Ivy

There is a newer version: 5.5.0
Show newest version
/*
 * Copyright (c) 2008-2020, 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;

import com.hazelcast.cluster.ClusterState;
import com.hazelcast.config.InMemoryFormat;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.MergePolicyConfig;
import com.hazelcast.config.MetadataPolicy;
import com.hazelcast.config.PartitioningStrategyConfig;
import com.hazelcast.core.PartitioningStrategy;
import com.hazelcast.internal.eviction.ExpirationManager;
import com.hazelcast.internal.serialization.InternalSerializationService;
import com.hazelcast.internal.util.InvocationUtil;
import com.hazelcast.internal.util.LocalRetryableExecution;
import com.hazelcast.internal.util.comparators.ValueComparator;
import com.hazelcast.internal.util.comparators.ValueComparatorUtil;
import com.hazelcast.logging.ILogger;
import com.hazelcast.map.MapInterceptor;
import com.hazelcast.map.impl.event.MapEventPublisher;
import com.hazelcast.map.impl.event.MapEventPublisherImpl;
import com.hazelcast.map.impl.eviction.MapClearExpiredRecordsTask;
import com.hazelcast.map.impl.journal.MapEventJournal;
import com.hazelcast.map.impl.journal.RingbufferMapEventJournalImpl;
import com.hazelcast.map.impl.mapstore.MapDataStore;
import com.hazelcast.map.impl.nearcache.MapNearCacheManager;
import com.hazelcast.map.impl.operation.BasePutOperation;
import com.hazelcast.map.impl.operation.BaseRemoveOperation;
import com.hazelcast.map.impl.operation.GetOperation;
import com.hazelcast.map.impl.operation.MapOperationProvider;
import com.hazelcast.map.impl.operation.MapOperationProviders;
import com.hazelcast.map.impl.operation.MapPartitionDestroyOperation;
import com.hazelcast.map.impl.query.AccumulationExecutor;
import com.hazelcast.map.impl.query.AggregationResult;
import com.hazelcast.map.impl.query.AggregationResultProcessor;
import com.hazelcast.map.impl.query.CallerRunsAccumulationExecutor;
import com.hazelcast.map.impl.query.CallerRunsPartitionScanExecutor;
import com.hazelcast.map.impl.query.QueryEngine;
import com.hazelcast.map.impl.query.QueryEngineImpl;
import com.hazelcast.map.impl.query.ParallelAccumulationExecutor;
import com.hazelcast.map.impl.query.ParallelPartitionScanExecutor;
import com.hazelcast.map.impl.query.PartitionScanExecutor;
import com.hazelcast.map.impl.query.PartitionScanRunner;
import com.hazelcast.map.impl.query.QueryResult;
import com.hazelcast.map.impl.query.QueryResultProcessor;
import com.hazelcast.map.impl.query.QueryRunner;
import com.hazelcast.map.impl.query.ResultProcessorRegistry;
import com.hazelcast.map.impl.querycache.NodeQueryCacheContext;
import com.hazelcast.map.impl.querycache.QueryCacheContext;
import com.hazelcast.map.impl.record.Record;
import com.hazelcast.map.impl.recordstore.DefaultRecordStore;
import com.hazelcast.map.impl.recordstore.EventJournalWriterRecordStoreMutationObserver;
import com.hazelcast.map.impl.recordstore.JsonMetadataRecordStoreMutationObserver;
import com.hazelcast.map.impl.recordstore.RecordStore;
import com.hazelcast.map.impl.recordstore.RecordStoreMutationObserver;
import com.hazelcast.map.listener.MapPartitionLostListener;
import com.hazelcast.map.merge.MergePolicyProvider;
import com.hazelcast.monitor.impl.LocalMapStatsImpl;
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.nio.serialization.DataType;
import com.hazelcast.query.impl.DefaultIndexProvider;
import com.hazelcast.query.impl.IndexCopyBehavior;
import com.hazelcast.query.impl.IndexProvider;
import com.hazelcast.query.impl.getters.Extractors;
import com.hazelcast.query.impl.predicates.QueryOptimizer;
import com.hazelcast.spi.EventFilter;
import com.hazelcast.spi.EventRegistration;
import com.hazelcast.spi.EventService;
import com.hazelcast.spi.NodeEngine;
import com.hazelcast.spi.Operation;
import com.hazelcast.spi.impl.eventservice.impl.TrueEventFilter;
import com.hazelcast.spi.partition.IPartitionService;
import com.hazelcast.spi.serialization.SerializationService;
import com.hazelcast.util.ConcurrencyUtil;
import com.hazelcast.util.ConstructorFunction;
import com.hazelcast.util.ContextMutexFactory;
import com.hazelcast.util.executor.ManagedExecutorService;
import com.hazelcast.util.function.Predicate;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

import static com.hazelcast.map.impl.ListenerAdapters.createListenerAdapter;
import static com.hazelcast.map.impl.MapListenerFlagOperator.setAndGetListenerFlags;
import static com.hazelcast.map.impl.MapService.SERVICE_NAME;
import static com.hazelcast.query.impl.predicates.QueryOptimizerFactory.newOptimizer;
import static com.hazelcast.spi.ExecutionService.QUERY_EXECUTOR;
import static com.hazelcast.spi.Operation.GENERIC_PARTITION_ID;
import static com.hazelcast.spi.properties.GroupProperty.AGGREGATION_ACCUMULATION_PARALLEL_EVALUATION;
import static com.hazelcast.spi.properties.GroupProperty.INDEX_COPY_BEHAVIOR;
import static com.hazelcast.spi.properties.GroupProperty.OPERATION_CALL_TIMEOUT_MILLIS;
import static com.hazelcast.spi.properties.GroupProperty.QUERY_PREDICATE_PARALLEL_EVALUATION;
import static java.lang.Thread.currentThread;

/**
 * Default implementation of {@link MapServiceContext}.
 */
@SuppressWarnings("WeakerAccess")
class MapServiceContextImpl implements MapServiceContext {

    protected static final long DESTROY_TIMEOUT_SECONDS = 30;

    protected final ConcurrentMap mapContainers = new ConcurrentHashMap();
    protected final AtomicReference> ownedPartitions = new AtomicReference>();
    protected final IndexProvider indexProvider = new DefaultIndexProvider();
    protected final ContextMutexFactory contextMutexFactory = new ContextMutexFactory();

    /**
     * Per node global write behind queue item counter.
     * Creating here because we want to have a counter per node.
     * This is used by owner and backups together so it should be defined
     * getting this into account.
     */
    protected final AtomicInteger writeBehindQueueItemCounter = new AtomicInteger(0);

    protected final NodeEngine nodeEngine;
    protected final InternalSerializationService serializationService;
    protected final ConstructorFunction mapConstructor;
    protected final PartitionContainer[] partitionContainers;
    protected final MapClearExpiredRecordsTask clearExpiredRecordsTask;
    protected final ExpirationManager expirationManager;
    protected final MapNearCacheManager mapNearCacheManager;
    protected final LocalMapStatsProvider localMapStatsProvider;
    protected final MergePolicyProvider mergePolicyProvider;
    protected final QueryEngine queryEngine;
    protected final QueryRunner mapQueryRunner;
    protected final PartitionScanRunner partitionScanRunner;
    protected final QueryOptimizer queryOptimizer;
    protected final PartitioningStrategyFactory partitioningStrategyFactory;
    protected final QueryCacheContext queryCacheContext;
    protected final MapEventJournal eventJournal;
    protected final MapEventPublisher mapEventPublisher;
    protected final EventService eventService;
    protected final MapOperationProviders operationProviders;
    protected final ResultProcessorRegistry resultProcessorRegistry;
    protected ILogger logger;

    protected MapService mapService;

    @SuppressWarnings("checkstyle:executablestatementcount")
    MapServiceContextImpl(NodeEngine nodeEngine) {
        this.nodeEngine = nodeEngine;
        this.serializationService = ((InternalSerializationService) nodeEngine.getSerializationService());
        this.mapConstructor = createMapConstructor();
        this.queryCacheContext = new NodeQueryCacheContext(this);
        this.partitionContainers = createPartitionContainers();
        this.clearExpiredRecordsTask = new MapClearExpiredRecordsTask(partitionContainers, nodeEngine);
        this.expirationManager = new ExpirationManager(clearExpiredRecordsTask, nodeEngine);
        this.mapNearCacheManager = createMapNearCacheManager();
        this.localMapStatsProvider = createLocalMapStatsProvider();
        this.mergePolicyProvider = new MergePolicyProvider(nodeEngine);
        this.mapEventPublisher = createMapEventPublisherSupport();
        this.eventJournal = createEventJournal();
        this.queryOptimizer = newOptimizer(nodeEngine.getProperties());
        this.resultProcessorRegistry = createResultProcessorRegistry(serializationService);
        this.partitionScanRunner = createPartitionScanRunner();
        this.queryEngine = createMapQueryEngine();
        this.mapQueryRunner = createMapQueryRunner(nodeEngine, queryOptimizer, resultProcessorRegistry, partitionScanRunner);
        this.eventService = nodeEngine.getEventService();
        this.operationProviders = createOperationProviders();
        this.partitioningStrategyFactory = new PartitioningStrategyFactory(nodeEngine.getConfigClassLoader());
        this.logger = nodeEngine.getLogger(getClass());
    }

    ConstructorFunction createMapConstructor() {
        return new ConstructorFunction() {
            @Override
            public MapContainer createNew(String mapName) {
                MapServiceContext mapServiceContext = getService().getMapServiceContext();
                return new MapContainer(mapName, nodeEngine.getConfig(), mapServiceContext);
            }
        };
    }

    // this method is overridden in another context
    MapNearCacheManager createMapNearCacheManager() {
        return new MapNearCacheManager(this);
    }

    // this method is overridden in another context
    MapOperationProviders createOperationProviders() {
        return new MapOperationProviders(this);
    }

    // this method is overridden in another context
    MapEventPublisherImpl createMapEventPublisherSupport() {
        return new MapEventPublisherImpl(this);
    }

    private MapEventJournal createEventJournal() {
        return new RingbufferMapEventJournalImpl(getNodeEngine(), this);
    }

    protected LocalMapStatsProvider createLocalMapStatsProvider() {
        return new LocalMapStatsProvider(this);
    }

    private QueryEngineImpl createMapQueryEngine() {
        return new QueryEngineImpl(this);
    }

    private PartitionScanRunner createPartitionScanRunner() {
        return new PartitionScanRunner(this);
    }

    protected QueryRunner createMapQueryRunner(NodeEngine nodeEngine, QueryOptimizer queryOptimizer,
                                               ResultProcessorRegistry resultProcessorRegistry,
                                               PartitionScanRunner partitionScanRunner) {
        boolean parallelEvaluation = nodeEngine.getProperties().getBoolean(QUERY_PREDICATE_PARALLEL_EVALUATION);
        PartitionScanExecutor partitionScanExecutor;
        if (parallelEvaluation) {
            int opTimeoutInMillis = nodeEngine.getProperties().getInteger(OPERATION_CALL_TIMEOUT_MILLIS);
            ManagedExecutorService queryExecutorService = nodeEngine.getExecutionService().getExecutor(QUERY_EXECUTOR);
            partitionScanExecutor = new ParallelPartitionScanExecutor(partitionScanRunner, queryExecutorService,
                    opTimeoutInMillis);
        } else {
            partitionScanExecutor = new CallerRunsPartitionScanExecutor(partitionScanRunner);
        }
        return new QueryRunner(this, queryOptimizer, partitionScanExecutor, resultProcessorRegistry);
    }

    private ResultProcessorRegistry createResultProcessorRegistry(SerializationService ss) {
        ResultProcessorRegistry registry = new ResultProcessorRegistry();
        registry.registerProcessor(QueryResult.class, createQueryResultProcessor(ss));
        registry.registerProcessor(AggregationResult.class, createAggregationResultProcessor(ss));
        return registry;
    }

    private QueryResultProcessor createQueryResultProcessor(SerializationService ss) {
        return new QueryResultProcessor(ss);
    }

    private AggregationResultProcessor createAggregationResultProcessor(SerializationService ss) {
        boolean parallelAccumulation = nodeEngine.getProperties().getBoolean(AGGREGATION_ACCUMULATION_PARALLEL_EVALUATION);
        int opTimeoutInMillis = nodeEngine.getProperties().getInteger(OPERATION_CALL_TIMEOUT_MILLIS);
        AccumulationExecutor accumulationExecutor;
        if (parallelAccumulation) {
            ManagedExecutorService queryExecutorService = nodeEngine.getExecutionService().getExecutor(QUERY_EXECUTOR);
            accumulationExecutor = new ParallelAccumulationExecutor(queryExecutorService, ss, opTimeoutInMillis);
        } else {
            accumulationExecutor = new CallerRunsAccumulationExecutor(ss);
        }

        return new AggregationResultProcessor(accumulationExecutor, serializationService);
    }

    private PartitionContainer[] createPartitionContainers() {
        int partitionCount = nodeEngine.getPartitionService().getPartitionCount();
        return new PartitionContainer[partitionCount];
    }

    @Override
    public MapContainer getMapContainer(String mapName) {
        return ConcurrencyUtil.getOrPutSynchronized(mapContainers, mapName, contextMutexFactory, mapConstructor);
    }

    @Override
    public Map getMapContainers() {
        return mapContainers;
    }

    @Override
    public PartitionContainer getPartitionContainer(int partitionId) {
        assert partitionId != GENERIC_PARTITION_ID : "Cannot be called with GENERIC_PARTITION_ID";

        return partitionContainers[partitionId];
    }

    @Override
    public void initPartitionsContainers() {
        final int partitionCount = nodeEngine.getPartitionService().getPartitionCount();
        for (int i = 0; i < partitionCount; i++) {
            partitionContainers[i] = createPartitionContainer(getService(), i);
        }
    }

    protected PartitionContainer createPartitionContainer(MapService service, int partitionId) {
        return new PartitionContainer(service, partitionId);
    }

    /**
     * Removes all record stores from all partitions.
     *
     * Calls {@link #removeRecordStoresFromPartitionMatchingWith} internally and
     *
     * @param onShutdown           {@code true} if this method is called during map service shutdown,
     *                             otherwise set {@code false}
     * @param onRecordStoreDestroy {@code true} if this method is called during to destroy record store,
     *                             otherwise set {@code false}
     */
    protected void removeAllRecordStoresOfAllMaps(boolean onShutdown, boolean onRecordStoreDestroy) {
        for (PartitionContainer partitionContainer : partitionContainers) {
            if (partitionContainer != null) {
                removeRecordStoresFromPartitionMatchingWith(allRecordStores(),
                        partitionContainer.getPartitionId(), onShutdown, onRecordStoreDestroy);
            }
        }
    }

    /**
     * @return predicate that matches with all record stores of all maps
     */
    private static Predicate allRecordStores() {
        return new Predicate() {
            @Override
            public boolean test(RecordStore recordStore) {
                return true;
            }
        };
    }

    @Override
    public void removeRecordStoresFromPartitionMatchingWith(Predicate predicate,
                                                            int partitionId,
                                                            boolean onShutdown,
                                                            boolean onRecordStoreDestroy) {

        PartitionContainer container = partitionContainers[partitionId];
        if (container == null) {
            return;
        }

        Iterator partitionIterator = container.getMaps().values().iterator();
        while (partitionIterator.hasNext()) {
            RecordStore partition = partitionIterator.next();
            if (predicate.test(partition)) {
                partition.clearPartition(onShutdown, onRecordStoreDestroy);
                partitionIterator.remove();
            }
        }
    }

    @Override
    public MapService getService() {
        return mapService;
    }

    @Override
    public void setService(MapService mapService) {
        this.mapService = mapService;
    }

    @Override
    public void destroyMapStores() {
        for (MapContainer mapContainer : mapContainers.values()) {
            MapStoreWrapper store = mapContainer.getMapStoreContext().getMapStoreWrapper();
            if (store != null) {
                store.destroy();
            }
        }
    }

    @Override
    public void flushMaps() {
        for (MapContainer mapContainer : mapContainers.values()) {
            mapContainer.getMapStoreContext().stop();
        }

        for (PartitionContainer partitionContainer : partitionContainers) {
            for (String mapName : mapContainers.keySet()) {
                RecordStore recordStore = partitionContainer.getExistingRecordStore(mapName);
                if (recordStore != null) {
                    MapDataStore mapDataStore = recordStore.getMapDataStore();
                    mapDataStore.hardFlush();
                }
            }
        }
    }

    @Override
    public void destroyMap(String mapName) {
        // on LiteMembers we don't have a MapContainer, but we may have a Near Cache and listeners
        mapNearCacheManager.destroyNearCache(mapName);
        nodeEngine.getEventService().deregisterAllListeners(SERVICE_NAME, mapName);

        MapContainer mapContainer = mapContainers.get(mapName);
        if (mapContainer == null) {
            return;
        }

        nodeEngine.getWanReplicationService().removeWanEventCounters(MapService.SERVICE_NAME, mapName);
        mapContainer.getMapStoreContext().stop();
        localMapStatsProvider.destroyLocalMapStatsImpl(mapContainer.getName());
        destroyPartitionsAndMapContainer(mapContainer);
    }

    /**
     * Destroys the map data on local partition threads and waits for
     * {@value #DESTROY_TIMEOUT_SECONDS} seconds
     * for each partition segment destruction to complete.
     *
     * @param mapContainer the map container to destroy
     */
    private void destroyPartitionsAndMapContainer(MapContainer mapContainer) {
        final List executions = new ArrayList();

        for (PartitionContainer container : partitionContainers) {
            final MapPartitionDestroyOperation op = new MapPartitionDestroyOperation(container, mapContainer);
            executions.add(InvocationUtil.executeLocallyWithRetry(nodeEngine, op));
        }

        for (LocalRetryableExecution execution : executions) {
            try {
                if (!execution.awaitCompletion(DESTROY_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
                    logger.warning("Map partition was not destroyed in expected time, possible leak");
                }
            } catch (InterruptedException e) {
                currentThread().interrupt();
                nodeEngine.getLogger(getClass()).warning(e);
            }
        }
    }

    @Override
    public void reset() {
        removeAllRecordStoresOfAllMaps(false, false);
        mapNearCacheManager.reset();
    }

    @Override
    public void shutdown() {
        removeAllRecordStoresOfAllMaps(true, false);
        mapNearCacheManager.shutdown();
        mapContainers.clear();
        expirationManager.onShutdown();
    }

    @Override
    public RecordStore getRecordStore(int partitionId, String mapName) {
        return getPartitionContainer(partitionId).getRecordStore(mapName);
    }

    @Override
    public RecordStore getRecordStore(int partitionId, String mapName, boolean skipLoadingOnCreate) {
        return getPartitionContainer(partitionId).getRecordStore(mapName, skipLoadingOnCreate);
    }

    @Override
    public RecordStore getExistingRecordStore(int partitionId, String mapName) {
        return getPartitionContainer(partitionId).getExistingRecordStore(mapName);
    }

    @Override
    public Collection getOwnedPartitions() {
        Collection partitions = ownedPartitions.get();
        if (partitions == null) {
            reloadOwnedPartitions();
            partitions = ownedPartitions.get();
        }
        return partitions;
    }

    /**
     * {@inheritDoc}
     * 

* The method will set the owned partition set in a CAS loop because * this method can be called concurrently. */ @Override public void reloadOwnedPartitions() { final IPartitionService partitionService = nodeEngine.getPartitionService(); for (; ; ) { final Collection expected = ownedPartitions.get(); final Collection partitions = partitionService.getMemberPartitions(nodeEngine.getThisAddress()); final Set newSet = Collections.unmodifiableSet(new LinkedHashSet(partitions)); if (ownedPartitions.compareAndSet(expected, newSet)) { return; } } } @Override public AtomicInteger getWriteBehindQueueItemCounter() { return writeBehindQueueItemCounter; } @Override public ExpirationManager getExpirationManager() { return expirationManager; } @Override public NodeEngine getNodeEngine() { return nodeEngine; } @Override public MergePolicyProvider getMergePolicyProvider() { return mergePolicyProvider; } @Override public Object getMergePolicy(String name) { MapContainer mapContainer = getMapContainer(name); MergePolicyConfig mergePolicyConfig = mapContainer.getMapConfig().getMergePolicyConfig(); return mergePolicyProvider.getMergePolicy(mergePolicyConfig.getPolicy()); } @Override public MapEventPublisher getMapEventPublisher() { return mapEventPublisher; } @Override public MapEventJournal getEventJournal() { return eventJournal; } @Override public QueryEngine getQueryEngine(String mapName) { return queryEngine; } @Override public QueryRunner getMapQueryRunner(String name) { return mapQueryRunner; } @Override public QueryOptimizer getQueryOptimizer() { return queryOptimizer; } @Override public LocalMapStatsProvider getLocalMapStatsProvider() { return localMapStatsProvider; } @Override public Object toObject(Object data) { return serializationService.toObject(data); } @Override public Data toData(Object object, PartitioningStrategy partitionStrategy) { return serializationService.toData(object, partitionStrategy); } @Override public Data toData(Object object) { return serializationService.toData(object, DataType.HEAP); } @Override public void interceptAfterGet(String mapName, Object value) { MapContainer mapContainer = getMapContainer(mapName); List interceptors = mapContainer.getInterceptorRegistry().getInterceptors(); if (!interceptors.isEmpty()) { value = toObject(value); for (MapInterceptor interceptor : interceptors) { interceptor.afterGet(value); } } } @Override public Object interceptPut(String mapName, Object oldValue, Object newValue) { MapContainer mapContainer = getMapContainer(mapName); List interceptors = mapContainer.getInterceptorRegistry().getInterceptors(); Object result = null; if (!interceptors.isEmpty()) { result = toObject(newValue); oldValue = toObject(oldValue); for (MapInterceptor interceptor : interceptors) { Object temp = interceptor.interceptPut(oldValue, result); if (temp != null) { result = temp; } } } return result == null ? newValue : result; } @Override public void interceptAfterPut(String mapName, Object newValue) { MapContainer mapContainer = getMapContainer(mapName); List interceptors = mapContainer.getInterceptorRegistry().getInterceptors(); if (!interceptors.isEmpty()) { newValue = toObject(newValue); for (MapInterceptor interceptor : interceptors) { interceptor.afterPut(newValue); } } } @Override public MapClearExpiredRecordsTask getClearExpiredRecordsTask() { return clearExpiredRecordsTask; } @Override public Object interceptRemove(String mapName, Object value) { MapContainer mapContainer = getMapContainer(mapName); List interceptors = mapContainer.getInterceptorRegistry().getInterceptors(); Object result = null; if (!interceptors.isEmpty()) { result = toObject(value); for (MapInterceptor interceptor : interceptors) { Object temp = interceptor.interceptRemove(result); if (temp != null) { result = temp; } } } return result == null ? value : result; } @Override public void interceptAfterRemove(String mapName, Object value) { MapContainer mapContainer = getMapContainer(mapName); InterceptorRegistry interceptorRegistry = mapContainer.getInterceptorRegistry(); List interceptors = interceptorRegistry.getInterceptors(); if (!interceptors.isEmpty()) { value = toObject(value); for (MapInterceptor interceptor : interceptors) { interceptor.afterRemove(value); } } } @Override public void addInterceptor(String id, String mapName, MapInterceptor interceptor) { MapContainer mapContainer = getMapContainer(mapName); mapContainer.getInterceptorRegistry().register(id, interceptor); } @Override public String generateInterceptorId(String mapName, MapInterceptor interceptor) { return interceptor.getClass().getName() + interceptor.hashCode(); } @Override public void removeInterceptor(String mapName, String id) { MapContainer mapContainer = getMapContainer(mapName); mapContainer.getInterceptorRegistry().deregister(id); } // TODO: interceptors should get a wrapped object which includes the serialized version @Override public Object interceptGet(String mapName, Object value) { MapContainer mapContainer = getMapContainer(mapName); InterceptorRegistry interceptorRegistry = mapContainer.getInterceptorRegistry(); List interceptors = interceptorRegistry.getInterceptors(); Object result = null; if (!interceptors.isEmpty()) { result = toObject(value); for (MapInterceptor interceptor : interceptors) { Object temp = interceptor.interceptGet(result); if (temp != null) { result = temp; } } } return result == null ? value : result; } @Override public boolean hasInterceptor(String mapName) { MapContainer mapContainer = getMapContainer(mapName); return !mapContainer.getInterceptorRegistry().getInterceptors().isEmpty(); } @Override public String addLocalEventListener(Object listener, String mapName) { EventRegistration registration = addListenerInternal(listener, TrueEventFilter.INSTANCE, mapName, true); return registration.getId(); } @Override public String addLocalEventListener(Object listener, EventFilter eventFilter, String mapName) { EventRegistration registration = addListenerInternal(listener, eventFilter, mapName, true); return registration.getId(); } @Override public String addLocalPartitionLostListener(MapPartitionLostListener listener, String mapName) { ListenerAdapter listenerAdapter = new InternalMapPartitionLostListenerAdapter(listener); EventFilter filter = new MapPartitionLostEventFilter(); EventRegistration registration = eventService.registerLocalListener(SERVICE_NAME, mapName, filter, listenerAdapter); return registration.getId(); } @Override public String addEventListener(Object listener, EventFilter eventFilter, String mapName) { EventRegistration registration = addListenerInternal(listener, eventFilter, mapName, false); return registration.getId(); } @Override public String addPartitionLostListener(MapPartitionLostListener listener, String mapName) { ListenerAdapter listenerAdapter = new InternalMapPartitionLostListenerAdapter(listener); EventFilter filter = new MapPartitionLostEventFilter(); EventRegistration registration = eventService.registerListener(SERVICE_NAME, mapName, filter, listenerAdapter); return registration.getId(); } private EventRegistration addListenerInternal(Object listener, EventFilter filter, String mapName, boolean local) { ListenerAdapter listenerAdaptor = createListenerAdapter(listener); if (!(filter instanceof EventListenerFilter)) { int enabledListeners = setAndGetListenerFlags(listenerAdaptor); filter = new EventListenerFilter(enabledListeners, filter); } if (local) { return eventService.registerLocalListener(SERVICE_NAME, mapName, filter, listenerAdaptor); } else { return eventService.registerListener(SERVICE_NAME, mapName, filter, listenerAdaptor); } } @Override public boolean removeEventListener(String mapName, String registrationId) { return eventService.deregisterListener(SERVICE_NAME, mapName, registrationId); } @Override public boolean removePartitionLostListener(String mapName, String registrationId) { return eventService.deregisterListener(SERVICE_NAME, mapName, registrationId); } @Override public MapOperationProvider getMapOperationProvider(String name) { return operationProviders.getOperationProvider(name); } @Override public MapOperationProvider getMapOperationProvider(MapConfig mapConfig) { return operationProviders.getOperationProvider(mapConfig); } @Override public IndexProvider getIndexProvider(MapConfig mapConfig) { return indexProvider; } @Override public Extractors getExtractors(String mapName) { MapContainer mapContainer = getMapContainer(mapName); return mapContainer.getExtractors(); } @Override public void incrementOperationStats(long startTime, LocalMapStatsImpl localMapStats, String mapName, Operation operation) { final long durationNanos = System.nanoTime() - startTime; if (operation instanceof BasePutOperation) { localMapStats.incrementPutLatencyNanos(durationNanos); } else if (operation instanceof BaseRemoveOperation) { localMapStats.incrementRemoveLatencyNanos(durationNanos); } else if (operation instanceof GetOperation) { localMapStats.incrementGetLatencyNanos(durationNanos); } } @Override public RecordStore createRecordStore(MapContainer mapContainer, int partitionId, MapKeyLoader keyLoader) { assert partitionId != GENERIC_PARTITION_ID : "Cannot be called with GENERIC_PARTITION_ID"; ILogger logger = nodeEngine.getLogger(DefaultRecordStore.class); return new DefaultRecordStore(mapContainer, partitionId, keyLoader, logger); } @Override public boolean removeMapContainer(MapContainer mapContainer) { return mapContainers.remove(mapContainer.getName(), mapContainer); } @Override public PartitioningStrategy getPartitioningStrategy(String mapName, PartitioningStrategyConfig config) { return partitioningStrategyFactory.getPartitioningStrategy(mapName, config); } @Override public void removePartitioningStrategyFromCache(String mapName) { partitioningStrategyFactory.removePartitioningStrategyFromCache(mapName); } @Override public PartitionContainer[] getPartitionContainers() { return partitionContainers; } @Override public void onClusterStateChange(ClusterState newState) { expirationManager.onClusterStateChange(newState); } @Override public PartitionScanRunner getPartitionScanRunner() { return partitionScanRunner; } @Override public ResultProcessorRegistry getResultProcessorRegistry() { return resultProcessorRegistry; } @Override public MapNearCacheManager getMapNearCacheManager() { return mapNearCacheManager; } @Override public String addListenerAdapter(ListenerAdapter listenerAdaptor, EventFilter eventFilter, String mapName) { EventRegistration registration = getNodeEngine().getEventService(). registerListener(MapService.SERVICE_NAME, mapName, eventFilter, listenerAdaptor); return registration.getId(); } @Override public String addLocalListenerAdapter(ListenerAdapter adapter, String mapName) { EventService eventService = getNodeEngine().getEventService(); EventRegistration registration = eventService.registerLocalListener(MapService.SERVICE_NAME, mapName, adapter); return registration.getId(); } @Override public QueryCacheContext getQueryCacheContext() { return queryCacheContext; } @Override public IndexCopyBehavior getIndexCopyBehavior() { return nodeEngine.getProperties().getEnum(INDEX_COPY_BEHAVIOR, IndexCopyBehavior.class); } @Override public Collection> createRecordStoreMutationObservers(String mapName, int partitionId) { Collection> observers = new LinkedList>(); addEventJournalUpdaterObserver(observers, mapName, partitionId); addMetadataInitializerObserver(observers, mapName, partitionId); return observers; } protected void addMetadataInitializerObserver(Collection> observers, String mapName, int partitionId) { MapContainer mapContainer = getMapContainer(mapName); MetadataPolicy policy = mapContainer.getMapConfig().getMetadataPolicy(); if (policy == MetadataPolicy.CREATE_ON_UPDATE) { RecordStoreMutationObserver observer = new JsonMetadataRecordStoreMutationObserver(serializationService, JsonMetadataInitializer.INSTANCE); observers.add(observer); } } private void addEventJournalUpdaterObserver(Collection> observers, String mapName, int partitionId) { RecordStoreMutationObserver observer = new EventJournalWriterRecordStoreMutationObserver(getEventJournal(), getMapContainer(mapName), partitionId); observers.add(observer); } @Override public ValueComparator getValueComparatorOf(InMemoryFormat inMemoryFormat) { return ValueComparatorUtil.getValueComparatorOf(inMemoryFormat); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy