org.infinispan.cache.impl.CacheImpl Maven / Gradle / Ivy
package org.infinispan.cache.impl;
import org.infinispan.AdvancedCache;
import org.infinispan.Version;
import org.infinispan.atomic.Delta;
import org.infinispan.batch.BatchContainer;
import org.infinispan.commands.CommandsFactory;
import org.infinispan.commands.VisitableCommand;
import org.infinispan.commands.control.LockControlCommand;
import org.infinispan.commands.read.EntryRetrievalCommand;
import org.infinispan.commands.read.EntrySetCommand;
import org.infinispan.commands.read.GetCacheEntryCommand;
import org.infinispan.commands.read.GetKeyValueCommand;
import org.infinispan.commands.read.KeySetCommand;
import org.infinispan.commands.read.SizeCommand;
import org.infinispan.commands.read.ValuesCommand;
import org.infinispan.commands.remote.GetKeysInGroupCommand;
import org.infinispan.commands.write.ApplyDeltaCommand;
import org.infinispan.commands.write.ClearCommand;
import org.infinispan.commands.write.EvictCommand;
import org.infinispan.commands.write.PutKeyValueCommand;
import org.infinispan.commands.write.PutMapCommand;
import org.infinispan.commands.write.RemoveCommand;
import org.infinispan.commands.write.ReplaceCommand;
import org.infinispan.commands.write.ValueMatcher;
import org.infinispan.commons.CacheConfigurationException;
import org.infinispan.commons.CacheException;
import org.infinispan.commons.api.BasicCacheContainer;
import org.infinispan.commons.marshall.StreamingMarshaller;
import org.infinispan.commons.util.CloseableIterable;
import org.infinispan.commons.util.CloseableIteratorCollection;
import org.infinispan.commons.util.CloseableIteratorSet;
import org.infinispan.commons.util.Util;
import org.infinispan.commons.util.concurrent.AbstractInProcessNotifyingFuture;
import org.infinispan.commons.util.concurrent.NotifyingFuture;
import org.infinispan.commons.util.concurrent.NotifyingFutureImpl;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.format.PropertyFormatter;
import org.infinispan.configuration.global.GlobalConfiguration;
import org.infinispan.container.DataContainer;
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
import org.infinispan.context.InvocationContextContainer;
import org.infinispan.context.InvocationContextFactory;
import org.infinispan.context.impl.TxInvocationContext;
import org.infinispan.distribution.DistributionManager;
import org.infinispan.eviction.EvictionManager;
import org.infinispan.factories.ComponentRegistry;
import org.infinispan.factories.annotations.ComponentName;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.SurvivesRestarts;
import org.infinispan.filter.AcceptAllKeyValueFilter;
import org.infinispan.filter.KeyFilter;
import org.infinispan.filter.KeyValueFilter;
import org.infinispan.filter.NullValueConverter;
import org.infinispan.interceptors.InterceptorChain;
import org.infinispan.interceptors.base.CommandInterceptor;
import org.infinispan.iteration.EntryIterable;
import org.infinispan.iteration.impl.EntryRetriever;
import org.infinispan.jmx.annotations.DataType;
import org.infinispan.jmx.annotations.DisplayType;
import org.infinispan.jmx.annotations.MBean;
import org.infinispan.jmx.annotations.ManagedAttribute;
import org.infinispan.jmx.annotations.ManagedOperation;
import org.infinispan.lifecycle.ComponentStatus;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.metadata.EmbeddedMetadata;
import org.infinispan.metadata.Metadata;
import org.infinispan.notifications.cachelistener.CacheNotifier;
import org.infinispan.notifications.cachelistener.filter.CacheEventConverter;
import org.infinispan.notifications.cachelistener.filter.CacheEventFilter;
import org.infinispan.partitionhandling.AvailabilityMode;
import org.infinispan.partitionhandling.impl.PartitionHandlingManager;
import org.infinispan.remoting.rpc.RpcManager;
import org.infinispan.security.AuthorizationManager;
import org.infinispan.stats.Stats;
import org.infinispan.stats.impl.StatsImpl;
import org.infinispan.topology.LocalTopologyManager;
import org.infinispan.transaction.impl.TransactionCoordinator;
import org.infinispan.transaction.impl.TransactionTable;
import org.infinispan.transaction.xa.TransactionXaAdapter;
import org.infinispan.transaction.xa.recovery.RecoveryManager;
import org.infinispan.util.concurrent.locks.LockManager;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
import javax.transaction.InvalidTransactionException;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import javax.transaction.xa.XAResource;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.infinispan.context.Flag.*;
import static org.infinispan.context.InvocationContextFactory.UNBOUNDED;
import static org.infinispan.factories.KnownComponentNames.ASYNC_TRANSPORT_EXECUTOR;
import static org.infinispan.factories.KnownComponentNames.CACHE_MARSHALLER;
/**
* @author [email protected]
* @author Galder Zamarreño
* @author Sanne Grinovero
* @author Trustin Lee
* @since 4.0
*/
@SurvivesRestarts
@MBean(objectName = CacheImpl.OBJECT_NAME, description = "Component that represents an individual cache instance.")
public class CacheImpl implements AdvancedCache {
public static final String OBJECT_NAME = "Cache";
protected InvocationContextContainer icc;
protected InvocationContextFactory invocationContextFactory;
protected CommandsFactory commandsFactory;
protected InterceptorChain invoker;
protected Configuration config;
protected CacheNotifier notifier;
protected BatchContainer batchContainer;
protected ComponentRegistry componentRegistry;
protected TransactionManager transactionManager;
protected RpcManager rpcManager;
protected StreamingMarshaller marshaller;
protected Metadata defaultMetadata;
private final String name;
private EvictionManager evictionManager;
private DataContainer dataContainer;
private static final Log log = LogFactory.getLog(CacheImpl.class);
private static final boolean trace = log.isTraceEnabled();
private EmbeddedCacheManager cacheManager;
private LockManager lockManager;
private DistributionManager distributionManager;
private ExecutorService asyncExecutor;
private TransactionTable txTable;
private RecoveryManager recoveryManager;
private TransactionCoordinator txCoordinator;
private AuthorizationManager authorizationManager;
private PartitionHandlingManager partitionHandlingManager;
private GlobalConfiguration globalCfg;
private boolean isClassLoaderInContext;
private EntryRetriever entryRetriever;
private LocalTopologyManager localTopologyManager;
public CacheImpl(String name) {
this.name = name;
}
@Inject
public void injectDependencies(EvictionManager evictionManager,
InvocationContextFactory invocationContextFactory,
InvocationContextContainer icc,
CommandsFactory commandsFactory,
InterceptorChain interceptorChain,
Configuration configuration,
CacheNotifier notifier,
ComponentRegistry componentRegistry,
TransactionManager transactionManager,
BatchContainer batchContainer,
RpcManager rpcManager, DataContainer dataContainer,
@ComponentName(CACHE_MARSHALLER) StreamingMarshaller marshaller,
DistributionManager distributionManager,
EmbeddedCacheManager cacheManager,
@ComponentName(ASYNC_TRANSPORT_EXECUTOR) ExecutorService asyncExecutor,
TransactionTable txTable, RecoveryManager recoveryManager, TransactionCoordinator txCoordinator,
LockManager lockManager,
AuthorizationManager authorizationManager,
GlobalConfiguration globalCfg,
EntryRetriever entryRetriever,
PartitionHandlingManager partitionHandlingManager,
LocalTopologyManager localTopologyManager) {
this.commandsFactory = commandsFactory;
this.invoker = interceptorChain;
this.config = configuration;
this.notifier = notifier;
this.componentRegistry = componentRegistry;
this.transactionManager = transactionManager;
this.batchContainer = batchContainer;
this.rpcManager = rpcManager;
this.evictionManager = evictionManager;
this.dataContainer = dataContainer;
this.marshaller = marshaller;
this.cacheManager = cacheManager;
this.invocationContextFactory = invocationContextFactory;
this.icc = icc;
this.distributionManager = distributionManager;
this.asyncExecutor = asyncExecutor;
this.txTable = txTable;
this.recoveryManager = recoveryManager;
this.txCoordinator = txCoordinator;
this.lockManager = lockManager;
this.authorizationManager = authorizationManager;
this.globalCfg = globalCfg;
this.entryRetriever = entryRetriever;
this.partitionHandlingManager = partitionHandlingManager;
this.localTopologyManager = localTopologyManager;
}
private void assertKeyNotNull(Object key) {
if (key == null) {
throw new NullPointerException("Null keys are not supported!");
}
}
private void assertKeyValueNotNull(Object key, Object value) {
assertKeyNotNull(key);
if (value == null) {
throw new NullPointerException("Null values are not supported!");
}
}
private void assertValueNotNull(Object value) {
if (value == null) {
throw new NullPointerException("Null values are not supported!");
}
}
private void assertKeysNotNull(Map, ?> data) {
if (data == null) {
throw new NullPointerException("Expected map cannot be null");
}
for (Object key : data.keySet()) {
if (key == null) {
throw new NullPointerException("Null keys are not supported!");
}
}
}
// CacheSupport does not extend AdvancedCache, so it cannot really call up
// to the cache methods that take Metadata parameter. Since CacheSupport
// methods are declared final, the easiest is for CacheImpl to stop
// extending CacheSupport and implement the base methods directly.
@Override
public final V put(K key, V value) {
return put(key, value, defaultMetadata);
}
@Override
public final V put(K key, V value, long lifespan, TimeUnit unit) {
return put(key, value, lifespan, unit, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public final V putIfAbsent(K key, V value, long lifespan, TimeUnit unit) {
return putIfAbsent(key, value, lifespan, unit, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public final void putAll(Map extends K, ? extends V> map, long lifespan, TimeUnit unit) {
putAll(map, lifespan, unit, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public final V replace(K key, V value, long lifespan, TimeUnit unit) {
return replace(key, value, lifespan, unit, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public final boolean replace(K key, V oldValue, V value, long lifespan, TimeUnit unit) {
return replace(key, oldValue, value, lifespan, unit, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public final V putIfAbsent(K key, V value) {
return putIfAbsent(key, value, defaultMetadata);
}
@Override
public final boolean replace(K key, V oldValue, V newValue) {
return replace(key, oldValue, newValue, defaultMetadata);
}
@Override
public final V replace(K key, V value) {
return replace(key, value, defaultMetadata);
}
@Override
public final NotifyingFuture putAsync(K key, V value) {
return putAsync(key, value, defaultMetadata);
}
@Override
public final NotifyingFuture putAsync(K key, V value, long lifespan, TimeUnit unit) {
return putAsync(key, value, lifespan, unit, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public final NotifyingFuture putAllAsync(Map extends K, ? extends V> data) {
return putAllAsync(data, defaultMetadata, null, null);
}
@Override
public final NotifyingFuture putAllAsync(Map extends K, ? extends V> data, long lifespan, TimeUnit unit) {
return putAllAsync(data, lifespan, MILLISECONDS, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public final NotifyingFuture putIfAbsentAsync(K key, V value) {
return putIfAbsentAsync(key, value, defaultMetadata, null, null);
}
@Override
public final NotifyingFuture putIfAbsentAsync(K key, V value, long lifespan, TimeUnit unit) {
return putIfAbsentAsync(key, value, lifespan, unit, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public final NotifyingFuture replaceAsync(K key, V value) {
return replaceAsync(key, value, defaultMetadata, null, null);
}
@Override
public final NotifyingFuture replaceAsync(K key, V value, long lifespan, TimeUnit unit) {
return replaceAsync(key, value, lifespan, unit, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public final NotifyingFuture replaceAsync(K key, V oldValue, V newValue) {
return replaceAsync(key, oldValue, newValue, defaultMetadata, null, null);
}
@Override
public final NotifyingFuture replaceAsync(K key, V oldValue, V newValue, long lifespan, TimeUnit unit) {
return replaceAsync(key, oldValue, newValue, lifespan, unit, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public final void putAll(Map extends K, ? extends V> m) {
putAll(m, defaultMetadata, null, null);
}
@Override
public final boolean remove(Object key, Object value) {
return remove(key, value, null, null);
}
final boolean remove(Object key, Object value, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
InvocationContext ctx = getInvocationContextWithImplicitTransaction(false, explicitClassLoader, 1);
return removeInternal(key, value, explicitFlags, ctx);
}
private boolean removeInternal(Object key, Object value, EnumSet explicitFlags, InvocationContext ctx) {
assertKeyValueNotNull(key, value);
RemoveCommand command = commandsFactory.buildRemoveCommand(key, value, explicitFlags);
return (Boolean) executeCommandAndCommitIfNeeded(ctx, command);
}
@Override
public final int size() {
return size(null, null);
}
final int size(EnumSet explicitFlags, ClassLoader explicitClassLoader) {
SizeCommand command = commandsFactory.buildSizeCommand(explicitFlags);
return (Integer) invoker.invoke(getInvocationContextForRead(explicitClassLoader, UNBOUNDED), command);
}
@Override
public final boolean isEmpty() {
return isEmpty(null, null);
}
final boolean isEmpty(EnumSet explicitFlags, ClassLoader explicitClassLoader) {
try (CloseableIterable> iterable = filterEntries(AcceptAllKeyValueFilter.getInstance(),
explicitFlags, explicitClassLoader).converter(NullValueConverter.getInstance())) {
return !iterable.iterator().hasNext();
}
}
@Override
public final boolean containsKey(Object key) {
return containsKey(key, null, null);
}
final boolean containsKey(Object key, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
assertKeyNotNull(key);
InvocationContext ctx = getInvocationContextForRead(explicitClassLoader, 1);
GetKeyValueCommand command = commandsFactory.buildGetKeyValueCommand(key, explicitFlags);
Object response = invoker.invoke(ctx, command);
return response != null;
}
@Override
public final boolean containsValue(Object value) {
return containsValue(value, null, null);
}
final boolean containsValue(Object value, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
assertValueNotNull(value);
try (CloseableIterable> iterable = filterEntries(AcceptAllKeyValueFilter.getInstance(),
explicitFlags, explicitClassLoader)) {
for (CacheEntry entry : iterable) {
if (value.equals(entry.getValue())) {
return true;
}
}
}
return false;
}
@Override
public final V get(Object key) {
return get(key, null, null);
}
@SuppressWarnings("unchecked")
final V get(Object key, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
assertKeyNotNull(key);
InvocationContext ctx = getInvocationContextForRead(explicitClassLoader, 1);
GetKeyValueCommand command = commandsFactory.buildGetKeyValueCommand(key, explicitFlags);
return (V) invoker.invoke(ctx, command);
}
public final CacheEntry getCacheEntry(Object key, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
assertKeyNotNull(key);
InvocationContext ctx = getInvocationContextForRead(explicitClassLoader, 1);
GetCacheEntryCommand command = commandsFactory.buildGetCacheEntryCommand(key, explicitFlags);
Object ret = invoker.invoke(ctx, command);
return (CacheEntry) ret;
}
@Override
public final CacheEntry getCacheEntry(K key) {
return getCacheEntry(key, null, null);
}
@Override
public EntryIterable filterEntries(KeyValueFilter super K, ? super V> filter) {
return filterEntries(filter, null, null);
}
protected EntryIterable filterEntries(KeyValueFilter super K, ? super V> filter, EnumSet explicitFlags,
ClassLoader explicitClassLoader) {
// We need a read invocation context as the remove is done with its own context
InvocationContext ctx = getInvocationContextForRead(explicitClassLoader, UNBOUNDED);
EntryRetrievalCommand command = commandsFactory.buildEntryRetrievalCommand(explicitFlags, filter);
return (EntryIterable) invoker.invoke(ctx, command);
}
@Override
public Map getGroup(String groupName) {
return getGroup(groupName, null, null);
}
protected final Map getGroup(String groupName, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
InvocationContext ctx = getInvocationContextForRead(explicitClassLoader, UNBOUNDED);
return Collections.unmodifiableMap(internalGetGroup(groupName, explicitFlags, explicitClassLoader, ctx));
}
private Map internalGetGroup(String groupName, EnumSet explicitFlags, ClassLoader explicitClassLoader,
InvocationContext ctx) {
GetKeysInGroupCommand command = commandsFactory.buildGetKeysInGroupCommand(explicitFlags, groupName);
//noinspection unchecked
return (Map) invoker.invoke(ctx, command);
}
@Override
public void removeGroup(String groupName) {
removeGroup(groupName, null, null);
}
protected final void removeGroup(String groupName, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
if (transactionManager == null) {
nonTransactionalRemoveGroup(groupName, explicitFlags, explicitClassLoader);
} else {
transactionalRemoveGroup(groupName, explicitFlags, explicitClassLoader);
}
}
private void transactionalRemoveGroup(String groupName, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
final boolean onGoingTransaction = getOngoingTransaction() != null;
if (!onGoingTransaction) {
tryBegin();
}
try {
InvocationContext context = getInvocationContextWithImplicitTransaction(false, explicitClassLoader, UNBOUNDED);
Map keys = internalGetGroup(groupName, explicitFlags, explicitClassLoader, context);
EnumSet removeFlags = explicitFlags == null ? EnumSet.noneOf(Flag.class) : EnumSet.copyOf(explicitFlags);
removeFlags.add(IGNORE_RETURN_VALUES);
for (K key : keys.keySet()) {
removeInternal(key, removeFlags, context);
}
if (!onGoingTransaction) {
tryCommit();
}
} catch (RuntimeException e) {
if (!onGoingTransaction) {
tryRollback();
}
throw e;
}
}
private void nonTransactionalRemoveGroup(String groupName, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
InvocationContext context = getInvocationContextForRead(explicitClassLoader, UNBOUNDED);
Map keys = internalGetGroup(groupName, explicitFlags, explicitClassLoader, context);
EnumSet removeFlags = explicitFlags == null ? EnumSet.noneOf(Flag.class) : EnumSet.copyOf(explicitFlags);
removeFlags.add(IGNORE_RETURN_VALUES);
for (K key : keys.keySet()) {
//a new context is needed for remove since in the non-owners, the command is sent to the primary owner to be
//executed. If the context is already populated, it throws a ClassCastException because the wrapForRemove is
//not invoked.
remove(key, removeFlags, explicitClassLoader);
}
}
@Override
public final V remove(Object key) {
return remove(key, null, null);
}
final V remove(Object key, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
InvocationContext ctx = getInvocationContextWithImplicitTransaction(false, explicitClassLoader, 1);
return removeInternal(key, explicitFlags, ctx);
}
@SuppressWarnings("unchecked")
private V removeInternal(Object key, EnumSet explicitFlags, InvocationContext ctx) {
assertKeyNotNull(key);
RemoveCommand command = commandsFactory.buildRemoveCommand(key, null, explicitFlags);
return (V) executeCommandAndCommitIfNeeded(ctx, command);
}
@ManagedOperation(
description = "Clears the cache",
displayName = "Clears the cache", name = "clear"
)
public final void clearOperation() {
//if we have a TM then this cache is transactional.
// We shouldn't rely on the auto-commit option as it might be disabled, so always start a tm.
if (transactionManager != null) {
try {
transactionManager.begin();
clear(null, null);
transactionManager.commit();
} catch (Throwable e) {
throw new CacheException(e);
}
} else {
clear(null, null);
}
}
@Override
public final void clear() {
clear(null, null);
}
final void clear(EnumSet explicitFlags, ClassLoader explicitClassLoader) {
InvocationContext ctx = getInvocationContextWithImplicitTransaction(false, explicitClassLoader, UNBOUNDED);
clearInternal(explicitFlags, ctx);
}
private void clearInternal(EnumSet explicitFlags, InvocationContext ctx) {
ClearCommand command = commandsFactory.buildClearCommand(explicitFlags);
executeCommandAndCommitIfNeeded(ctx, command);
}
@Override
public CloseableIteratorSet keySet() {
return keySet(null, null);
}
@SuppressWarnings("unchecked")
CloseableIteratorSet keySet(EnumSet explicitFlags, ClassLoader explicitClassLoader) {
InvocationContext ctx = getInvocationContextForRead(explicitClassLoader, UNBOUNDED);
KeySetCommand command = commandsFactory.buildKeySetCommand(explicitFlags);
return (CloseableIteratorSet) invoker.invoke(ctx, command);
}
@Override
public CloseableIteratorCollection values() {
return values(null, null);
}
@SuppressWarnings("unchecked")
CloseableIteratorCollection values(EnumSet explicitFlags, ClassLoader explicitClassLoader) {
InvocationContext ctx = getInvocationContextForRead(explicitClassLoader, UNBOUNDED);
ValuesCommand command = commandsFactory.buildValuesCommand(explicitFlags);
return (CloseableIteratorCollection) invoker.invoke(ctx, command);
}
@Override
public CloseableIteratorSet> entrySet() {
return entrySet(null, null);
}
@SuppressWarnings("unchecked")
CloseableIteratorSet> entrySet(EnumSet explicitFlags, ClassLoader explicitClassLoader) {
InvocationContext ctx = getInvocationContextForRead(explicitClassLoader, UNBOUNDED);
EntrySetCommand command = commandsFactory.buildEntrySetCommand(explicitFlags);
return (CloseableIteratorSet>) invoker.invoke(ctx, command);
}
@Override
public final void putForExternalRead(K key, V value) {
putForExternalRead(key, value, null, null);
}
@Override
public void putForExternalRead(K key, V value, long lifespan, TimeUnit lifespanUnit) {
putForExternalRead(key, value, lifespan, lifespanUnit, defaultMetadata.maxIdle(), MILLISECONDS);
}
@Override
public void putForExternalRead(K key, V value, long lifespan, TimeUnit lifespanUnit, long maxIdleTime, TimeUnit idleTimeUnit) {
Metadata metadata = new EmbeddedMetadata.Builder()
.lifespan(lifespan, lifespanUnit)
.maxIdle(maxIdleTime, idleTimeUnit).build();
putForExternalRead(key, value, metadata);
}
@Override
public void putForExternalRead(K key, V value, Metadata metadata) {
Metadata merged = applyDefaultMetadata(metadata);
putForExternalRead(key, value, merged, null, null);
}
final void putForExternalRead(K key, V value, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
putForExternalRead(key, value, defaultMetadata, explicitFlags, explicitClassLoader);
}
final void putForExternalRead(K key, V value, Metadata metadata, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
Transaction ongoingTransaction = null;
try {
ongoingTransaction = suspendOngoingTransactionIfExists();
EnumSet flags = EnumSet.of(FAIL_SILENTLY, FORCE_ASYNCHRONOUS, ZERO_LOCK_ACQUISITION_TIMEOUT, PUT_FOR_EXTERNAL_READ);
if (explicitFlags != null && !explicitFlags.isEmpty()) {
flags.addAll(explicitFlags);
}
// if the entry exists then this should be a no-op.
putIfAbsent(key, value, metadata, flags, explicitClassLoader);
} catch (Exception e) {
if (log.isDebugEnabled()) log.debug("Caught exception while doing putForExternalRead()", e);
}
finally {
resumePreviousOngoingTransaction(ongoingTransaction, true, "Had problems trying to resume a transaction after putForExternalRead()");
}
}
@Override
public final void evict(K key) {
evict(key, null, null);
}
final void evict(K key, EnumSet explicitFlags, ClassLoader explicitClassLoader) {
assertKeyNotNull(key);
InvocationContext ctx = createSingleKeyNonTxInvocationContext(explicitClassLoader);
EvictCommand command = commandsFactory.buildEvictCommand(key, explicitFlags);
invoker.invoke(ctx, command);
}
private InvocationContext createSingleKeyNonTxInvocationContext(ClassLoader explicitClassLoader) {
InvocationContext ctx = invocationContextFactory.createSingleKeyNonTxInvocationContext();
return setInvocationContextClassLoader(ctx, explicitClassLoader);
}
@Override
public Configuration getCacheConfiguration() {
return config;
}
@Override
public void addListener(Object listener) {
notifier.addListener(listener);
}
@Override
public void addListener(Object listener, KeyFilter super K> filter) {
notifier.addListener(listener, filter);
}
@Override
public void addListener(Object listener, CacheEventFilter super K, ? super V> filter,
CacheEventConverter super K, ? super V, C> converter) {
notifier.addListener(listener, filter, converter);
}
@Override
public void removeListener(Object listener) {
notifier.removeListener(listener);
}
@Override
public Set
© 2015 - 2025 Weber Informatics LLC | Privacy Policy