/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed 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.onosproject.store.service;

/**
 * Distributed version of com.google.common.util.concurrent.AtomicLongMap.
 */
public interface AtomicCounterMap<K> {

    /**
     * Increments by one the value currently associated with key, and returns the new value.
     *
     * @param key key with which the specified value is to be associated
     * @return incremented value
     */
    long incrementAndGet(K key);

    /**
     * Decrements by one the value currently associated with key, and returns the new value.
     *
     * @param key key with which the specified value is to be associated
     * @return updated value
     */
    long decrementAndGet(K key);

    /**
     * Increments by one the value currently associated with key, and returns the old value.
     *
     * @param key key with which the specified value is to be associated
     * @return previous value
     */
    long getAndIncrement(K key);

    /**
     * Decrements by one the value currently associated with key, and returns the old value.
     *
     * @param key key with which the specified value is to be associated
     * @return previous value
     */
    long getAndDecrement(K key);

    /**
     * Adds delta to the value currently associated with key, and returns the new value.
     *
     * @param key key with which the specified value is to be associated
     * @param delta the value to add
     * @return updated value
     */
    long addAndGet(K key, long delta);

    /**
     * Adds delta to the value currently associated with key, and returns the old value.
     *
     * @param key key with which the specified value is to be associated
     * @param delta the value to add
     * @return previous value
     */
    long getAndAdd(K key, long delta);

    /**
     * Returns the value associated with key, or zero if there is no value associated with key.
     *
     * @param key key with which the specified value is to be associated
     * @return current value
     */
    long get(K key);

    /**
     * Associates ewValue with key in this map, and returns the value previously
     * associated with key, or zero if there was no such value.
     *
     * @param key key with which the specified value is to be associated
     * @param newValue the value to put
     * @return previous value or zero
     */
    long put(K key, long newValue);


    /**
     * If key is not already associated with a value or if key is associated with
     * zero, associate it with newValue. Returns the previous value associated with
     * key, or zero if there was no mapping for key.
     *
     * @param key key with which the specified value is to be associated
     * @param newValue the value to put
     * @return previous value or zero
     */
    long putIfAbsent(K key, long newValue);

    /**
     * If (key, expectedOldValue) is currently in the map, this method replaces
     * expectedOldValue with newValue and returns true; otherwise, this method return false.
     *
     * If expectedOldValue is zero, this method will succeed if (key, zero)
     * is currently in the map, or if key is not in the map at all.
     *
     * @param key key with which the specified value is to be associated
     * @param expectedOldValue the expected value
     * @param newValue the value to replace
     * @return true if the value was replaced, false otherwise
     */
    boolean replace(K key, long expectedOldValue, long newValue);

    /**
     * Removes and returns the value associated with key. If key is not
     * in the map, this method has no effect and returns zero.
     *
     * @param key key with which the specified value is to be associated
     * @return the previous value associated with the specified key or null
     */
    long remove(K key);

    /**
     * If (key, value) is currently in the map, this method removes it and returns
     * true; otherwise, this method returns false.
     *
     * @param key key with which the specified value is to be associated
     * @param value the value to remove
     * @return true if the value was removed, false otherwise
     */
    boolean remove(K key, long value);
}
