/*
 * 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.Closeable;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import org.apache.ignite.lang.IgniteCallable;
import org.apache.ignite.lang.IgniteRunnable;

/**
 * Set implementation based on on In-Memory Data Grid.
 * <h1 class="header">Overview</h1>
 * Cache set implements {@link Set} interface and provides all methods from collections.
 * Note that all {@link Collection} methods in the set may throw {@link IgniteException} in case of failure
 * or if set was removed.
 * <h1 class="header">Collocated vs Non-collocated</h1>
 * Set items can be placed on one node or distributed throughout grid nodes
 * (governed by {@code collocated} parameter). {@code Non-collocated} mode is provided only
 * for partitioned caches. If {@code collocated} parameter is {@code true}, then all set items
 * will be collocated on one node, otherwise items will be distributed through all grid nodes.
 * @see Ignite#set(String, org.apache.ignite.configuration.CollectionConfiguration)
 */
public interface IgniteSet<T> extends Set<T>, Closeable {
    /** {@inheritDoc} */
    @Override boolean add(T t) throws IgniteException;

    /** {@inheritDoc} */
    @Override boolean addAll(Collection<? extends T> c) throws IgniteException;

    /** {@inheritDoc} */
    @Override void clear() throws IgniteException;

    /** {@inheritDoc} */
    @Override boolean contains(Object o) throws IgniteException;

    /** {@inheritDoc} */
    @Override boolean containsAll(Collection<?> c) throws IgniteException;

    /** {@inheritDoc} */
    @Override boolean isEmpty() throws IgniteException;

    /** {@inheritDoc} */
    @Override Iterator<T> iterator() throws IgniteException;

    /** {@inheritDoc} */
    @Override boolean remove(Object o) throws IgniteException;

    /** {@inheritDoc} */
    @Override boolean removeAll(Collection<?> c) throws IgniteException;

    /** {@inheritDoc} */
    @Override boolean retainAll(Collection<?> c) throws IgniteException;

    /** {@inheritDoc} */
    @Override int size() throws IgniteException;

    /** {@inheritDoc} */
    @Override Object[] toArray() throws IgniteException;

    /** {@inheritDoc} */
    @Override <T1> T1[] toArray(T1[] a) throws IgniteException;

    /**
     * Removes this set.
     * In order to check the state it is possible to use {@link #removed()}.
     *
     * @throws IgniteException If operation failed.
     */
    @Override public void close() throws IgniteException;

    /**
     * Gets set name.
     *
     * @return Set name.
     */
    public String name();

    /**
     * Returns {@code true} if this set can be kept on the one node only.
     * Returns {@code false} if this set can be kept on the many nodes.
     *
     * @return {@code True} if this set is in {@code collocated} mode {@code false} otherwise.
     */
    public boolean collocated();

    /**
     * Gets status of set. In order to change the status it is possible to use {@link #close()} method.
     *
     * @return {@code True} if set was removed from cache {@code false} otherwise.
     */
    public boolean removed();

    /**
     * Executes given job on collocated set on the node where the set is located
     * (a.k.a. affinity co-location).
     * <p>
     * This is not supported for non-collocated sets.
     *
     * @param job Job which will be co-located with the set.
     * @throws IgniteException If job failed.
     */
    public void affinityRun(IgniteRunnable job) throws IgniteException;

    /**
     * Executes given job on collocated set on the node where the set is located
     * (a.k.a. affinity co-location).
     * <p>
     * This is not supported for non-collocated sets.
     *
     * @param job Job which will be co-located with the set.
     * @throws IgniteException If job failed.
     */
    public <R> R affinityCall(IgniteCallable<R> job) throws IgniteException;
}
