blob: b837cd493fc2b2387c823462a35465462d9221e3 [file] [log] [blame]
/*
* 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.
*/
#ifndef _DECAF_UTIL_CONCURRENT_CONCURRENTMAP_H_
#define _DECAF_UTIL_CONCURRENT_CONCURRENTMAP_H_
#include <decaf/util/Config.h>
#include <decaf/util/Map.h>
#include <decaf/lang/exceptions/UnsupportedOperationException.h>
#include <decaf/lang/exceptions/IllegalStateException.h>
#include <decaf/util/NoSuchElementException.h>
namespace decaf {
namespace util {
namespace concurrent {
/**
* Interface for a Map type that provides additional atomic putIfAbsent, remove,
* and replace methods alongside the already available Map interface.
*
* @since 1.0
*/
template<typename K, typename V>
class ConcurrentMap : public Map<K, V>{
public:
virtual ~ConcurrentMap() {}
/**
* If the specified key is not already associated with a value, associate it with
* the given value. This is equivalent to
* <pre>
* if( !map.containsKey( key ) ) {
* map.put( key, value );
* return true;
* } else {
* return false;
* }
* </pre>
* except that the action is performed atomically.
*
* @param key
* The key to map the value to.
* @param value
* The value to map to the given key.
*
* @return true if the put operation was performed otherwise return false
* which indicates there was a value previously mapped to the key.
* @throw UnsupportedOperationException
* if the put operation is not supported by this map
*/
virtual bool putIfAbsent( const K& key, const V& value ) = 0;
/**
* Remove entry for key only if currently mapped to given value.
* Acts as
* <pre>
* if( ( map.containsKey( key ) && ( map.get( key ) == value ) ) ) {
* map.remove( key );
* return true;
* } else {
* return false;
* }
* </pre>
* except that the action is performed atomically.
*
* @param key key with which the specified value is associated.
* @param value value associated with the specified key.
*
* @return true if the value was removed, false otherwise
*/
virtual bool remove( const K& key, const V& value ) = 0;
/**
* Replace entry for key only if currently mapped to given value.
* Acts as
* <pre>
* if( ( map.containsKey( key ) && ( map.get( key ) == oldValue ) ) {
* map.put( key, newValue );
* return true;
* } else {
* return false;
* }
* </pre>
* except that the action is performed atomically.
*
* @param key key with which the specified value is associated.
* @param oldValue value expected to be associated with the specified key.
* @param newValue value to be associated with the specified key.
*
* @return true if the value was replaced
*/
virtual bool replace( const K& key, const V& oldValue, const V& newValue ) = 0;
/**
* Replace entry for key only if currently mapped to some value.
* Acts as
* <pre>
* if( ( map.containsKey( key ) ) {
* return map.put( key, value );
* } else {
* throw NoSuchElementException(...);
* };
* </pre>
* except that the action is performed atomically.
*
* @param key key with which the specified value is associated.
* @param value value to be associated with the specified key.
*
* @return copy of the previous value associated with specified key, or
* throws an NoSuchElementException if there was no mapping for key.
*
* @throws NoSuchElementException if there was no previous mapping.
*/
virtual V replace( const K& key, const V& value ) = 0;
public:
using Map<K, V>::remove;
};
}}}
#endif /* _DECAF_UTIL_CONCURRENT_CONCURRENTMAP_H_ */