org.spf4j.ds.CopyOnWriteMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spf4j-core Show documentation
Show all versions of spf4j-core Show documentation
A continuously growing collection of utilities to measure performance, get better diagnostics,
improve performance, or do things more reliably, faster that other open source libraries...
package org.spf4j.ds;
/*
* 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.
*
*/
import com.google.common.collect.Maps;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* A thread-safe version of {@link Map} in which all operations that change the Map are implemented by making a new copy
* of the underlying Map.
*
* While the creation of a new Map can be expensive, this class is designed for cases in which the primary function is
* to read data from the Map, not to modify the Map. Therefore the operations that do not cause a change to this class
* happen quickly and concurrently.
*
* @author The Apache MINA Project ([email protected])
* @version $Rev$, $Date$
*/
@SuppressFBWarnings(value = {"NOS_NON_OWNED_SYNCHRONIZATION"},
justification = "Special case, not necessary on read path due to use of volatile")
public class CopyOnWriteMap implements Map, Cloneable {
private volatile Map internalMap;
/**
* Creates a new instance of CopyOnWriteMap.
*
*/
public CopyOnWriteMap() {
internalMap = new HashMap();
}
/**
* Creates a new instance of CopyOnWriteMap with the specified initial size
*
* @param initialCapacity The initial size of the Map.
*/
public CopyOnWriteMap(final int initialCapacity) {
internalMap = new HashMap(initialCapacity);
}
/**
* Creates a new instance of CopyOnWriteMap in which the initial data being held by this map is contained in the
* supplied map.
*
* @param data A Map containing the initial contents to be placed into this class.
*/
public CopyOnWriteMap(final Map data) {
internalMap = new HashMap(data);
}
/**
* @return a copy of this map, this is a fast operation.
*/
public final CopyOnWriteMap copy() {
return new CopyOnWriteMap<>(internalMap);
}
/**
* Adds the provided key and value to this map.
*
* @see java.util.Map#put(java.lang.Object, java.lang.Object)
*/
public V put(final K key, final V value) {
synchronized (this) {
Map newMap = Maps.newHashMapWithExpectedSize(internalMap.size() + 1);
newMap.putAll(internalMap);
V val = newMap.put(key, value);
internalMap = newMap;
return val;
}
}
/**
* Removed the value and key from this map based on the provided key.
*
* @see java.util.Map#remove(java.lang.Object)
*/
public V remove(final Object key) {
synchronized (this) {
Map newMap = new HashMap(internalMap);
V val = newMap.remove(key);
internalMap = newMap;
return val;
}
}
/**
* Inserts all the keys and values contained in the provided map to this map.
*
* @see java.util.Map#putAll(java.util.Map)
*/
public void putAll(final Map extends K, ? extends V> newData) {
synchronized (this) {
Map newMap = Maps.newHashMapWithExpectedSize(internalMap.size() + newData.size());
newMap.putAll(internalMap);
newMap.putAll(newData);
internalMap = newMap;
}
}
/**
* Removes all entries in this map.
*
* @see java.util.Map#clear()
*/
public void clear() {
synchronized (this) {
internalMap = new HashMap(0);
}
}
//
// Below are methods that do not modify
// the internal Maps
/**
* Returns the number of key/value pairs in this map.
*
* @see java.util.Map#size()
*/
public int size() {
return internalMap.size();
}
/**
* Returns true if this map is empty, otherwise false.
*
* @see java.util.Map#isEmpty()
*/
public boolean isEmpty() {
return internalMap.isEmpty();
}
/**
* Returns true if this map contains the provided key, otherwise this method return false.
*
* @see java.util.Map#containsKey(java.lang.Object)
*/
public boolean containsKey(final Object key) {
return internalMap.containsKey(key);
}
/**
* Returns true if this map contains the provided value, otherwise this method returns false.
*
* @see java.util.Map#containsValue(java.lang.Object)
*/
public boolean containsValue(final Object value) {
return internalMap.containsValue(value);
}
/**
* Returns the value associated with the provided key from this map.
*
* @see java.util.Map#get(java.lang.Object)
*/
public V get(final Object key) {
return internalMap.get(key);
}
/**
* This method will return a read-only {@link Set}.
*/
public Set keySet() {
return internalMap.keySet();
}
/**
* This method will return a read-only {@link Collection}.
*/
public Collection values() {
return internalMap.values();
}
/**
* This method will return a read-only {@link Set}.
*/
public Set> entrySet() {
return internalMap.entrySet();
}
/**
* @return a clone of this map. equivalent to copy()
*/
@Override
public CopyOnWriteMap clone() {
try {
return (CopyOnWriteMap) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
/**
* @return string representation of this map the includes the contents.
*/
@Override
public String toString() {
return "CopyOnWriteMap{internalMap=" + internalMap + '}';
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy