/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.sail.memory.model;
import java.lang.ref.WeakReference;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;
/**
* An object registry that uses weak references to keep track of the stored
* objects. The registry can be used to retrieve stored objects using another,
* equivalent object. As such, it can be used to prevent the use of duplicates
* in another data structure, reducing memory usage. The objects that are being
* stored should properly implement the {@link Object#equals} and
* {@link Object#hashCode} methods.
*/
public class WeakObjectRegistry<E> extends AbstractSet<E> {
/*-----------*
* Variables *
*-----------*/
/**
* The hash map that is used to store the objects.
*/
private final Map<E, WeakReference<E>> objectMap = new WeakHashMap<E, WeakReference<E>>();
/*--------------*
* Constructors *
*--------------*/
/**
* Constructs a new, empty object registry.
*/
public WeakObjectRegistry() {
super();
}
/**
* Constructs a new WeakObjectRegistry containing the elements in the
* specified collection.
*
* @param c
* The collection whose elements are to be placed into this object
* registry.
* @throws NullPointerException
* If the specified collection is null.
*/
public WeakObjectRegistry(Collection<? extends E> c) {
this();
addAll(c);
}
/*---------*
* Methods *
*---------*/
/**
* Retrieves the stored object that is equal to the supplied <tt>key</tt>
* object.
*
* @param key
* The object that should be used as the search key for the operation.
* @return A stored object that is equal to the supplied key, or
* <tt>null</tt> if no such object was found.
*/
public E get(Object key) {
WeakReference<E> weakRef = objectMap.get(key);
if (weakRef != null) {
return weakRef.get();
}
return null;
}
@Override
public Iterator<E> iterator()
{
return objectMap.keySet().iterator();
}
@Override
public int size()
{
return objectMap.size();
}
@Override
public boolean contains(Object o)
{
return get(o) != null;
}
@Override
public boolean add(E object)
{
WeakReference<E> ref = new WeakReference<E>(object);
ref = objectMap.put(object, ref);
if (ref != null && ref.get() != null) {
// A duplicate was added which replaced the existing object. Undo this
// operation.
objectMap.put(ref.get(), ref);
return false;
}
return true;
}
@Override
public boolean remove(Object o)
{
WeakReference<E> ref = objectMap.remove(o);
return ref != null && ref.get() != null;
}
@Override
public void clear()
{
objectMap.clear();
}
}