blob: 28642234fa8f53edb3a93f68e2dbbbd5c519ef86 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A ReferenceCounter is used to reference counting objects.
* Each object is identified by a unique ID. Together they form
* an ID - value pair. An object is added to the counter by calling
* #put(id, object). From this point on additional refs can be made
* by calling #addRef(id) or #removeRef(id).
*/
public class ReferenceCounter {
private Map mapIdToRec = new HashMap(11);
/**
* Capture the information about an object.
*/
public class RefRec {
public RefRec(Object id, Object value) {
this.id = id;
this.value = value;
addRef();
}
public Object getId() {
return id;
}
public Object getValue() {
return value;
}
public int addRef() {
++refCount;
return refCount;
}
public int removeRef() {
--refCount;
return refCount;
}
public int getRef() {
return refCount;
}
public boolean isNotReferenced() {
return (refCount <= 0);
}
public Object id;
public Object value;
private int refCount;
}
/**
* Creates a new counter.
*/
public ReferenceCounter() {
super();
}
/**
* Adds one reference to an object in the counter.
*
* @param id is a unique ID for the object.
* @return the new ref count
*/
public int addRef(Object id) {
RefRec rec = (RefRec) mapIdToRec.get(id);
if (rec == null) {
return 0;
}
return rec.addRef();
}
/**
* Returns the object defined by an ID. If the ID is not
* found <code>null</code> is returned.
*
* @return the object or <code>null</code>
*/
public Object get(Object id) {
RefRec rec = (RefRec) mapIdToRec.get(id);
if (rec == null) {
return null;
}
return rec.getValue();
}
/**
* Returns a complete list of the keys in the counter.
*
* @return a Set containing the ID for each.
*/
public Set keySet() {
return mapIdToRec.keySet();
}
/**
* Adds an object to the counter for counting and gives
* it an initial ref count of 1.
*
* @param id is a unique ID for the object.
* @param value is the object itself.
*/
public void put(Object id, Object value) {
RefRec rec = new RefRec(id, value);
mapIdToRec.put(id, rec);
}
/**
* @param id is a unique ID for the object.
* @return the current ref count
*/
public int getRef(Object id) {
RefRec rec = (RefRec) mapIdToRec.get(id);
if (rec == null) {
return 0;
}
return rec.refCount;
}
/**
* Removes one reference from an object in the counter.
* If the ref count drops to 0 the object is removed from
* the counter completely.
*
* @param id is a unique ID for the object.
* @return the new ref count
*/
public int removeRef(Object id) {
RefRec rec = (RefRec) mapIdToRec.get(id);
if (rec == null) {
return 0;
}
int newCount = rec.removeRef();
if (newCount <= 0) {
mapIdToRec.remove(id);
}
return newCount;
}
/**
* Returns a complete list of the values in the counter.
*
* @return a Collection containing the values.
*/
public List values() {
int size = mapIdToRec.size();
ArrayList list = new ArrayList(size);
Iterator iter = mapIdToRec.values().iterator();
while (iter.hasNext()) {
RefRec rec = (RefRec) iter.next();
list.add(rec.getValue());
}
return list;
}
}