/******************************************************************************* * Copyright (c) 2011 Google, Inc 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: * Sergey Prigogin (Google) - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom; import java.util.HashMap; /** * Thread-safe reference counted set of objects. * * @param <T> Type of the objects contained in the set. */ public class AtomicMultiSet<T> { private final HashMap<T, Integer> map = new HashMap<T, Integer>(); /** * Adds object to the set if it was not present, or increments its reference count * otherwise. * @param object The object to add to the set. * @return Reference count of the object after the operation. */ public synchronized int add(T object) { Integer count = map.get(object); if (count == null) { count = Integer.valueOf(1); } else { count = Integer.valueOf(count.intValue() + 1); } map.put(object, count); return count.intValue(); } /** * Decrements reference count of the object in the set and removes the object if its * reference count reaches zero. * @param object The object to remove from the set. * @return Reference count of the object after the operation, or -1 if the object was not * present in the set. */ public synchronized int remove(T object) { Integer count = map.remove(object); if (count == null) { return -1; } int n = count.intValue() - 1; if (n <= 0) { return n; } map.put(object, Integer.valueOf(n)); return n; } public synchronized void clear() { map.clear(); } public synchronized boolean contains(T object) { return map.containsKey(object); } public synchronized int getCount(T object) { Integer count = map.get(object); return count != null ? count.intValue() : 0; } public synchronized boolean isEmpty() { return map.isEmpty(); } public synchronized int size() { return map.size(); } @Override public synchronized String toString() { return map.toString(); } }