/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.ignite;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.configuration.Configuration;
import javax.cache.event.CacheEntryRemovedListener;
import javax.cache.expiry.ExpiryPolicy;
import javax.cache.integration.CacheLoader;
import javax.cache.integration.CacheWriter;
import javax.cache.processor.EntryProcessor;
import javax.cache.processor.EntryProcessorException;
import javax.cache.processor.EntryProcessorResult;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheEntry;
import org.apache.ignite.cache.CacheEntryProcessor;
import org.apache.ignite.cache.CacheMetrics;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.CachePeekMode;
import org.apache.ignite.cache.PartitionLossPolicy;
import org.apache.ignite.cache.ReadRepairStrategy;
import org.apache.ignite.cache.query.FieldsQueryCursor;
import org.apache.ignite.cache.query.Query;
import org.apache.ignite.cache.query.QueryCursor;
import org.apache.ignite.cache.query.QueryDetailMetrics;
import org.apache.ignite.cache.query.QueryMetrics;
import org.apache.ignite.cache.query.ScanQuery;
import org.apache.ignite.cache.query.SpiQuery;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.cache.query.TextQuery;
import org.apache.ignite.cache.store.CacheStore;
import org.apache.ignite.cluster.ClusterGroup;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.events.CacheConsistencyViolationEvent;
import org.apache.ignite.events.EventType;
import org.apache.ignite.lang.IgniteAsyncSupport;
import org.apache.ignite.lang.IgniteAsyncSupported;
import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.lang.IgniteBiPredicate;
import org.apache.ignite.lang.IgniteClosure;
import org.apache.ignite.lang.IgniteExperimental;
import org.apache.ignite.lang.IgniteFuture;
import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionException;
import org.apache.ignite.transactions.TransactionHeuristicException;
import org.apache.ignite.transactions.TransactionIsolation;
import org.apache.ignite.transactions.TransactionRollbackException;
import org.apache.ignite.transactions.TransactionTimeoutException;
import org.jetbrains.annotations.Nullable;

/**
 * Main entry point for all <b>Data Grid APIs.</b> You can get a named cache by calling {@link Ignite#cache(String)}
 * method.
 * <h1 class="header">Functionality</h1>
 * This API extends {@link javax.cache.Cache} API which contains {@code JCache (JSR107)} cache functionality
 * and documentation. In addition to {@link javax.cache.Cache} functionality this API provides:
 * <ul>
 * <li>Ability to perform basic atomic Map-like operations available on {@code JCache} API.</li>
 * <li>Ability to bulk load cache via {@link #loadCache(IgniteBiPredicate, Object...)} method.
 * <li>Distributed lock functionality via {@link #lock(Object)} methods.</li>
 * <li>Ability to query cache using Predicate, SQL, and Text queries via {@link #query(Query)} method.</li>
 * <li>Ability to collect cache and query metrics.</li>
 * <li>Ability to force partition rebalancing via {@link #rebalance()} methopd
 *  (in case if delayed rebalancing was configured.)</li>
 * <li>Ability to peek into memory without doing actual {@code get(...)} from cache
 *  via {@link #localPeek(Object, CachePeekMode...)} methods</li>
 * <li>Ability to evict and promote entries from on-heap to off-heap or swap and back.</li>
 * <li>Ability to atomically collocate compute and data via {@link #invoke(Object, CacheEntryProcessor, Object...)}
 *  methods.</li>
 * </ul>
 * <h1 class="header">Transactions</h1>
 * Cache API supports transactions. You can group and set of cache methods within a transaction
 * to provide ACID-compliant behavior. See {@link IgniteTransactions} for more information.
 * <br>
 * Methods which can be used inside transaction (put, get...) throw TransactionException.
 * See {@link TransactionException} for more information.
 *
 * @param <K> Cache key type.
 * @param <V> Cache value type.
 */
public interface IgniteCache<K, V> extends javax.cache.Cache<K, V>, IgniteAsyncSupport {
    /** {@inheritDoc} */
    @Deprecated
    @Override public IgniteCache<K, V> withAsync();

    /** {@inheritDoc} */
    @Override public <C extends Configuration<K, V>> C getConfiguration(Class<C> clazz);

    /**
     * Returns cache with the specified expired policy set. This policy will be used for each operation
     * invoked on the returned cache.
     * <p>
     * This method does not modify existing cache instance.
     *
     * @param plc Expire policy to use.
     * @return Cache instance with the specified expiry policy set.
     */
    public IgniteCache<K, V> withExpiryPolicy(ExpiryPolicy plc);

    /**
     * @return Cache with read-through write-through behavior disabled.
     */
    public IgniteCache<K, V> withSkipStore();

    /**
     * @return Cache with no-retries behavior enabled.
     */
    public IgniteCache<K, V> withNoRetries();

    /**
     * Gets an instance of {@code IgniteCache} that will be allowed to execute cache read operations
     * regardless of partition loss policy.
     *
     * @return Cache without partition loss protection.
     */
    public IgniteCache<K, V> withPartitionRecover();

    /**
     * <b>This is an experimental API.</b>
     * <p>
     * Gets an instance of {@code IgniteCache} that will perform backup nodes check on each get attempt.
     * <p>
     * Read Repair means that each backup node will be checked to have the same entry as the primary node has.
     * <p>
     * In case consistency violations were found, the values across the topology will be replaced by repaired values
     * according to the chosen strategy, see {@link ReadRepairStrategy} for the details.
     * <p>
     * A consistency violation exception will be thrown when the repair is impossible.
     * <p>
     * {@link CacheConsistencyViolationEvent} will be recorded for each violation in case it's configured as recordable.
     * <ul>
     *  <li>For transactional caches, values will be repaired:
     *  <ul>
     *      <li>automatically for transactions that have {@link TransactionConcurrency#OPTIMISTIC} concurrency mode
     *          or {@link TransactionIsolation#READ_COMMITTED} isolation level,</li>
     *      <li>at commit() phase for transactions that have {@link TransactionConcurrency#PESSIMISTIC} concurrency mode
     *          and isolation level other than {@link TransactionIsolation#READ_COMMITTED}</li>
     *  </ul>
     *  Warning:
     *  <p>
     *  This proxy usage does not guarantee "all copies check" in case the value have been already cached inside the transaction.
     *  In case you don't use a READ_COMMITTED isolation mode and already have a cached value, for example have already
     *  read the value or performed a write, you'll just get the cached value.
     *  </li>
     *  <li>For atomic caches, values will be repaired automatically.
     *  <p>
     *  Warning:
     *  <p>
     *  Due to the nature of an atomic cache, false-positive results can be observed. For example, an attempt to check
     *  consistency under cache's loading may lead to a consistency violation exception. By default, the implementation tries
     *  to check the given key three times. The number of attempts can be changed using
     *  {@link IgniteSystemProperties#IGNITE_NEAR_GET_MAX_REMAPS} property.
     *  </li>
     * </ul>
     * A consistency check is incompatible with the following cache configurations:
     * <ul>
     *     <li>Caches without backups.</li>
     *     <li>Near caches.</li>
     *     <li>Caches that use "read-through" mode.</li>
     * </ul>
     * <p>
     * Full list of repairable methods:
     * <ul>
     * <li>{@link IgniteCache#containsKey} &amp;&amp; {@link IgniteCache#containsKeyAsync}</li>
     * <li>{@link IgniteCache#containsKeys} &amp;&amp; {@link IgniteCache#containsKeysAsync}</li>
     * <li>{@link IgniteCache#getEntry} &amp;&amp; {@link IgniteCache#getEntryAsync}</li>
     * <li>{@link IgniteCache#getEntries} &amp;&amp; {@link IgniteCache#getEntriesAsync}</li>
     * <li>{@link IgniteCache#get} &amp;&amp; {@link IgniteCache#getAsync}</li>
     * <li>{@link IgniteCache#getAll} &amp;&amp; {@link IgniteCache#getAllAsync}</li>
     * </ul>
     * @param strategy Read Repair strategy.
     * @return Cache with explicit consistency check on each read and repair if necessary.
     */
    @IgniteExperimental
    public IgniteCache<K, V> withReadRepair(ReadRepairStrategy strategy);

    /**
     * Returns cache that will operate with binary objects.
     * <p>
     * Cache returned by this method will not be forced to deserialize binary objects,
     * so keys and values will be returned from cache API methods without changes. Therefore,
     * signature of the cache can contain only following types:
     * <ul>
     *     <li><code>org.apache.ignite.binary.BinaryObject</code> for binary classes</li>
     *     <li>All primitives (byte, int, ...) and there boxed versions (Byte, Integer, ...)</li>
     *     <li>Arrays of primitives (byte[], int[], ...)</li>
     *     <li>{@link String} and array of {@link String}s</li>
     *     <li>{@link UUID} and array of {@link UUID}s</li>
     *     <li>{@link Date} and array of {@link Date}s</li>
     *     <li>{@link Timestamp} and array of {@link Timestamp}s</li>
     *     <li>Enums and array of enums</li>
     *     <li>
     *         Maps, collections and array of objects (but objects inside
     *         them will still be converted if they are binary)
     *     </li>
     * </ul>
     * <p>
     * For example, if you use {@link Integer} as a key and {@code Value} class as a value
     * (which will be stored in binary format), you should acquire following projection
     * to avoid deserialization:
     * <pre>
     * IgniteCache&lt;Integer, BinaryObject&gt; prj = cache.withKeepBinary();
     *
     * // Value is not deserialized and returned in binary format.
     * BinaryObject po = prj.get(1);
     * </pre>
     * <p>
     * Note that this method makes sense only if cache is working in binary mode
     * if default marshaller is used.
     * If not, this method is no-op and will return current cache.
     *
     * @param <V1> Type of the cache value binary objects.
     * @param <K1> Type of the cache key.
     * @return New cache instance for binary objects.
     */
    public <K1, V1> IgniteCache<K1, V1> withKeepBinary();

    /**
     * Executes {@link #localLoadCache(IgniteBiPredicate, Object...)} on all cache nodes.
     *
     * @param p Optional predicate (may be {@code null}). If provided, will be used to
     *      filter values loaded from storage before they are put into cache.
     * @param args Optional user arguments to be passed into
     *      {@link CacheStore#loadCache(IgniteBiInClosure, Object...)} method.
     * @throws CacheException If loading failed.
     */
    @IgniteAsyncSupported
    public void loadCache(@Nullable IgniteBiPredicate<K, V> p, @Nullable Object... args) throws CacheException;

    /**
     * Asynchronously executes {@link #localLoadCache(IgniteBiPredicate, Object...)} on all cache nodes.
     *
     * @param p Optional predicate (may be {@code null}). If provided, will be used to
     *      filter values loaded from storage before they are put into cache.
     * @param args Optional user arguments to be passed into
     *      {@link CacheStore#loadCache(IgniteBiInClosure, Object...)} method.
     * @return a Future representing pending completion of the cache loading.
     * @throws CacheException If loading failed.
     */
    public IgniteFuture<Void> loadCacheAsync(@Nullable IgniteBiPredicate<K, V> p, @Nullable Object... args)
        throws CacheException;

    /**
     * Delegates to {@link CacheStore#loadCache(IgniteBiInClosure,Object...)} method
     * to load state from the underlying persistent storage. The loaded values
     * will then be given to the optionally passed in predicate, and, if the predicate returns
     * {@code true}, will be stored in cache. If predicate is {@code null}, then
     * all loaded values will be stored in cache.
     * <p>
     * Note that this method does not receive keys as a parameter, so it is up to
     * {@link CacheStore} implementation to provide all the data to be loaded.
     * <p>
     * This method is not transactional and may end up loading a stale value into
     * cache if another thread has updated the value immediately after it has been
     * loaded. It is mostly useful when pre-loading the cache from underlying
     * data store before start, or for read-only caches.
     *
     * @param p Optional predicate (may be {@code null}). If provided, will be used to
     *      filter values to be put into cache.
     * @param args Optional user arguments to be passed into
     *      {@link CacheStore#loadCache(IgniteBiInClosure, Object...)} method.
     * @throws CacheException If loading failed.
     */
    @IgniteAsyncSupported
    public void localLoadCache(@Nullable IgniteBiPredicate<K, V> p, @Nullable Object... args) throws CacheException;

    /**
     * Asynchronously loads state from the underlying persistent storage by delegating
     * to {@link CacheStore#loadCache(IgniteBiInClosure,Object...)} method. The loaded values
     * will then be given to the optionally passed in predicate, and, if the predicate returns
     * {@code true}, will be stored in cache. If predicate is {@code null}, then
     * all loaded values will be stored in cache.
     * <p>
     * Note that this method does not receive keys as a parameter, so it is up to
     * {@link CacheStore} implementation to provide all the data to be loaded.
     * <p>
     * This method is not transactional and may end up loading a stale value into
     * cache if another thread has updated the value immediately after it has been
     * loaded. It is mostly useful when pre-loading the cache from underlying
     * data store before start, or for read-only caches.
     *
     * @param p Optional predicate (may be {@code null}). If provided, will be used to
     *      filter values to be put into cache.
     * @param args Optional user arguments to be passed into
     *      {@link CacheStore#loadCache(IgniteBiInClosure, Object...)} method.
     * @return a Future representing pending completion of the cache loading.
     * @throws CacheException If loading failed.
     */
    public IgniteFuture<Void> localLoadCacheAsync(@Nullable IgniteBiPredicate<K, V> p, @Nullable Object... args)
        throws CacheException;

    /**
     * Stores given key-value pair in cache only if cache had no previous mapping for it. If cache
     * previously contained value for the given key, then this value is returned.
     * In case of {@link CacheMode#PARTITIONED} or {@link CacheMode#REPLICATED} caches,
     * the value will be loaded from the primary node, which in its turn may load the value
     * from the swap storage, and consecutively, if it's not in swap,
     * from the underlying persistent storage. If value has to be loaded from persistent
     * storage, {@link CacheStore#load(Object)} method will be used.
     * <p>
     * If the returned value is not needed, method {@link #putIfAbsent(Object, Object)} should
     * always be used instead of this one to avoid the overhead associated with returning of the
     * previous value.
     * <p>
     * If write-through is enabled, the stored value will be persisted to {@link CacheStore}
     * via {@link CacheStore#write(javax.cache.Cache.Entry)} method.
     * <h2 class="header">Transactions</h2>
     * This method is transactional and will enlist the entry into ongoing transaction
     * if there is one.
     *
     * @param key Key to store in cache.
     * @param val Value to be associated with the given key.
     * @return Previously contained value regardless of whether put happened or not ({@code null} if there was no
     *      previous value).
     * @throws NullPointerException If either key or value are {@code null}.
     * @throws CacheException If put operation failed.
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    public V getAndPutIfAbsent(K key, V val) throws CacheException, TransactionException;

    /**
     * Asynchronously stores given key-value pair in cache only if cache had no previous mapping for it. If cache
     * previously contained value for the given key, then this value is returned.
     * In case of {@link CacheMode#PARTITIONED} or {@link CacheMode#REPLICATED} caches,
     * the value will be loaded from the primary node, which in its turn may load the value
     * from the swap storage, and consecutively, if it's not in swap,
     * from the underlying persistent storage. If value has to be loaded from persistent
     * storage, {@link CacheStore#load(Object)} method will be used.
     * <p>
     * If the returned value is not needed, method {@link #putIfAbsentAsync(Object, Object)} should
     * always be used instead of this one to avoid the overhead associated with returning of the
     * previous value.
     * <p>
     * If write-through is enabled, the stored value will be persisted to {@link CacheStore}
     * via {@link CacheStore#write(javax.cache.Cache.Entry)} method.
     * <h2 class="header">Transactions</h2>
     * This method is transactional and will enlist the entry into ongoing transaction
     * if there is one.
     *
     * @param key Key to store in cache.
     * @param val Value to be associated with the given key.
     * @return a Future representing pending completion of the operation.
     * @throws NullPointerException If either key or value are {@code null}.
     * @throws CacheException If put operation failed.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<V> getAndPutIfAbsentAsync(K key, V val) throws CacheException, TransactionException;

    /**
     * Creates a {@link Lock} instance associated with passed key.
     * This method does not acquire lock immediately, you have to call appropriate method on returned instance.
     * Returned lock does not support {@link Lock#newCondition()} method,
     * other methods defined in {@link Lock} are supported.
     *
     * @param key Key for lock.
     * @return New lock instance associated with passed key.
     * @see Lock#lock()
     * @see Lock#tryLock(long, TimeUnit)
     */
    public Lock lock(K key);

    /**
     * Creates a {@link Lock} instance associated with passed keys.
     * This method does not acquire lock immediately, you have to call appropriate method on returned instance.
     * Returned lock does not support {@link Lock#newCondition()} method,
     * other methods defined in {@link Lock} are supported.
     *
     * @param keys Keys for lock.
     * @return New lock instance associated with passed key.
     * @see Lock#lock()
     * @see Lock#tryLock(long, TimeUnit)
     * @deprecated It is recommended to use {@link Ignite#reentrantLock(String, boolean, boolean, boolean)} instead.
     *      This method will be removed in future releases.
     */
    public Lock lockAll(Collection<? extends K> keys);

    /**
     * Checks if specified key is locked.
     * <p>
     * This is a local in-VM operation and does not involve any network trips
     * or access to persistent storage in any way.
     *
     * @param key Key to check.
     * @param byCurrThread If {@code true} method will check that current thread owns a lock on this key, otherwise
     *     will check that any thread on any node owns a lock on this key.
     * @return {@code True} if lock is owned by some node.
     */
    public boolean isLocalLocked(K key, boolean byCurrThread);

    /**
     * Queries cache. Accepts any subclass of {@link Query} interface.
     * See also {@link #query(SqlFieldsQuery)}.
     *
     * @param qry Query.
     * @param <R> Type of the query result.
     * @return Cursor.
     * @see ScanQuery
     * @see SqlFieldsQuery
     * @see TextQuery
     * @see SpiQuery
     *
     */
    public <R> QueryCursor<R> query(Query<R> qry);

    /**
     * Queries cache. Accepts {@link SqlFieldsQuery} class.
     *
     * @param qry SqlFieldsQuery.
     * @return Cursor.
     * @see SqlFieldsQuery
     */
    public FieldsQueryCursor<List<?>> query(SqlFieldsQuery qry);

    /**
     * Queries the cache transforming the entries on the server nodes. Can be used, for example,
     * to avoid network overhead in case only one field out of the large is required by client.
     * <p>
     * Currently transformers are supported ONLY for {@link ScanQuery}. Passing any other
     * subclass of {@link Query} interface to this method will end up with
     * {@link UnsupportedOperationException}.
     *
     * @param qry Query.
     * @param transformer Transformer.
     * @param <T> Type of the initial query result.
     * @param <R> Type of the transformed query result.
     * @return Cursor.
     */
    public <T, R> QueryCursor<R> query(Query<T> qry, IgniteClosure<T, R> transformer);

    /**
     * Allows for iteration over local cache entries.
     *
     * @param peekModes Peek modes.
     * @return Iterable over local cache entries.
     * @throws CacheException If failed.
     */
    public Iterable<Entry<K, V>> localEntries(CachePeekMode... peekModes) throws CacheException;

    /**
     * Gets query metrics.
     *
     * @return Metrics.
     */
    public QueryMetrics queryMetrics();

    /**
     * Reset query metrics.
     */
    public void resetQueryMetrics();

    /**
     * Gets query detail metrics.
     * Query detail metrics could be enabled via {@link CacheConfiguration#setQueryDetailMetricsSize(int)} method.
     *
     * @return Metrics.
     */
    public Collection<? extends QueryDetailMetrics> queryDetailMetrics();

    /**
     * Reset query detail metrics.
     */
    public void resetQueryDetailMetrics();

    /**
     * Attempts to evict all entries associated with keys. Note,
     * that entry will be evicted only if it's not used (not
     * participating in any locks or transactions).
     *
     * @param keys Keys to evict.
     */
    public void localEvict(Collection<? extends K> keys);

    /**
     * Peeks at a value in the local storage using an optional peek mode.
     * <p>
     * This method will not load a value from the configured {@link CacheStore} or from a remote node.
     * <h2 class="header">Transactions</h2>
     * This method does not participate in any transactions.
     *
     * @param key Entry key.
     * @param peekModes Peek modes.
     * @return Peeked value, or {@code null} if not found.
     * @throws NullPointerException If key is {@code null}.
     */
    public V localPeek(K key, CachePeekMode... peekModes);

    /**
     * Gets the number of all entries cached across all nodes. By default, if {@code peekModes} value isn't defined,
     * only size of primary copies across all nodes will be returned. This behavior is identical to calling
     * this method with {@link CachePeekMode#PRIMARY} peek mode.
     * <p>
     * NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
     *
     * @param peekModes Optional peek modes. If not provided, then total cache size is returned.
     * @return Cache size across all nodes.
     * @throws CacheException On error.
     */
    @IgniteAsyncSupported
    public int size(CachePeekMode... peekModes) throws CacheException;

    /**
     * Asynchronously gets the number of all entries cached across all nodes. By default,
     * if {@code peekModes} value isn't defined, only size of primary copies across all nodes will be returned.
     * This behavior is identical to calling this method with {@link CachePeekMode#PRIMARY} peek mode.
     * <p>
     * NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
     *
     * @param peekModes Optional peek modes. If not provided, then total cache size is returned.
     * @return a Future representing pending completion of the operation.
     * @throws CacheException On error.
     */
    public IgniteFuture<Integer> sizeAsync(CachePeekMode... peekModes) throws CacheException;

    /**
     * Gets the number of all entries cached across all nodes as a long value. By default, if {@code peekModes} value
     * isn't defined, only size of primary copies across all nodes will be returned. This behavior is identical to
     * calling this method with {@link CachePeekMode#PRIMARY} peek mode.
     * <p>
     * NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
     *
     * @param peekModes Optional peek modes. If not provided, then total cache size is returned.
     * @return Cache size across all nodes.
     * @throws CacheException On error.
     */
    @IgniteAsyncSupported
    public long sizeLong(CachePeekMode... peekModes) throws CacheException;

    /**
     * Asynchronously gets the number of all entries cached across all nodes as a long value. By default,
     * if {@code peekModes} value isn't defined, only size of primary copies across all nodes will be returned.
     * This behavior is identical to calling this method with {@link CachePeekMode#PRIMARY} peek mode.
     * <p>
     * NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
     *
     * @param peekModes Optional peek modes. If not provided, then total cache size is returned.
     * @return a Future representing pending completion of the operation.
     * @throws CacheException On error.
     */
    public IgniteFuture<Long> sizeLongAsync(CachePeekMode... peekModes) throws CacheException;

    /**
     * Gets the number of all entries cached in a partition as a long value. By default, if {@code peekModes} value
     * isn't defined, only size of primary copies across all nodes will be returned. This behavior is identical to
     * calling this method with {@link CachePeekMode#PRIMARY} peek mode.
     * <p>
     * NOTE: this operation is distributed and will query all participating nodes for their partition cache sizes.
     *
     * @param partition partition.
     * @param peekModes Optional peek modes. If not provided, then total partition cache size is returned.
     * @return Partition cache size across all nodes.
     * @throws CacheException On error.
     */
    @IgniteAsyncSupported
    public long sizeLong(int partition, CachePeekMode... peekModes) throws CacheException;

    /**
     * Asynchronously gets the number of all entries cached in a partition as a long value. By default, if {@code peekModes} value
     * isn't defined, only size of primary copies across all nodes will be returned. This behavior is identical to
     * calling this method with {@link CachePeekMode#PRIMARY} peek mode.
     * <p>
     * NOTE: this operation is distributed and will query all participating nodes for their partition cache sizes.
     *
     * @param partition partition.
     * @param peekModes Optional peek modes. If not provided, then total partition cache size is returned.
     * @return a Future representing pending completion of the operation.
     * @throws CacheException On error.
     */
    public IgniteFuture<Long> sizeLongAsync(int partition, CachePeekMode... peekModes) throws CacheException;

    /**
     * Gets the number of all entries cached on this node. By default, if {@code peekModes} value isn't defined,
     * only size of primary copies will be returned. This behavior is identical to calling this method with
     * {@link CachePeekMode#PRIMARY} peek mode.
     *
     * @param peekModes Optional peek modes. If not provided, then total cache size is returned.
     * @return Cache size on this node.
     */
    public int localSize(CachePeekMode... peekModes);

    /**
     * Gets the number of all entries cached on this node as a long value. By default, if {@code peekModes} value isn't
     * defined, only size of primary copies will be returned. This behavior is identical to calling this method with
     * {@link CachePeekMode#PRIMARY} peek mode.
     *
     * @param peekModes Optional peek modes. If not provided, then total cache size is returned.
     * @return Cache size on this node.
     */
    public long localSizeLong(CachePeekMode... peekModes);

    /**
     * Gets the number of all entries cached on this node for the partition as a long value. By default, if {@code peekModes} value isn't
     * defined, only size of primary copies will be returned. This behavior is identical to calling this method with
     * {@link CachePeekMode#PRIMARY} peek mode.
     *
     * @param partition partition.
     * @param peekModes Optional peek modes. If not provided, then total cache size is returned.
     * @return Cache size on this node.
     */
    public long localSizeLong(int partition, CachePeekMode... peekModes);

    /**
     * Asynchronously invokes each {@link EntryProcessor} from map's values against the correspondent
     * {@link javax.cache.Cache.Entry} specified by map's key set.
     * <p>
     * If an {@link javax.cache.Cache.Entry} does not exist for the specified key, an attempt is made
     * to load it (if a loader is configured) or a surrogate {@link javax.cache.Cache.Entry},
     * consisting of the key and a value of null is provided.
     * <p>
     * The order that the entries for the keys are processed is undefined.
     * Implementations may choose to process the entries in any order, including
     * concurrently.  Furthermore there is no guarantee implementations will
     * use the same {@link EntryProcessor} instance to process each entry, as
     * the case may be in a non-local cache topology.
     * <p>
     * The result of executing the {@link EntryProcessor} is returned in the future as a
     * {@link Map} of {@link EntryProcessorResult}s, one result per key. Should the
     * {@link EntryProcessor} or Caching implementation throw an exception, the
     * exception is wrapped and re-thrown when a call to
     * {@link javax.cache.processor.EntryProcessorResult#get()} is made.
     * <p>
     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for information on
     * system behavior in crash scenarios for atomic caches.
     * <p>
     * Keys are locked in the order in which they appear in map. It is caller's responsibility to
     * make sure keys always follow same order, such as by using {@link java.util.TreeMap}. Using unordered map,
     * such as {@link java.util.HashMap}, while calling this method in parallel <b>will lead to deadlock</b>.
     *
     * @param map Map containing keys and entry processors to be applied to values.
     * @param args Additional arguments to pass to the {@link EntryProcessor}.
     * @param <T> Type of the cache entry processing result.
     * @return The map of {@link EntryProcessorResult}s of the processing per key,
     *      if any, defined by the {@link EntryProcessor} implementation.  No mappings
     *      will be returned for {@link EntryProcessor}s that return a
     *      <code>null</code> value for a key.
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    public <T> Map<K, EntryProcessorResult<T>> invokeAll(Map<? extends K, ? extends EntryProcessor<K, V, T>> map,
        Object... args) throws TransactionException;

    /**
     * Asynchronous version of the {@link #invokeAll(Map, Object...)} method.
     *
     * @param map Map containing keys and entry processors to be applied to values.
     * @param args Additional arguments to pass to the {@link EntryProcessor}.
     * @param <T> Type of the cache entry processing result.
     * @return a Future representing pending completion of the operation. See more about future result
     * at the {@link #invokeAll(Map, Object...)}.
     * @throws TransactionException If operation within transaction is failed.
     */
    public <T> IgniteFuture<Map<K, EntryProcessorResult<T>>> invokeAllAsync(
        Map<? extends K, ? extends EntryProcessor<K, V, T>> map, Object... args) throws TransactionException;

    /**
     * {@inheritDoc}
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public V get(K key) throws TransactionException;

    /**
     * Asynchronously gets an entry from the cache.
     * <p>
     * If the cache is configured to use read-through, and a future result would be null
     * because the entry is missing from the cache, the Cache's {@link CacheLoader}
     * is called in an attempt to load the entry.
     *
     * @param key Key.
     * @return a Future representing pending completion of the operation.
     */
    public IgniteFuture<V> getAsync(K key);

    /**
     * Gets an entry from the cache.
     * <p>
     * If the cache is configured to use read-through, and get would return null
     * because the entry is missing from the cache, the Cache's {@link CacheLoader}
     * is called in an attempt to load the entry.
     *
     * @param key The key whose associated value is to be returned.
     * @return The element, or null, if it does not exist.
     * @throws IllegalStateException If the cache is {@link #isClosed()}.
     * @throws NullPointerException If the key is {@code null}.
     * @throws CacheException If there is a problem fetching the value.
     * @throws ClassCastException If the implementation is configured to perform
     * runtime-type-checking, and the key or value types are incompatible with those that have been
     * configured for the {@link Cache}.
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    public CacheEntry<K, V> getEntry(K key) throws TransactionException;

    /**
     * Asynchronously gets an entry from the cache.
     * <p>
     * If the cache is configured to use read-through, and a future result would be null
     * because the entry is missing from the cache, the Cache's {@link CacheLoader}
     * is called in an attempt to load the entry.
     *
     * @param key The key whose associated value is to be returned.
     * @return a Future representing pending completion of the operation.
     * @throws IllegalStateException If the cache is {@link #isClosed()}.
     * @throws NullPointerException If the key is {@code null}.
     * @throws CacheException If there is a problem fetching the value.
     * @throws ClassCastException If the implementation is configured to perform
     * runtime-type-checking, and the key or value types are incompatible with those that have been
     * configured for the {@link Cache}.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<CacheEntry<K, V>> getEntryAsync(K key) throws TransactionException;

    /**
     * {@inheritDoc}
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public Map<K, V> getAll(Set<? extends K> keys) throws TransactionException;

    /**
     * Asynchronously gets a collection of entries from the {@link Cache}, returning them as
     * {@link Map} of the values associated with the set of keys requested.
     * <p>
     * If the cache is configured read-through, and a future result for a key would
     * be null because an entry is missing from the cache, the Cache's
     * {@link CacheLoader} is called in an attempt to load the entry. If an
     * entry cannot be loaded for a given key, the key will not be present in
     * the returned Map.
     *
     * @param keys Keys set.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Map<K, V>> getAllAsync(Set<? extends K> keys) throws TransactionException;

    /**
     * Gets a collection of entries from the {@link Cache}.
     * <p>
     * If the cache is configured read-through, and a get for a key would
     * return null because an entry is missing from the cache, the Cache's
     * {@link CacheLoader} is called in an attempt to load the entry. If an
     * entry cannot be loaded for a given key, the key will not be present in
     * the returned Collection.
     *
     * @param keys The keys whose associated values are to be returned.
     * @return A collection of entries that were found for the given keys. Entries not found
     *         in the cache are not in the returned collection.
     * @throws NullPointerException If keys is null or if keys contains a {@code null}.
     * @throws IllegalStateException If the cache is {@link #isClosed()}.
     * @throws CacheException If there is a problem fetching the values.
     * @throws ClassCastException If the implementation is configured to perform
     * runtime-type-checking, and the key or value types are incompatible with those that have been
     * configured for the {@link Cache}.
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    public Collection<CacheEntry<K, V>> getEntries(Set<? extends K> keys) throws TransactionException;

    /**
     * Asynchronously gets a collection of entries from the {@link Cache}.
     * <p>
     * If the cache is configured read-through, and a future result for a key would
     * be null because an entry is missing from the cache, the Cache's
     * {@link CacheLoader} is called in an attempt to load the entry. If an
     * entry cannot be loaded for a given key, the key will not be present in
     * the returned Collection.
     *
     * @param keys The keys whose associated values are to be returned.
     * @return a Future representing pending completion of the operation.
     * @throws NullPointerException If keys is null or if keys contains a {@code null}.
     * @throws IllegalStateException If the cache is {@link #isClosed()}.
     * @throws CacheException If there is a problem fetching the values.
     * @throws ClassCastException If the implementation is configured to perform
     * runtime-type-checking, and the key or value types are incompatible with those that have been
     * configured for the {@link Cache}.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Collection<CacheEntry<K, V>>> getEntriesAsync(Set<? extends K> keys) throws TransactionException;

    /**
     * Gets values from cache. Will bypass started transaction, if any, i.e. will not enlist entries
     * and will not lock any keys if pessimistic transaction is started by thread.
     *
     * @param keys The keys whose associated values are to be returned.
     * @return A map of entries that were found for the given keys.
     */
    @IgniteAsyncSupported
    public Map<K, V> getAllOutTx(Set<? extends K> keys);

    /**
     * Asynchronously gets values from cache. Will bypass started transaction, if any, i.e. will not enlist entries
     * and will not lock any keys if pessimistic transaction is started by thread.
     *
     * @param keys The keys whose associated values are to be returned.
     * @return a Future representing pending completion of the operation.
     */
    public IgniteFuture<Map<K, V>> getAllOutTxAsync(Set<? extends K> keys);

    /**
     * {@inheritDoc}
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public boolean containsKey(K key) throws TransactionException;

    /**
     * Asynchronously determines if the {@link Cache} contains an entry for the specified key.
     * <p>
     * More formally, future result is <tt>true</tt> if and only if this cache contains a
     * mapping for a key <tt>k</tt> such that <tt>key.equals(k)</tt>.
     * (There can be at most one such mapping.)
     *
     * @param key Key.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Boolean> containsKeyAsync(K key) throws TransactionException;

    /**
     * Determines if the {@link Cache} contains entries for the specified keys.
     *
     * @param keys Key whose presence in this cache is to be tested.
     * @return {@code True} if this cache contains a mapping for the specified keys.
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    public boolean containsKeys(Set<? extends K> keys) throws TransactionException;

    /**
     * Asynchronously determines if the {@link Cache} contains entries for the specified keys.
     *
     * @param keys Key whose presence in this cache is to be tested.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Boolean> containsKeysAsync(Set<? extends K> keys) throws TransactionException;

    /**
     * {@inheritDoc}
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public void put(K key, V val) throws TransactionException;

    /**
     * Asynchronously associates the specified value with the specified key in the cache.
     * <p>
     * If the {@link Cache} previously contained a mapping for the key, the old
     * value is replaced by the specified value.  (A cache <tt>c</tt> is said to
     * contain a mapping for a key <tt>k</tt> if and only if {@link
     * #containsKey(Object) c.containsKey(k)} would return <tt>true</tt>.)
     *
     * @param key Key.
     * @param val Value.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Void> putAsync(K key, V val) throws TransactionException;

    /**
     * {@inheritDoc}
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public V getAndPut(K key, V val) throws TransactionException;

    /**
     * Asynchronously associates the specified value with the specified key in this cache,
     * returning an existing value if one existed as the future result.
     * <p>
     * If the cache previously contained a mapping for
     * the key, the old value is replaced by the specified value.  (A cache
     * <tt>c</tt> is said to contain a mapping for a key <tt>k</tt> if and only
     * if {@link #containsKey(Object) c.containsKey(k)} would return
     * <tt>true</tt>.)
     * <p>
     * The previous value is returned as the future result, or future result is null if there was no value associated
     * with the key previously.
     *
     * @param key Key.
     * @param val Value.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<V> getAndPutAsync(K key, V val) throws TransactionException;

    /**
     * {@inheritDoc}
     * <p>
     * Keys are locked in the order in which they appear in map. It is caller's responsibility to
     * make sure keys always follow same order, such as by using {@link java.util.TreeMap}. Using unordered map,
     * such as {@link java.util.HashMap}, while calling this method in parallel <b>will lead to deadlock</b>.
     *
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public void putAll(Map<? extends K, ? extends V> map) throws TransactionException;

    /**
     * Asynchronously copies all of the entries from the specified map to the {@link Cache}.
     * <p>
     * The effect of this call is equivalent to that of calling
     * {@link #putAsync(Object, Object)}  putAsync(k, v)} on this cache once for each mapping
     * from key <tt>k</tt> to value <tt>v</tt> in the specified map.
     * <p>
     * The order in which the individual puts occur is undefined.
     * <p>
     * The behavior of this operation is undefined if entries in the cache
     * corresponding to entries in the map are modified or removed while this
     * operation is in progress. or if map is modified while the operation is in
     * progress.
     * <p>
     * In Default Consistency mode, individual puts occur atomically but not
     * the entire putAll.  Listeners may observe individual updates.
     * <p>
     * Keys are locked in the order in which they appear in map. It is caller's responsibility to
     * make sure keys always follow same order, such as by using {@link java.util.TreeMap}. Using unordered map,
     * such as {@link java.util.HashMap}, while calling this method in parallel <b>will lead to deadlock</b>.
     *
     * @param map Map containing keys and values to put into the cache.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Void> putAllAsync(Map<? extends K, ? extends V> map) throws TransactionException;

    /**
     * {@inheritDoc}
     * <p>
     * For {@link CacheAtomicityMode#ATOMIC} return
     * value on primary node crash may be incorrect because of the automatic retries. It is recommended
     * to disable retries with {@link #withNoRetries()} and manually restore primary-backup
     * consistency in case of update failure.
     *
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public boolean putIfAbsent(K key, V val) throws TransactionException;

    /**
     * Asynchronously associates the specified key with the given value if it is
     * not already associated with a value.
     * <p>
     * For {@link CacheAtomicityMode#ATOMIC} return
     * value on primary node crash may be incorrect because of the automatic retries. It is recommended
     * to disable retries with {@link #withNoRetries()} and manually restore primary-backup
     * consistency in case of update failure.
     *
     * @param key Key.
     * @param val Value.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionTimeoutException If operation performs within transaction and timeout occurred.
     * @throws TransactionRollbackException If operation performs within transaction that automatically rolled back.
     * @throws TransactionHeuristicException If operation performs within transaction that entered an unknown state.
     */
    public IgniteFuture<Boolean> putIfAbsentAsync(K key, V val);

    /**
     * {@inheritDoc}
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public boolean remove(K key) throws TransactionException;

    /**
     * Asynchronously removes the mapping for a key from this cache if it is present.
     * <p>
     * More formally, if this cache contains a mapping from key <tt>k</tt> to
     * value <tt>v</tt> such that
     * <code>(key==null ?  k==null : key.equals(k))</code>, that mapping is removed.
     * (The cache can contain at most one such mapping.)
     *
     * <p>A future result is <tt>true</tt> if this cache previously associated the key,
     * or <tt>false</tt> if the cache contained no mapping for the key.
     * <p>
     * The cache will not contain a mapping for the specified key once the
     * returned future is completed.
     *
     * @param key Key.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Boolean> removeAsync(K key) throws TransactionException;

    /**
     * {@inheritDoc}
     * <p>
     * For {@link CacheAtomicityMode#ATOMIC} return
     * value on primary node crash may be incorrect because of the automatic retries. It is recommended
     * to disable retries with {@link #withNoRetries()} and manually restore primary-backup
     * consistency in case of update failure.
     *
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public boolean remove(K key, V oldVal) throws TransactionException;

    /**
     * Asynchronously removes the mapping for a key only if currently mapped to the
     * given value.
     * <p>
     * For {@link CacheAtomicityMode#ATOMIC} return
     * value on primary node crash may be incorrect because of the automatic retries. It is recommended
     * to disable retries with {@link #withNoRetries()} and manually restore primary-backup
     * consistency in case of update failure.
     *
     * @param key Key.
     * @param oldVal Old value.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Boolean> removeAsync(K key, V oldVal) throws TransactionException;

    /**
     * {@inheritDoc}
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public V getAndRemove(K key) throws TransactionException;

    /**
     * Asynchronously removes the entry for a key only if currently mapped to some
     * value.
     *
     * @param key Key.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<V> getAndRemoveAsync(K key) throws TransactionException;

    /**
     * {@inheritDoc}
     * <p>
     * For {@link CacheAtomicityMode#ATOMIC} return
     * value on primary node crash may be incorrect because of the automatic retries. It is recommended
     * to disable retries with {@link #withNoRetries()} and manually restore primary-backup
     * consistency in case of update failure.
     *
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public boolean replace(K key, V oldVal, V newVal) throws TransactionException;

    /**
     * Asynchronous version of the {@link #replace(Object, Object, Object)}.
     * <p>
     * For {@link CacheAtomicityMode#ATOMIC} return
     * value on primary node crash may be incorrect because of the automatic retries. It is recommended
     * to disable retries with {@link #withNoRetries()} and manually restore primary-backup
     * consistency in case of update failure.
     *
     * @param key Key.
     * @param oldVal Old value.
     * @param newVal New value.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Boolean> replaceAsync(K key, V oldVal, V newVal) throws TransactionException;

    /**
     * {@inheritDoc}
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public boolean replace(K key, V val) throws TransactionException;

    /**
     * Asynchronously replaces the entry for a key only if currently mapped to a
     * given value.
     *
     * @param key Key.
     * @param val Value.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Boolean> replaceAsync(K key, V val) throws TransactionException;

    /**
     * {@inheritDoc}
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public V getAndReplace(K key, V val) throws TransactionException;

    /**
     * Asynchronously replaces the value for a given key if and only if there is a
     * value currently mapped by the key.
     *
     * @param key Key.
     * @param val Value.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionTimeoutException If operation performs within transaction and timeout occurred.
     * @throws TransactionRollbackException If operation performs within transaction that automatically rolled back.
     * @throws TransactionHeuristicException If operation performs within transaction that entered an unknown state.
     */
    public IgniteFuture<V> getAndReplaceAsync(K key, V val);

    /**
     * {@inheritDoc}
     * <p>
     * Keys are locked in the order in which they appear in key set. It is caller's responsibility to
     * make sure keys always follow same order, such as by using {@link java.util.TreeSet}. Using unordered map,
     * such as {@link java.util.HashSet}, while calling this method in parallel <b>will lead to deadlock</b>.
     *
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public void removeAll(Set<? extends K> keys) throws TransactionException;

    /**
     * Asynchronously removes entries for the specified keys.
     * <p>
     * The order in which the individual entries are removed is undefined.
     * <p>
     * For every entry in the key set, the following are called:
     * <ul>
     *   <li>any registered {@link CacheEntryRemovedListener}s</li>
     *   <li>if the cache is a write-through cache, the {@link CacheWriter}</li>
     * </ul>
     * If the key set is empty, the {@link CacheWriter} is not called.
     * <p>
     * Keys are locked in the order in which they appear in key set. It is caller's responsibility to
     * make sure keys always follow same order, such as by using {@link java.util.TreeSet}. Using unordered map,
     * such as {@link java.util.HashSet}, while calling this method in parallel <b>will lead to deadlock</b>.
     *
     * @param keys Keys set.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public IgniteFuture<Void> removeAllAsync(Set<? extends K> keys) throws TransactionException;

    /**
     * Removes all of the mappings from this cache.
     * <p>
     * The order that the individual entries are removed is undefined.
     * <p>
     * For every mapping that exists the following are called:
     * <ul>
     *   <li>any registered {@link CacheEntryRemovedListener}s</li>
     *   <li>if the cache is a write-through cache, the {@link CacheWriter}</li>
     * </ul>
     * If the cache is empty, the {@link CacheWriter} is not called.
     * <p>
     * This operation is not transactional. It calls broadcast closure that
     * deletes all primary keys from remote nodes.
     * <p>
     * This is potentially an expensive operation as listeners are invoked.
     * Use {@link #clear()} to avoid this.
     *
     * @throws IllegalStateException if the cache is {@link #isClosed()}
     * @throws CacheException        if there is a problem during the remove
     * @see #clear()
     * @see CacheWriter#deleteAll
     */
    @IgniteAsyncSupported
    @Override public void removeAll();

    /**
     * Asynchronously removes all of the mappings from this cache.
     * <p>
     * The order that the individual entries are removed is undefined.
     * <p>
     * For every mapping that exists the following are called:
     * <ul>
     *   <li>any registered {@link CacheEntryRemovedListener}s</li>
     *   <li>if the cache is a write-through cache, the {@link CacheWriter}</li>
     * </ul>
     * If the cache is empty, the {@link CacheWriter} is not called.
     * <p>
     * This is potentially an expensive operation as listeners are invoked.
     * Use {@link #clearAsync()} to avoid this.
     *
     * @return a Future representing pending completion of the operation.
     * @throws IllegalStateException if the cache is {@link #isClosed()}
     * @throws CacheException        if there is a problem during the remove
     * @see #clearAsync()
     * @see CacheWriter#deleteAll
     */
    public IgniteFuture<Void> removeAllAsync();

    /**
     * Clears the contents of the cache, without notifying listeners or {@link CacheWriter}s.
     * Entries are cleared only if they are not currently locked, and are not participating in a transaction.
     * This operation is not transactional. It calls broadcast closure that deletes all primary keys from remote nodes.
     *
     * @throws IllegalStateException if the cache is {@link #isClosed()}.
     * @throws CacheException        if there is a problem during the clear.
     */
    @IgniteAsyncSupported
    @Override public void clear();

    /**
     * Asynchronously clears the contents of the cache, without notifying listeners or
     * {@link CacheWriter}s.
     * This operation is not transactional. It calls broadcast closure that deletes all primary keys from remote nodes.
     *
     * @return a Future representing pending completion of the operation.
     */
    public IgniteFuture<Void> clearAsync();

    /**
     * Clears entry from the cache and swap storage, without notifying listeners or
     * {@link CacheWriter}s. Entry is cleared only if it is not currently locked,
     * and is not participating in a transaction.
     * This operation is not transactional. It calls broadcast closure that deletes all primary keys from remote nodes.
     *
     * @param key Key to clear.
     * @throws IllegalStateException if the cache is {@link #isClosed()}
     * @throws CacheException        if there is a problem during the clear
     */
    @IgniteAsyncSupported
    public void clear(K key);

    /**
     * Asynchronously clears entry from the cache and swap storage, without notifying listeners or
     * {@link CacheWriter}s. Entry is cleared only if it is not currently locked,
     * and is not participating in a transaction.
     * This operation is not transactional. It calls broadcast closure that deletes all primary keys from remote nodes.
     *
     * @param key Key to clear.
     * @return a Future representing pending completion of the operation.
     * @throws IllegalStateException if the cache is {@link #isClosed()}
     * @throws CacheException        if there is a problem during the clear
     */
    public IgniteFuture<Void> clearAsync(K key);

    /**
     * Clears entries from the cache and swap storage, without notifying listeners or
     * {@link CacheWriter}s. Entry is cleared only if it is not currently locked,
     * and is not participating in a transaction.
     * This operation is not transactional. It calls broadcast closure that deletes all primary keys from remote nodes.
     *
     * @param keys Keys to clear.
     * @throws IllegalStateException if the cache is {@link #isClosed()}
     * @throws CacheException        if there is a problem during the clear
     */
    @IgniteAsyncSupported
    public void clearAll(Set<? extends K> keys);

    /**
     * Asynchronously clears entries from the cache and swap storage, without notifying listeners or
     * {@link CacheWriter}s. Entry is cleared only if it is not currently locked,
     * and is not participating in a transaction.
     * This operation is not transactional. It calls broadcast closure that deletes all primary keys from remote nodes.
     *
     * @param keys Keys to clear.
     * @return a Future representing pending completion of the operation.
     * @throws IllegalStateException if the cache is {@link #isClosed()}
     * @throws CacheException        if there is a problem during the clear
     */
    public IgniteFuture<Void> clearAllAsync(Set<? extends K> keys);

    /**
     * Clears entry from the cache and swap storage, without notifying listeners or
     * {@link CacheWriter}s. Entry is cleared only if it is not currently locked,
     * and is not participating in a transaction.
     * This operation is not transactional. It calls broadcast closure that deletes all primary keys from remote nodes.
     * <p/>
     * Note that this operation is local as it merely clears
     * an entry from local cache, it does not remove entries from
     * remote caches.
     *
     * @param key Key to clear.
     */
    public void localClear(K key);

    /**
     * Clears entries from the cache and swap storage, without notifying listeners or
     * {@link CacheWriter}s. Entry is cleared only if it is not currently locked,
     * and is not participating in a transaction.
     * This operation is not transactional. It calls broadcast closure that deletes all primary keys from remote nodes.
     * <p/>
     * Note that this operation is local as it merely clears
     * an entry from local cache, it does not remove entries from
     * remote caches.
     *
     * @param keys Keys to clear.
     */
    public void localClearAll(Set<? extends K> keys);

    /**
     * {@inheritDoc}
     * <p>
     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for information on
     * system behavior in crash scenarios for atomic caches.
     *
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public <T> T invoke(K key, EntryProcessor<K, V, T> entryProcessor, Object... arguments)
        throws TransactionException;

    /**
     * Asynchronously invokes an {@link EntryProcessor} against the {@link javax.cache.Cache.Entry} specified by
     * the provided key. If an {@link javax.cache.Cache.Entry} does not exist for the specified key,
     * an attempt is made to load it (if a loader is configured) or a surrogate
     * {@link javax.cache.Cache.Entry}, consisting of the key with a null value is used instead.
     * <p>
     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for information on
     * system behavior in crash scenarios for atomic caches.
     *
     * @param key The key to the entry.
     * @param entryProcessor The {@link EntryProcessor} to invoke.
     * @param arguments Additional arguments to pass to the {@link EntryProcessor}.
     * @param <T> Type of the cache entry processing result.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public <T> IgniteFuture<T> invokeAsync(K key, EntryProcessor<K, V, T> entryProcessor, Object... arguments)
        throws TransactionException;

    /**
     * Invokes an {@link CacheEntryProcessor} against the {@link javax.cache.Cache.Entry} specified by
     * the provided key. If an {@link javax.cache.Cache.Entry} does not exist for the specified key,
     * an attempt is made to load it (if a loader is configured) or a surrogate
     * {@link javax.cache.Cache.Entry}, consisting of the key with a null value is used instead.
     * <p>
     * An instance of entry processor must be stateless as it may be invoked multiple times on primary and
     * backup nodes in the cache. It is guaranteed that the value passed to the entry processor will be always
     * the same.
     * <p>
     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for information on
     * system behavior in crash scenarios for atomic caches.
     *
     * @param key The key to the entry.
     * @param entryProcessor The {@link CacheEntryProcessor} to invoke.
     * @param arguments Additional arguments to pass to the {@link CacheEntryProcessor}.
     * @param <T> Type of the cache entry processing result.
     * @return The result of the processing, if any, defined by the {@link CacheEntryProcessor} implementation.
     * @throws NullPointerException If key or {@link CacheEntryProcessor} is null
     * @throws IllegalStateException If the cache is {@link #isClosed()}
     * @throws ClassCastException If the implementation is configured to perform
     *                               runtime-type-checking, and the key or value
     *                               types are incompatible with those that have been
     *                               configured for the {@link Cache}.
     * @throws EntryProcessorException If an exception is thrown by the {@link
     *                                 CacheEntryProcessor}, a Caching Implementation
     *                                 must wrap any {@link Exception} thrown
     *                                 wrapped in an {@link EntryProcessorException}.
     * @throws TransactionException If operation within transaction is failed.
     * @see CacheEntryProcessor
     */
    @IgniteAsyncSupported
    public <T> T invoke(K key, CacheEntryProcessor<K, V, T> entryProcessor, Object... arguments)
        throws TransactionException;

    /**
     * Asynchronously invokes an {@link CacheEntryProcessor} against the {@link javax.cache.Cache.Entry} specified by
     * the provided key. If an {@link javax.cache.Cache.Entry} does not exist for the specified key,
     * an attempt is made to load it (if a loader is configured) or a surrogate
     * {@link javax.cache.Cache.Entry}, consisting of the key with a null value is used instead.
     * <p>
     * An instance of entry processor must be stateless as it may be invoked multiple times on primary and
     * backup nodes in the cache. It is guaranteed that the value passed to the entry processor will be always
     * the same.
     *
     * @param key The key to the entry.
     * @param entryProcessor The {@link CacheEntryProcessor} to invoke.
     * @param arguments Additional arguments to pass to the {@link CacheEntryProcessor}.
     * @param <T> Type of the cache entry processing result.
     * @return a Future representing pending completion of the operation.
     * @throws NullPointerException If key or {@link CacheEntryProcessor} is null
     * @throws IllegalStateException If the cache is {@link #isClosed()}
     * @throws ClassCastException If the implementation is configured to perform
     *                               runtime-type-checking, and the key or value
     *                               types are incompatible with those that have been
     *                               configured for the {@link Cache}.
     * @throws EntryProcessorException If an exception is thrown by the {@link
     *                                 CacheEntryProcessor}, a Caching Implementation
     *                                 must wrap any {@link Exception} thrown
     *                                 wrapped in an {@link EntryProcessorException}.
     * @throws TransactionException If operation within transaction is failed.
     * @see CacheEntryProcessor
     */
    public <T> IgniteFuture<T> invokeAsync(K key, CacheEntryProcessor<K, V, T> entryProcessor, Object... arguments)
        throws TransactionException;

    /**
     * {@inheritDoc}
     * <p>
     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for information on
     * system behavior in crash scenarios for atomic caches.
     * <p>
     * Keys are locked in the order in which they appear in key set. It is caller's responsibility to
     * make sure keys always follow same order, such as by using {@link java.util.TreeSet}. Using unordered map,
     * such as {@link java.util.HashSet}, while calling this method in parallel <b>will lead to deadlock</b>.
     *
     * @throws TransactionException If operation within transaction is failed.
     */
    @IgniteAsyncSupported
    @Override public <T> Map<K, EntryProcessorResult<T>> invokeAll(Set<? extends K> keys,
        EntryProcessor<K, V, T> entryProcessor, Object... args) throws TransactionException;

    /**
     * Asynchronously invokes an {@link EntryProcessor} against the set of {@link javax.cache.Cache.Entry}s
     * specified by the set of keys.
     * <p>
     * If an {@link javax.cache.Cache.Entry} does not exist for the specified key, an attempt is made
     * to load it (if a loader is configured) or a surrogate {@link javax.cache.Cache.Entry},
     * consisting of the key and a value of null is provided.
     * <p>
     * The order that the entries for the keys are processed is undefined.
     * Implementations may choose to process the entries in any order, including
     * concurrently.  Furthermore there is no guarantee implementations will
     * use the same {@link EntryProcessor} instance to process each entry, as
     * the case may be in a non-local cache topology.
     * <p>
     * The result of executing the {@link EntryProcessor} is returned in the future as a
     * {@link Map} of {@link EntryProcessorResult}s, one result per key.  Should the
     * {@link EntryProcessor} or Caching implementation throw an exception, the
     * exception is wrapped and re-thrown when a call to
     * {@link javax.cache.processor.EntryProcessorResult#get()} is made.
     * <p>
     * Please refer to documentation for {@link CacheAtomicityMode#ATOMIC} for information on
     * system behavior in crash scenarios for atomic caches.
     * <p>
     * Keys are locked in the order in which they appear in key set. It is caller's responsibility to
     * make sure keys always follow same order, such as by using {@link java.util.TreeSet}. Using unordered map,
     * such as {@link java.util.HashSet}, while calling this method in parallel <b>will lead to deadlock</b>.
     *
     * @param keys The set of keys.
     * @param entryProcessor The {@link EntryProcessor} to invoke.
     * @param args Additional arguments to pass to the {@link EntryProcessor}.
     * @param <T> Type of the cache entry processing result.
     * @return a Future representing pending completion of the operation.
     * @throws TransactionException If operation within transaction is failed.
     */
    public <T> IgniteFuture<Map<K, EntryProcessorResult<T>>> invokeAllAsync(Set<? extends K> keys,
        EntryProcessor<K, V, T> entryProcessor, Object... args) throws TransactionException;

    /**
     * Invokes an {@link CacheEntryProcessor} against the set of {@link javax.cache.Cache.Entry}s
     * specified by the set of keys.
     * <p>
     * If an {@link javax.cache.Cache.Entry} does not exist for the specified key, an attempt is made
     * to load it (if a loader is configured) or a surrogate {@link javax.cache.Cache.Entry},
     * consisting of the key and a value of null is provided.
     * <p>
     * The order that the entries for the keys are processed is undefined.
     * Implementations may choose to process the entries in any order, including
     * concurrently.  Furthermore there is no guarantee implementations will
     * use the same {@link CacheEntryProcessor} instance to process each entry, as
     * the case may be in a non-local cache topology.
     * <p>
     * The result of executing the {@link CacheEntryProcessor} is returned as a
     * {@link Map} of {@link EntryProcessorResult}s, one result per key.  Should the
     * {@link CacheEntryProcessor} or Caching implementation throw an exception, the
     * exception is wrapped and re-thrown when a call to
     * {@link javax.cache.processor.EntryProcessorResult#get()} is made.
     * <p>
     * An instance of entry processor must be stateless as it may be invoked multiple times on primary and
     * backup nodes in the cache. It is guaranteed that the value passed to the entry processor will be always
     * the same.
     * <p>
     * Keys are locked in the order in which they appear in key set. It is caller's responsibility to
     * make sure keys always follow same order, such as by using {@link java.util.TreeSet}. Using unordered map,
     * such as {@link java.util.HashSet}, while calling this method in parallel <b>will lead to deadlock</b>.
     *
     * @param keys The set of keys for entries to process.
     * @param entryProcessor The {@link CacheEntryProcessor} to invoke.
     * @param args Additional arguments to pass to the {@link CacheEntryProcessor}.
     * @param <T> Type of the cache entry processing result.
     * @return The map of {@link EntryProcessorResult}s of the processing per key,
     * if any, defined by the {@link CacheEntryProcessor} implementation.  No mappings
     * will be returned for {@link CacheEntryProcessor}s that return a
     * <code>null</code> value for a key.
     * @throws NullPointerException If keys or {@link CacheEntryProcessor} are {#code null}.
     * @throws IllegalStateException If the cache is {@link #isClosed()}.
     * @throws ClassCastException If the implementation is configured to perform
     *                               runtime-type-checking, and the key or value
     *                               types are incompatible with those that have been
     *                               configured for the {@link Cache}.
     * @throws TransactionException If operation within transaction is failed.
     * @see CacheEntryProcessor
     */
    @IgniteAsyncSupported
    public <T> Map<K, EntryProcessorResult<T>> invokeAll(Set<? extends K> keys,
        CacheEntryProcessor<K, V, T> entryProcessor, Object... args) throws TransactionException;

    /**
     * Asynchronously invokes an {@link CacheEntryProcessor} against the set of {@link javax.cache.Cache.Entry}s
     * specified by the set of keys.
     * <p>
     * If an {@link javax.cache.Cache.Entry} does not exist for the specified key, an attempt is made
     * to load it (if a loader is configured) or a surrogate {@link javax.cache.Cache.Entry},
     * consisting of the key and a value of null is provided.
     * <p>
     * The order that the entries for the keys are processed is undefined.
     * Implementations may choose to process the entries in any order, including
     * concurrently.  Furthermore there is no guarantee implementations will
     * use the same {@link CacheEntryProcessor} instance to process each entry, as
     * the case may be in a non-local cache topology.
     * <p>
     * The result of executing the {@link CacheEntryProcessor} is returned in the future as a
     * {@link Map} of {@link EntryProcessorResult}s, one result per key.  Should the
     * {@link CacheEntryProcessor} or Caching implementation throw an exception, the
     * exception is wrapped and re-thrown when a call to
     * {@link javax.cache.processor.EntryProcessorResult#get()} is made.
     * <p>
     * An instance of entry processor must be stateless as it may be invoked multiple times on primary and
     * backup nodes in the cache. It is guaranteed that the value passed to the entry processor will be always
     * the same.
     * <p>
     * Keys are locked in the order in which they appear in key set. It is caller's responsibility to
     * make sure keys always follow same order, such as by using {@link java.util.TreeSet}. Using unordered map,
     * such as {@link java.util.HashSet}, while calling this method in parallel <b>will lead to deadlock</b>.
     *
     * @param keys The set of keys for entries to process.
     * @param entryProcessor The {@link CacheEntryProcessor} to invoke.
     * @param args Additional arguments to pass to the {@link CacheEntryProcessor}.
     * @param <T> Type of the cache entry processing result.
     * @return a Future representing pending completion of the operation.
     * @throws NullPointerException If keys or {@link CacheEntryProcessor} are {#code null}.
     * @throws IllegalStateException If the cache is {@link #isClosed()}.
     * @throws ClassCastException If the implementation is configured to perform
     *                               runtime-type-checking, and the key or value
     *                               types are incompatible with those that have been
     *                               configured for the {@link Cache}.
     * @throws TransactionException If operation within transaction is failed.
     * @see CacheEntryProcessor
     */
    public <T> IgniteFuture<Map<K, EntryProcessorResult<T>>> invokeAllAsync(Set<? extends K> keys,
        CacheEntryProcessor<K, V, T> entryProcessor, Object... args) throws TransactionException;

    /**
     * Closes this cache instance.
     * <p>
     * For local cache equivalent to {@link #destroy()}.
     * For distributed caches, if called on clients, stops client cache, if called on a server node,
     * just closes this cache instance and does not destroy cache data.
     * <p>
     * After cache instance is closed another {@code IgniteCache} instance for the same
     * cache can be created using {@link Ignite#cache(String)} method.
     */
    @Override public void close();

    /**
     * Completely deletes the cache with all its data from the system on all cluster nodes.
     */
    public void destroy();

    /**
     * This cache node to re-balance its partitions. This method is usually used when
     * {@link CacheConfiguration#getRebalanceDelay()} configuration parameter has non-zero value.
     * When many nodes are started or stopped almost concurrently, it is more efficient to delay
     * rebalancing until the node topology is stable to make sure that no redundant re-partitioning
     * happens.
     * <p>
     * In case of{@link CacheMode#PARTITIONED} caches, for better efficiency user should
     * usually make sure that new nodes get placed on the same place of consistent hash ring as
     * the left nodes, and that nodes are restarted before
     * {@link CacheConfiguration#getRebalanceDelay() rebalanceDelay} expires. To place nodes
     * on the same place in consistent hash ring, use
     * {@link IgniteConfiguration#setConsistentId(Serializable)} to make sure that
     * a node maps to the same hash ID if re-started.
     * <p>
     * See {@link CacheConfiguration#getRebalanceDelay()} for more information on how to configure
     * rebalance re-partition delay.
     * <p>
     * @return Future that will be completed when rebalancing is finished. Future.get() returns {@code true}
     *      when rebalance was successfully finished.
     * @deprecated Use baseline topology feature instead. Please, be aware this API will be removed in the next releases.
     */
    @Deprecated
    public IgniteFuture<Boolean> rebalance();

    /**
     * Returns future that will be completed when all indexes for this cache are ready to use.
     *
     * @return Future.
     */
    public IgniteFuture<?> indexReadyFuture();

    /**
     * Gets whole cluster snapshot metrics (statistics) for this cache.
     *
     * @return Cache metrics.
     */
    public CacheMetrics metrics();

    /**
     * Gets cluster group snapshot metrics for caches in cluster group.
     *
     * @param grp Cluster group.
     * @return Cache metrics.
     */
    public CacheMetrics metrics(ClusterGroup grp);

    /**
     * Gets local snapshot metrics (statistics) for this cache.
     *
     * @return Cache metrics.
     */
    public CacheMetrics localMetrics();

    /**
     * Gets a collection of lost partition IDs.
     *
     * This method provides a facility for fine-tuned handling of lost partitions.
     * Once all lost partitions are considered recovered (for example, after the previously failed
     * primary and backup nodes, that stored partition data in Ignite persistence, are booted)
     * {@link Ignite#resetLostPartitions(Collection)} can used in order to clear {@code lost} flag
     * making all partitions fully operational.
     *
     * @return Lost partitions.
     * @see PartitionLossPolicy
     * @see EventType#EVT_CACHE_REBALANCE_PART_DATA_LOST
     * @see Ignite#resetLostPartitions(Collection)
     */
    public Collection<Integer> lostPartitions();

    /**
     * Sets statistics enabled flag cluster wide for this cache.
     *
     * @param enabled Statistics enabled flag.
     */
    public void enableStatistics(boolean enabled);

    /**
     * Clear cluster statistics for this cache.
     */
    public void clearStatistics();

    /**
     * Efficiently preloads cache primary partition into page memory.
     * <p>
     * This is useful for fast iteration over cache partition data if persistence is enabled and the data is "cold".
     * <p>
     * Preload will reduce available amount of page memory for subsequent operations and may lead to earlier page
     * replacement.
     * <p>
     * This method is irrelevant for in-memory caches. Calling this method on an in-memory cache will result in
     * exception.
     *
     * @param partition Partition.
     */
    public void preloadPartition(int partition);

    /**
     * Efficiently preloads cache partition into page memory.
     * <p>
     * This is useful for fast iteration over cache partition data if persistence is enabled and the data is "cold".
     * <p>
     * Preload will reduce available amount of page memory for subsequent operations and may lead to earlier page
     * replacement.
     * <p>
     * This method is irrelevant for in-memory caches. Calling this method on an in-memory cache will result in
     * exception.
     *
     * @param partition Partition.
     * @return A future representing pending completion of the partition preloading.
     */
    public IgniteFuture<Void> preloadPartitionAsync(int partition);

    /**
     * Efficiently preloads cache partition into page memory if it exists on the local node.
     * <p>
     * This is useful for fast iteration over cache partition data if persistence is enabled and the data is "cold".
     * <p>
     * Preload will reduce available amount of page memory for subsequent operations and may lead to earlier page
     * replacement.
     * <p>
     * This method is irrelevant for in-memory caches. Calling this method on an in-memory cache will result in
     * exception.
     *
     * @param partition Partition.
     * @return {@code True} if partition was preloaded, {@code false} if it doesn't belong to local node.
     */
    public boolean localPreloadPartition(int partition);
}
