com.tangosol.internal.util.DefaultAsyncNamedCache Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of coherence Show documentation
Show all versions of coherence Show documentation
Oracle Coherence Community Edition
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* https://oss.oracle.com/licenses/upl.
*/
package com.tangosol.internal.util;
import com.oracle.coherence.common.util.Options;
import com.tangosol.internal.util.processor.CacheProcessors;
import com.tangosol.net.AsyncNamedCache;
import com.tangosol.net.CacheService;
import com.tangosol.net.Member;
import com.tangosol.net.NamedCache;
import com.tangosol.net.NamedMap;
import com.tangosol.net.PartitionedService;
import com.tangosol.net.partition.PartitionSet;
import com.tangosol.util.Filter;
import com.tangosol.util.InvocableMap;
import com.tangosol.util.InvocableMap.StreamingAggregator;
import com.tangosol.util.aggregator.AsynchronousAggregator;
import com.tangosol.util.filter.PartitionedFilter;
import com.tangosol.util.processor.AsynchronousProcessor;
import com.tangosol.util.processor.SingleEntryAsynchronousProcessor;
import com.tangosol.util.processor.StreamingAsynchronousProcessor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
/**
* Default implementation of the {@link AsyncNamedCache} API.
*
* @author as 2015.01.15
*/
public class DefaultAsyncNamedCache
implements AsyncNamedCache
{
// ---- constructors ----------------------------------------------------
/**
* Construct DefaultAsyncNamedCache instance.
*
* @param cache the wrapped NamedCache to delegate invocations to
*/
public DefaultAsyncNamedCache(NamedCache cache)
{
// NOTE: while not strictly required any longer, we need to keep this
// constructor in order to preserve binary compatibility with 12.2.1.0.0
this(cache, null);
}
/**
* Construct DefaultAsyncNamedCache instance.
*
* @param cache the wrapped NamedCache to delegate invocations to
* @param options the configuration options
*/
public DefaultAsyncNamedCache(NamedCache cache, AsyncNamedCache.Option[] options)
{
m_cache = cache;
m_options = Options.from(AsyncNamedCache.Option.class, options);
}
// ---- AsyncNamedCache interface ---------------------------------------
@Override
public NamedCache getNamedCache()
{
return m_cache;
}
// ---- AsyncNamedMap interface -----------------------------------------
@Override
public NamedMap getNamedMap()
{
return m_cache;
}
@Override
public CompletableFuture>> entrySet(Filter> filter)
{
// optimized implementation that runs query against individual partitions
// in parallel and aggregates the results
if (m_cache.getCacheService() instanceof PartitionedService && !(filter instanceof PartitionedFilter))
{
int cParts = ((PartitionedService) m_cache.getCacheService()).getPartitionCount();
PartitionSet parts = new PartitionSet(cParts);
List>>> futures = new ArrayList<>(cParts);
for (int i = 0; i < cParts; i++)
{
parts.add(i);
futures.add(invokeAll(new PartitionedFilter<>(filter, parts), new AsynchronousProcessor<>(CacheProcessors.binaryGet(), i))
.thenApply(Map::entrySet));
parts.remove(i);
}
CompletableFuture>> result = new CompletableFuture<>();
CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new))
.whenComplete((v, err) ->
{
if (err != null)
{
result.completeExceptionally(err);
}
else
{
Set> set = new HashSet<>();
futures.forEach(f -> f.thenAccept(set::addAll));
result.complete(set);
}
});
return result;
}
else
{
return AsyncNamedCache.super.entrySet(filter);
}
}
@Override
public CompletableFuture entrySet(Filter> filter, Consumer super Map.Entry extends K, ? extends V>> callback)
{
// optimized implementation that runs query against individual partitions
// in parallel and aggregates the results
if (m_cache.getCacheService() instanceof PartitionedService && !(filter instanceof PartitionedFilter))
{
int cParts = ((PartitionedService) m_cache.getCacheService()).getPartitionCount();
PartitionSet parts = new PartitionSet(cParts);
List> futures = new ArrayList<>(cParts);
for (int i = 0; i < cParts; i++)
{
parts.add(i);
futures.add(invokeAll(new PartitionedFilter<>(filter, parts),
new StreamingAsynchronousProcessor<>(CacheProcessors.binaryGet(), i, callback),
callback)); // needed to ensure the streaming invokeAll is called!
parts.remove(i);
}
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
}
else
{
return AsyncNamedCache.super.entrySet(filter, callback);
}
}
// ---- AsyncInvocableMap interface -------------------------------------
@Override
public CompletableFuture invoke(K key,
InvocableMap.EntryProcessor processor)
{
SingleEntryAsynchronousProcessor asyncProcessor =
instantiateSingleEntryAsyncProcessor(processor);
m_cache.invoke(key, asyncProcessor);
return asyncProcessor.getCompletableFuture();
}
@Override
public CompletableFuture