Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.hazelcast.client.proxy.NearCachedClientMapProxy Maven / Gradle / Ivy
/*
* Copyright (c) 2008-2015, 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.client.proxy;
import com.hazelcast.cache.impl.nearcache.NearCache;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.client.impl.client.BaseClientRemoveListenerRequest;
import com.hazelcast.client.map.impl.nearcache.ClientHeapNearCache;
import com.hazelcast.client.spi.EventHandler;
import com.hazelcast.config.NearCacheConfig;
import com.hazelcast.core.ExecutionCallback;
import com.hazelcast.core.ICompletableFuture;
import com.hazelcast.logging.Logger;
import com.hazelcast.map.impl.MapEntries;
import com.hazelcast.map.impl.client.MapAddNearCacheEntryListenerRequest;
import com.hazelcast.map.impl.client.MapRemoveEntryListenerRequest;
import com.hazelcast.map.impl.nearcache.BatchNearCacheInvalidation;
import com.hazelcast.map.impl.nearcache.CleaningNearCacheInvalidation;
import com.hazelcast.map.impl.nearcache.SingleNearCacheInvalidation;
import com.hazelcast.monitor.LocalMapStats;
import com.hazelcast.monitor.NearCacheStats;
import com.hazelcast.monitor.impl.LocalMapStatsImpl;
import com.hazelcast.monitor.impl.NearCacheStatsImpl;
import com.hazelcast.nio.serialization.Data;
import com.hazelcast.util.executor.CompletedFuture;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import static com.hazelcast.cache.impl.nearcache.NearCache.NULL_OBJECT;
import static com.hazelcast.util.MapUtil.createHashMap;
import static java.util.Collections.emptyMap;
/**
* A Client-side {@code IMap} implementation which is fronted by a near-cache.
*
* @param the key type for this {@code IMap} proxy.
* @param the value type for this {@code IMap} proxy.
*/
public class NearCachedClientMapProxy extends ClientMapProxy {
protected NearCache nearCache;
protected volatile String invalidationListenerId;
public NearCachedClientMapProxy(String serviceName, String name) {
super(serviceName, name);
}
@Override
protected void onInitialize() {
super.onInitialize();
init();
}
protected void init() {
ClientConfig clientConfig = getContext().getClientConfig();
NearCacheConfig nearCacheConfig = clientConfig.getNearCacheConfig(name);
nearCache = new ClientHeapNearCache(name, getContext(), nearCacheConfig);
if (nearCache.isInvalidateOnChange()) {
addNearCacheInvalidateListener();
}
}
@Override
protected boolean containsKeyInternal(Data keyData) {
Object cached = nearCache.get(keyData);
if (cached != null) {
return NULL_OBJECT != cached;
} else {
return super.containsKeyInternal(keyData);
}
}
@Override
protected V getInternal(Data keyData) {
Object cached = nearCache.get(keyData);
if (cached != null) {
if (NULL_OBJECT == cached) {
return null;
}
return (V) cached;
} else {
V response = super.getInternal(keyData);
nearCache.put(keyData, response);
return response;
}
}
@Override
protected V removeInternal(Data keyData) {
invalidateNearCache(keyData);
return super.removeInternal(keyData);
}
@Override
protected boolean removeInternal(Data keyData, Data valueData) {
invalidateNearCache(keyData);
return super.removeInternal(keyData, valueData);
}
@Override
protected void deleteInternal(Data keyData) {
invalidateNearCache(keyData);
super.deleteInternal(keyData);
}
@Override
public ICompletableFuture getAsyncInternal(final Data keyData) {
Object cached = nearCache.get(keyData);
if (cached != null && NULL_OBJECT != cached) {
return new CompletedFuture(getContext().getSerializationService(),
cached, getContext().getExecutionService().getAsyncExecutor());
}
ICompletableFuture future = super.getAsyncInternal(keyData);
future.andThen(new ExecutionCallback() {
@Override
public void onResponse(V response) {
nearCache.put(keyData, response);
}
@Override
public void onFailure(Throwable t) {
}
});
return future;
}
@Override
protected Future putAsyncInternal(long ttl, TimeUnit timeunit, Data keyData, Data valueData) {
invalidateNearCache(keyData);
return super.putAsyncInternal(ttl, timeunit, keyData, valueData);
}
@Override
protected Future removeAsyncInternal(Data keyData) {
invalidateNearCache(keyData);
return super.removeAsyncInternal(keyData);
}
@Override
protected Boolean tryRemoveInternal(long timeout, TimeUnit timeunit, Data keyData) {
invalidateNearCache(keyData);
return super.tryRemoveInternal(timeout, timeunit, keyData);
}
@Override
protected Boolean tryPutInternal(long timeout, TimeUnit timeunit, Data keyData, Data valueData) {
invalidateNearCache(keyData);
return super.tryPutInternal(timeout, timeunit, keyData, valueData);
}
@Override
protected V putInternal(long ttl, TimeUnit timeunit, Data keyData, Data valueData) {
invalidateNearCache(keyData);
return super.putInternal(ttl, timeunit, keyData, valueData);
}
@Override
protected void putTransientInternal(long ttl, TimeUnit timeunit, Data keyData, Data valueData) {
invalidateNearCache(keyData);
super.putTransientInternal(ttl, timeunit, keyData, valueData);
}
@Override
protected V putIfAbsentInternal(long ttl, TimeUnit timeunit, Data keyData, Data valueData) {
invalidateNearCache(keyData);
return super.putIfAbsentInternal(ttl, timeunit, keyData, valueData);
}
@Override
protected Boolean replaceIfSameInternal(Data keyData, Data oldValueData, Data newValueData) {
invalidateNearCache(keyData);
return super.replaceIfSameInternal(keyData, oldValueData, newValueData);
}
@Override
protected V replaceInternal(Data keyData, Data valueData) {
invalidateNearCache(keyData);
return super.replaceInternal(keyData, valueData);
}
@Override
protected void setInternal(long ttl, TimeUnit timeunit, Data keyData, Data valueData) {
invalidateNearCache(keyData);
super.setInternal(ttl, timeunit, keyData, valueData);
}
@Override
protected Boolean evictInternal(Data keyData) {
invalidateNearCache(keyData);
return super.evictInternal(keyData);
}
@Override
public void evictAll() {
nearCache.clear();
super.evictAll();
}
@Override
public void loadAll(boolean replaceExistingValues) {
if (replaceExistingValues) {
nearCache.clear();
}
super.loadAll(replaceExistingValues);
}
@Override
protected void loadAllInternal(boolean replaceExistingValues, List dataKeys) {
invalidateNearCache(dataKeys);
super.loadAllInternal(replaceExistingValues, dataKeys);
}
@Override
protected List getAllInternal(Map> partitionToKeyData, Map result) {
for (Entry> partitionKeyEntry : partitionToKeyData.entrySet()) {
List keyList = partitionKeyEntry.getValue();
Iterator iterator = keyList.iterator();
while (iterator.hasNext()) {
Data key = iterator.next();
Object cached = nearCache.get(key);
if (cached != null && NULL_OBJECT != cached) {
result.put((K) toObject(key), (V) cached);
iterator.remove();
}
}
}
List responses = super.getAllInternal(partitionToKeyData, result);
for (MapEntries entries : responses) {
for (Entry entry : entries.entries()) {
nearCache.put(entry.getKey(), entry.getValue());
}
}
//TODO: This returned value is not be used.
return responses;
}
@Override
public LocalMapStats getLocalMapStats() {
LocalMapStats localMapStats = super.getLocalMapStats();
NearCacheStats nearCacheStats = nearCache.getNearCacheStats();
((LocalMapStatsImpl) localMapStats).setNearCacheStats(((NearCacheStatsImpl) nearCacheStats));
return localMapStats;
}
@Override
protected Map prepareResult(MapEntries mapEntries) {
if (mapEntries.isEmpty()) {
return emptyMap();
}
Map result = createHashMap(mapEntries.size());
for (Entry dataEntry : mapEntries) {
Data keyData = dataEntry.getKey();
invalidateNearCache(keyData);
Data valueData = dataEntry.getValue();
K key = toObject(keyData);
result.put(key, toObject(valueData));
}
return result;
}
@Override
protected void putAllInternal(List> futures, MapEntries[] entriesPerPartition) {
for (int i = 0; i < entriesPerPartition.length; i++) {
MapEntries mapEntries = entriesPerPartition[i];
Collection> entries = mapEntries.entries();
for (Entry entry : entries) {
Data keyData = entry.getKey();
invalidateNearCache(keyData);
}
}
super.putAllInternal(futures, entriesPerPartition);
}
@Override
public void clear() {
nearCache.clear();
super.clear();
}
@Override
protected void onDestroy() {
removeNearCacheInvalidationListener();
nearCache.destroy();
super.onDestroy();
}
@Override
protected void onShutdown() {
removeNearCacheInvalidationListener();
nearCache.destroy();
super.onShutdown();
}
public NearCache getNearCache() {
return nearCache;
}
protected void invalidateNearCache(Data key) {
nearCache.remove(key);
}
protected void invalidateNearCache(Collection keys) {
if (keys == null || keys.isEmpty()) {
return;
}
for (Data key : keys) {
nearCache.remove(key);
}
}
protected void addNearCacheInvalidateListener() {
EventHandler handler = new InvalidationListener();
addNearCacheInvalidateListener(handler);
}
public void addNearCacheInvalidateListener(EventHandler handler) {
try {
MapAddNearCacheEntryListenerRequest addRequest = new MapAddNearCacheEntryListenerRequest(name, false);
BaseClientRemoveListenerRequest removeRequest = new MapRemoveEntryListenerRequest(name);
invalidationListenerId = registerListener(addRequest, removeRequest, handler);
} catch (Exception e) {
Logger.getLogger(ClientHeapNearCache.class).severe(
"-----------------\n Near Cache is not initialized!!! \n-----------------", e);
}
}
protected final class InvalidationListener implements EventHandler {
public InvalidationListener() {
}
@Override
public void handle(Object event) {
if (event instanceof BatchNearCacheInvalidation) {
List keys = ((BatchNearCacheInvalidation) event).getDataList();
for (Data key : keys) {
nearCache.remove(key);
}
return;
}
if (event instanceof SingleNearCacheInvalidation) {
Data key = ((SingleNearCacheInvalidation) event).getKey();
nearCache.remove(key);
return;
}
if (event instanceof CleaningNearCacheInvalidation) {
nearCache.clear();
return;
}
throw new IllegalArgumentException("Unexpected event received [" + event + ']');
}
@Override
public void beforeListenerRegister() {
nearCache.clear();
}
@Override
public void onListenerRegister() {
nearCache.clear();
}
}
protected void removeNearCacheInvalidationListener() {
String invalidationListenerId = this.invalidationListenerId;
if (invalidationListenerId == null) {
return;
}
deregisterListener(invalidationListenerId);
}
}