001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal;
011:
012: import java.util.ArrayList;
013: import java.util.HashMap;
014: import java.util.Iterator;
015: import java.util.List;
016: import java.util.Map;
017: import java.util.Set;
018:
019: /**
020: * A ReferenceCounter is used to reference counting objects.
021: * Each object is identified by a unique ID. Together they form
022: * an ID - value pair. An object is added to the counter by calling
023: * #put(id, object). From this point on additional refs can be made
024: * by calling #addRef(id) or #removeRef(id).
025: */
026: public class ReferenceCounter {
027: private Map mapIdToRec = new HashMap(11);
028:
029: /**
030: * Capture the information about an object.
031: */
032: public class RefRec {
033: public RefRec(Object id, Object value) {
034: this .id = id;
035: this .value = value;
036: addRef();
037: }
038:
039: public Object getId() {
040: return id;
041: }
042:
043: public Object getValue() {
044: return value;
045: }
046:
047: public int addRef() {
048: ++refCount;
049: return refCount;
050: }
051:
052: public int removeRef() {
053: --refCount;
054: return refCount;
055: }
056:
057: public int getRef() {
058: return refCount;
059: }
060:
061: public boolean isNotReferenced() {
062: return (refCount <= 0);
063: }
064:
065: public Object id;
066:
067: public Object value;
068:
069: private int refCount;
070: }
071:
072: /**
073: * Creates a new counter.
074: */
075: public ReferenceCounter() {
076: super ();
077: }
078:
079: /**
080: * Adds one reference to an object in the counter.
081: *
082: * @param id is a unique ID for the object.
083: * @return the new ref count
084: */
085: public int addRef(Object id) {
086: RefRec rec = (RefRec) mapIdToRec.get(id);
087: if (rec == null) {
088: return 0;
089: }
090: return rec.addRef();
091: }
092:
093: /**
094: * Returns the object defined by an ID. If the ID is not
095: * found <code>null</code> is returned.
096: *
097: * @return the object or <code>null</code>
098: */
099: public Object get(Object id) {
100: RefRec rec = (RefRec) mapIdToRec.get(id);
101: if (rec == null) {
102: return null;
103: }
104: return rec.getValue();
105: }
106:
107: /**
108: * Returns a complete list of the keys in the counter.
109: *
110: * @return a Set containing the ID for each.
111: */
112: public Set keySet() {
113: return mapIdToRec.keySet();
114: }
115:
116: /**
117: * Adds an object to the counter for counting and gives
118: * it an initial ref count of 1.
119: *
120: * @param id is a unique ID for the object.
121: * @param value is the object itself.
122: */
123: public void put(Object id, Object value) {
124: RefRec rec = new RefRec(id, value);
125: mapIdToRec.put(id, rec);
126: }
127:
128: /**
129: * @param id is a unique ID for the object.
130: * @return the current ref count
131: */
132: public int getRef(Object id) {
133: RefRec rec = (RefRec) mapIdToRec.get(id);
134: if (rec == null) {
135: return 0;
136: }
137: return rec.refCount;
138: }
139:
140: /**
141: * Removes one reference from an object in the counter.
142: * If the ref count drops to 0 the object is removed from
143: * the counter completely.
144: *
145: * @param id is a unique ID for the object.
146: * @return the new ref count
147: */
148: public int removeRef(Object id) {
149: RefRec rec = (RefRec) mapIdToRec.get(id);
150: if (rec == null) {
151: return 0;
152: }
153: int newCount = rec.removeRef();
154: if (newCount <= 0) {
155: mapIdToRec.remove(id);
156: }
157: return newCount;
158: }
159:
160: /**
161: * Returns a complete list of the values in the counter.
162: *
163: * @return a Collection containing the values.
164: */
165: public List values() {
166: int size = mapIdToRec.size();
167: ArrayList list = new ArrayList(size);
168: Iterator iter = mapIdToRec.values().iterator();
169: while (iter.hasNext()) {
170: RefRec rec = (RefRec) iter.next();
171: list.add(rec.getValue());
172: }
173: return list;
174: }
175: }
|