com.liferay.portal.kernel.util.WeakValueConcurrentHashMap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of portal-service Show documentation
Show all versions of portal-service Show documentation
Contains interfaces for the portal services. Interfaces are only loaded by the global class loader and are shared by all plugins.
/**
* Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.kernel.util;
import com.liferay.portal.kernel.memory.EqualityWeakReference;
import com.liferay.portal.kernel.memory.FinalizeAction;
import com.liferay.portal.kernel.memory.FinalizeManager;
import java.io.Serializable;
import java.lang.ref.Reference;
import java.util.AbstractCollection;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* @author Shuyang Zhou
*/
public class WeakValueConcurrentHashMap
implements ConcurrentMap, Serializable {
public WeakValueConcurrentHashMap() {
_map = new ConcurrentHashMap>();
}
public WeakValueConcurrentHashMap(int initialCapacity) {
_map = new ConcurrentHashMap>(initialCapacity);
}
public WeakValueConcurrentHashMap(
int initialCapacity, float loadFactor, int concurrencyLevel) {
_map = new ConcurrentHashMap>(
initialCapacity, loadFactor, concurrencyLevel);
}
public WeakValueConcurrentHashMap(Map extends K, ? extends V> map) {
_map = new ConcurrentHashMap>();
putAll(map);
}
@Override
public void clear() {
_map.clear();
}
@Override
public boolean containsKey(Object key) {
return _map.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
return _map.containsValue(new EqualityWeakReference((V)value));
}
@Override
public Set> entrySet() {
if (_entrySet == null) {
_entrySet = new UnwrapEntrySet();
}
return _entrySet;
}
@Override
public V get(Object key) {
Reference valueReference = _map.get(key);
if (valueReference != null) {
return valueReference.get();
}
return null;
}
@Override
public boolean isEmpty() {
return _map.isEmpty();
}
@Override
public Set keySet() {
return _map.keySet();
}
@Override
public V put(K key, V value) {
Reference valueReference = wrapValue(key, value);
valueReference = _map.putIfAbsent(key, valueReference);
if (valueReference != null) {
return valueReference.get();
}
return null;
}
@Override
public final void putAll(Map extends K, ? extends V> map) {
for (Map.Entry extends K, ? extends V> entry : map.entrySet()) {
K key = entry.getKey();
V value = entry.getValue();
Reference valueReference = wrapValue(key, value);
_map.put(key, valueReference);
}
}
@Override
public V putIfAbsent(K key, V value) {
Reference valueReference = wrapValue(key, value);
valueReference = _map.putIfAbsent(key, valueReference);
if (valueReference != null) {
return valueReference.get();
}
return null;
}
@Override
public V remove(Object key) {
Reference valueReference = _map.remove(key);
if (valueReference != null) {
return valueReference.get();
}
return null;
}
@Override
public boolean remove(Object key, Object value) {
Reference valueReference = wrapValue(key, value);
return _map.remove(key, valueReference);
}
@Override
public V replace(K key, V value) {
Reference valueReference = wrapValue(key, value);
valueReference = _map.replace(key, valueReference);
if (valueReference != null) {
return valueReference.get();
}
return null;
}
@Override
public boolean replace(K key, V oldValue, V newValue) {
Reference oldValueReference = wrapValue(key, oldValue);
Reference newValueReference = wrapValue(key, newValue);
return _map.replace(key, oldValueReference, newValueReference);
}
@Override
public int size() {
return _map.size();
}
@Override
public Collection values() {
if (_values == null) {
_values = new UnwrapValues();
}
return _values;
}
protected Reference wrapValue(Object key, Object value) {
return FinalizeManager.register(
(V)value, new RemoveEntryFinalizeAction((K)key));
}
private transient Set> _entrySet;
private final ConcurrentMap> _map;
private transient Collection _values;
private class RemoveEntryFinalizeAction implements FinalizeAction {
public RemoveEntryFinalizeAction(K key) {
_key = key;
}
@Override
public void doFinalize() {
remove(_key);
}
private final K _key;
}
private class UnwrapEntry implements Map.Entry {
public UnwrapEntry(Entry> entry) {
_entry = entry;
}
@Override
public K getKey() {
return _entry.getKey();
}
@Override
public V getValue() {
Reference valueReference = _entry.getValue();
if (valueReference != null) {
return valueReference.get();
}
return null;
}
@Override
public V setValue(V value) {
return WeakValueConcurrentHashMap.this.put(_entry.getKey(), value);
}
private Map.Entry> _entry;
}
private class UnwrapEntryIterator implements Iterator> {
public UnwrapEntryIterator() {
_iterator = _map.entrySet().iterator();
}
@Override
public boolean hasNext() {
return _iterator.hasNext();
}
@Override
public Entry next() {
return new UnwrapEntry(_iterator.next());
}
@Override
public void remove() {
_iterator.remove();
}
private Iterator>> _iterator;
}
private class UnwrapEntrySet extends AbstractSet> {
@Override
public void clear() {
WeakValueConcurrentHashMap.this.clear();
}
@Override
public boolean contains(Object obj) {
if (!(obj instanceof Map.Entry, ?>)) {
return false;
}
Map.Entry entry = (Map.Entry)obj;
V value = WeakValueConcurrentHashMap.this.get(entry.getKey());
if ((value != null) && value.equals(entry.getValue())) {
return true;
}
else {
return false;
}
}
@Override
public Iterator> iterator() {
return new UnwrapEntryIterator();
}
@Override
public boolean remove(Object obj) {
if (!(obj instanceof Map.Entry, ?>)) {
return false;
}
Map.Entry entry = (Map.Entry)obj;
return WeakValueConcurrentHashMap.this.remove(
entry.getKey(), entry.getValue());
}
@Override
public int size() {
return WeakValueConcurrentHashMap.this.size();
}
@Override
public Object[] toArray() {
List> list = new ArrayList>(size());
Iterator> iterator = iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list.toArray();
}
@Override
public T[] toArray(T[] array) {
List> list = new ArrayList>(size());
Iterator> iterator = iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list.toArray(array);
}
}
private class UnwrapValueIterator implements Iterator {
public UnwrapValueIterator() {
_iterator = _map.values().iterator();
}
@Override
public boolean hasNext() {
return _iterator.hasNext();
}
@Override
public V next() {
Reference valueReference = _iterator.next();
if (valueReference != null) {
return valueReference.get();
}
return null;
}
@Override
public void remove() {
_iterator.remove();
}
private Iterator> _iterator;
}
private class UnwrapValues extends AbstractCollection {
@Override
public void clear() {
WeakValueConcurrentHashMap.this.clear();
}
@Override
public boolean contains(Object obj) {
return WeakValueConcurrentHashMap.this.containsValue(obj);
}
@Override
public Iterator iterator() {
return new UnwrapValueIterator();
}
@Override
public int size() {
return WeakValueConcurrentHashMap.this.size();
}
@Override
public Object[] toArray() {
List list = new ArrayList();
Iterator iterator = iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list.toArray();
}
@Override
public T[] toArray(T[] a) {
List list = new ArrayList();
Iterator iterator = iterator();
while (iterator.hasNext()) {
list.add(iterator.next());
}
return list.toArray(a);
}
}
}