org.infinispan.interceptors.distribution.DistributionBulkInterceptor Maven / Gradle / Ivy
package org.infinispan.interceptors.distribution;
import org.infinispan.AdvancedCache;
import org.infinispan.Cache;
import org.infinispan.CacheSet;
import org.infinispan.CacheStream;
import org.infinispan.commands.LocalFlagAffectedCommand;
import org.infinispan.commands.read.AbstractCloseableIteratorCollection;
import org.infinispan.commands.read.EntrySetCommand;
import org.infinispan.commands.read.KeySetCommand;
import org.infinispan.commons.util.CloseableIterator;
import org.infinispan.commons.util.CloseableIteratorMapper;
import org.infinispan.commons.util.CloseableSpliterator;
import org.infinispan.commons.util.Closeables;
import org.infinispan.container.entries.CacheEntry;
import org.infinispan.container.entries.ForwardingCacheEntry;
import org.infinispan.context.Flag;
import org.infinispan.context.InvocationContext;
import org.infinispan.context.impl.LocalTxInvocationContext;
import org.infinispan.distribution.DistributionManager;
import org.infinispan.factories.ComponentRegistry;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.interceptors.base.CommandInterceptor;
import org.infinispan.stream.StreamMarshalling;
import org.infinispan.stream.impl.ClusterStreamManager;
import org.infinispan.stream.impl.DistributedCacheStream;
import org.infinispan.stream.impl.RemovableCloseableIterator;
import org.infinispan.stream.impl.RemovableIterator;
import org.infinispan.stream.impl.tx.TxClusterStreamManager;
import org.infinispan.stream.impl.tx.TxDistributedCacheStream;
import java.util.Iterator;
import java.util.Map;
import java.util.Spliterator;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import static org.infinispan.factories.KnownComponentNames.ASYNC_OPERATIONS_EXECUTOR;
/**
* Interceptor that handles bulk entrySet and keySet commands when using in a distributed/replicated environment.
* This interceptor produces backing collections for either method and a distributed stream for either which leverages
* distributed processing through the cluster.
* @param The key type of entries
* @param The value type of entries
* @deprecated Since 8.2, no longer public API.
*/
@Deprecated
public class DistributionBulkInterceptor extends CommandInterceptor {
private Cache cache;
@Inject
public void inject(Cache cache) {
this.cache = cache;
}
@Override
public CacheSet> visitEntrySetCommand(InvocationContext ctx, EntrySetCommand command) throws Throwable {
CacheSet> entrySet = (CacheSet>) super.visitEntrySetCommand(ctx, command);
if (!command.hasFlag(Flag.CACHE_MODE_LOCAL)) {
if (ctx.isInTxScope()) {
return new TxBackingEntrySet<>(getCacheWithFlags(cache, command), entrySet, command,
(LocalTxInvocationContext) ctx);
} else {
return new BackingEntrySet<>(getCacheWithFlags(cache, command), entrySet, command);
}
}
return entrySet;
}
protected static class BackingEntrySet extends AbstractCloseableIteratorCollection, K, V>
implements CacheSet> {
protected final CacheSet> entrySet;
protected final LocalFlagAffectedCommand command;
private BackingEntrySet(Cache cache, CacheSet> entrySet, LocalFlagAffectedCommand command) {
super(cache);
this.entrySet = entrySet;
this.command = command;
}
@Override
public CloseableIterator> iterator() {
return new CloseableIteratorMapper<>(new RemovableCloseableIterator<>(Closeables.iterator(stream()), cache,
CacheEntry::getKey), e -> new EntryWrapper<>(cache, e));
}
@Override
public CloseableSpliterator> spliterator() {
return Closeables.spliterator(stream());
}
@Override
public boolean contains(Object o) {
Map.Entry entry = toEntry(o);
if (entry != null) {
V value = cache.get(entry.getKey());
return value != null && value.equals(entry.getValue());
}
return false;
}
@Override
public boolean remove(Object o) {
Map.Entry entry = toEntry(o);
if (entry != null) {
return cache.remove(entry.getKey(), entry.getValue());
}
return false;
}
private Map.Entry toEntry(Object obj) {
if (obj instanceof Map.Entry) {
return (Map.Entry) obj;
} else {
return null;
}
}
@Override
public CacheStream> stream() {
AdvancedCache advancedCache = cache.getAdvancedCache();
ComponentRegistry registry = advancedCache.getComponentRegistry();
CacheStream> cacheStream = new DistributedCacheStream>(
cache.getCacheManager().getAddress(), false, advancedCache.getDistributionManager(),
() -> entrySet.stream(), registry.getComponent(ClusterStreamManager.class),
!command.hasFlag(Flag.SKIP_CACHE_LOAD),
cache.getCacheConfiguration().clustering().stateTransfer().chunkSize(),
registry.getComponent(Executor.class, ASYNC_OPERATIONS_EXECUTOR), registry) {
@Override
public Iterator> iterator() {
if (intermediateOperations.isEmpty()) {
return new RemovableIterator<>(super.iterator(), cache, e -> e.getKey());
}
return super.iterator();
}
};
return applyTimeOut(cacheStream, cache);
}
@Override
public CacheStream> parallelStream() {
AdvancedCache advancedCache = cache.getAdvancedCache();
ComponentRegistry registry = advancedCache.getComponentRegistry();
CacheStream> cacheStream = new DistributedCacheStream<>(cache.getCacheManager().getAddress(),
true, advancedCache.getDistributionManager(), () -> entrySet.parallelStream(),
registry.getComponent(ClusterStreamManager.class), !command.hasFlag(Flag.SKIP_CACHE_LOAD),
cache.getCacheConfiguration().clustering().stateTransfer().chunkSize(),
registry.getComponent(Executor.class, ASYNC_OPERATIONS_EXECUTOR), registry);
return applyTimeOut(cacheStream, cache);
}
}
protected static class TxBackingEntrySet extends BackingEntrySet {
private final LocalTxInvocationContext ctx;
private TxBackingEntrySet(Cache cache, CacheSet> entrySet, LocalFlagAffectedCommand command,
LocalTxInvocationContext ctx) {
super(cache, entrySet, command);
this.ctx = ctx;
}
@Override
public CacheStream> stream() {
AdvancedCache advancedCache = cache.getAdvancedCache();
DistributionManager dm = advancedCache.getDistributionManager();
ComponentRegistry registry = advancedCache.getComponentRegistry();
ClusterStreamManager realManager = registry.getComponent(ClusterStreamManager.class);
TxClusterStreamManager txManager = new TxClusterStreamManager<>(realManager, ctx, dm.getConsistentHash());
CacheStream> cacheStream = new TxDistributedCacheStream<>(cache.getCacheManager().getAddress(),
false, dm, () -> entrySet.stream(), txManager, !command.hasFlag(Flag.SKIP_CACHE_LOAD),
cache.getCacheConfiguration().clustering().stateTransfer().chunkSize(),
registry.getComponent(Executor.class, ASYNC_OPERATIONS_EXECUTOR), registry, ctx);
return applyTimeOut(cacheStream, cache);
}
@Override
public CacheStream> parallelStream() {
AdvancedCache advancedCache = cache.getAdvancedCache();
DistributionManager dm = advancedCache.getDistributionManager();
ComponentRegistry registry = advancedCache.getComponentRegistry();
ClusterStreamManager realManager = registry.getComponent(ClusterStreamManager.class);
TxClusterStreamManager txManager = new TxClusterStreamManager<>(realManager, ctx, dm.getConsistentHash());
CacheStream> cacheStream = new TxDistributedCacheStream<>(cache.getCacheManager().getAddress(),
true, dm, () -> entrySet.parallelStream(), txManager, !command.hasFlag(Flag.SKIP_CACHE_LOAD),
cache.getCacheConfiguration().clustering().stateTransfer().chunkSize(),
registry.getComponent(Executor.class, ASYNC_OPERATIONS_EXECUTOR), registry, ctx);
return applyTimeOut(cacheStream, cache);
}
}
private static CacheStream applyTimeOut(CacheStream stream, Cache, ?> cache) {
return stream.timeout(cache.getCacheConfiguration().clustering().sync().replTimeout(),
TimeUnit.MILLISECONDS);
}
/**
* Wrapper for CacheEntry(s) that can be used to update the cache when it's value is set.
* @param The key type
* @param The value type
*/
private static class EntryWrapper extends ForwardingCacheEntry {
private final Cache cache;
private final CacheEntry entry;
public EntryWrapper(Cache cache, CacheEntry entry) {
this.cache = cache;
this.entry = entry;
}
@Override
protected CacheEntry delegate() {
return entry;
}
@Override
public V setValue(V value) {
cache.put(entry.getKey(), value);
return super.setValue(value);
}
}
@Override
public CacheSet visitKeySetCommand(InvocationContext ctx, KeySetCommand command) throws Throwable {
if (!command.hasFlag(Flag.CACHE_MODE_LOCAL)) {
if (ctx.isInTxScope()) {
return new TxBackingKeySet<>(getCacheWithFlags(cache, command), cache.getAdvancedCache().withFlags(
Flag.CACHE_MODE_LOCAL).cacheEntrySet(), command, (LocalTxInvocationContext) ctx);
} else {
return new BackingKeySet<>(getCacheWithFlags(cache, command), cache.getAdvancedCache().withFlags(
Flag.CACHE_MODE_LOCAL).cacheEntrySet(), command);
}
}
return (CacheSet) super.visitKeySetCommand(ctx, command);
}
protected static class BackingKeySet extends AbstractCloseableIteratorCollection
implements CacheSet {
protected final CacheSet> entrySet;
protected final LocalFlagAffectedCommand command;
public BackingKeySet(Cache cache, CacheSet> entrySet, LocalFlagAffectedCommand command) {
super(cache);
this.entrySet = entrySet;
this.command = command;
}
@Override
public CloseableIterator iterator() {
return new RemovableCloseableIterator(Closeables.iterator(stream()), cache, Function.identity());
}
@Override
public boolean contains(Object o) {
return cache.containsKey(o);
}
@Override
public boolean remove(Object o) {
return cache.remove(o) != null;
}
@Override
public CloseableSpliterator spliterator() {
return Closeables.spliterator(iterator(), Long.MAX_VALUE,
Spliterator.CONCURRENT | Spliterator.DISTINCT | Spliterator.NONNULL);
}
@Override
public CacheStream stream() {
AdvancedCache advancedCache = cache.getAdvancedCache();
ComponentRegistry registry = advancedCache.getComponentRegistry();
return new DistributedCacheStream(cache.getCacheManager().getAddress(), false,
advancedCache.getDistributionManager(), () -> entrySet.stream(),
registry.getComponent(ClusterStreamManager.class), !command.hasFlag(Flag.SKIP_CACHE_LOAD),
cache.getCacheConfiguration().clustering().stateTransfer().chunkSize(),
registry.getComponent(Executor.class, ASYNC_OPERATIONS_EXECUTOR), registry,
StreamMarshalling.entryToKeyFunction()) {
@Override
public Iterator iterator() {
// The act of mapping to key requires 1 intermediate operation
if (intermediateOperations.size() == 1) {
return new RemovableIterator<>(super.iterator(), cache, Function.identity());
}
return super.iterator();
}
};
}
@Override
public CacheStream parallelStream() {
AdvancedCache advancedCache = cache.getAdvancedCache();
ComponentRegistry registry = advancedCache.getComponentRegistry();
return new DistributedCacheStream<>(cache.getCacheManager().getAddress(), true,
advancedCache.getDistributionManager(), () -> entrySet.parallelStream(),
registry.getComponent(ClusterStreamManager.class), !command.hasFlag(Flag.SKIP_CACHE_LOAD),
cache.getCacheConfiguration().clustering().stateTransfer().chunkSize(),
registry.getComponent(Executor.class, ASYNC_OPERATIONS_EXECUTOR), registry,
StreamMarshalling.entryToKeyFunction());
}
}
private static class TxBackingKeySet extends BackingKeySet {
private final LocalTxInvocationContext ctx;
public TxBackingKeySet(Cache cache, CacheSet> entrySet, LocalFlagAffectedCommand command,
LocalTxInvocationContext ctx) {
super(cache, entrySet, command);
this.ctx = ctx;
}
@Override
public CacheStream stream() {
AdvancedCache advancedCache = cache.getAdvancedCache();
DistributionManager dm = advancedCache.getDistributionManager();
ComponentRegistry registry = advancedCache.getComponentRegistry();
ClusterStreamManager realManager = registry.getComponent(ClusterStreamManager.class);
TxClusterStreamManager txManager = new TxClusterStreamManager<>(realManager, ctx, dm.getConsistentHash());
return new TxDistributedCacheStream<>(cache.getCacheManager().getAddress(), false,
dm, () -> entrySet.stream(), txManager, !command.hasFlag(Flag.SKIP_CACHE_LOAD),
cache.getCacheConfiguration().clustering().stateTransfer().chunkSize(),
registry.getComponent(Executor.class, ASYNC_OPERATIONS_EXECUTOR), registry,
StreamMarshalling.entryToKeyFunction(), ctx);
}
@Override
public CacheStream parallelStream() {
AdvancedCache advancedCache = cache.getAdvancedCache();
DistributionManager dm = advancedCache.getDistributionManager();
ComponentRegistry registry = advancedCache.getComponentRegistry();
ClusterStreamManager realManager = registry.getComponent(ClusterStreamManager.class);
TxClusterStreamManager txManager = new TxClusterStreamManager<>(realManager, ctx, dm.getConsistentHash());
return new TxDistributedCacheStream<>(cache.getCacheManager().getAddress(), true,
dm, () -> entrySet.parallelStream(), txManager, !command.hasFlag(Flag.SKIP_CACHE_LOAD),
cache.getCacheConfiguration().clustering().stateTransfer().chunkSize(),
registry.getComponent(Executor.class, ASYNC_OPERATIONS_EXECUTOR), registry,
StreamMarshalling.entryToKeyFunction(), ctx);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy