/******************************************************************************* * Copyright © 2011, 2013 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.edt.compiler.internal.core.utils; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import org.eclipse.edt.compiler.binding.IPartBinding; import org.eclipse.edt.mof.utils.NameUtile; public class PartBindingCache { private static final boolean DEBUG = false; private static class SoftReferenceWithKey extends SoftReference { Object key; SoftReferenceWithKey(Object key, Object referent, ReferenceQueue q) { super(referent, q); } } private static class PartKey { String packageName; String partName; PartKey(String packageName, String partName) { this.packageName = packageName; this.partName = partName; } public int hashCode() { return partName.hashCode(); } public boolean equals(Object obj) { PartKey anotherPartKey = (PartKey) obj; return (NameUtile.equals(anotherPartKey.packageName, this.packageName)) && (NameUtile.equals(anotherPartKey.partName, this.partName)); } } private Map softReferences; private ReferenceQueue referenceQueue; public PartBindingCache() { this.softReferences = new LinkedHashMap(16, 0.75f, true); this.referenceQueue = new ReferenceQueue(); } public PartBindingCache(final int maxSize) { this.softReferences = new LinkedHashMap((int)(maxSize * 0.75f), 0.75f, true) { private static final long serialVersionUID = 343884753499895404L; protected boolean removeEldestEntry(Entry eldest) { return size() > maxSize; } }; this.referenceQueue = new ReferenceQueue(); } /** * @param packageName * @param partName */ public void put(String packageName, String partName, IPartBinding partBinding) { if(DEBUG) System.out.println("Put: " + partName); //$NON-NLS-1$ removeClearedReferences(); PartKey partKey = new PartKey(packageName, partName); softReferences.put(partKey, new SoftReferenceWithKey(partKey, partBinding, referenceQueue)); } /** * @param packageName * @param partName */ public IPartBinding get(String packageName, String partName) { removeClearedReferences(); SoftReferenceWithKey ref = (SoftReferenceWithKey) softReferences.get(new PartKey(packageName, partName)); if(ref == null) { return null; } Object result = ref.get(); if(DEBUG && result == null) System.out.println("Key " + partName + " has been cleared"); //$NON-NLS-1$ //$NON-NLS-2$ return (IPartBinding) result; } /** * @param packageName * @param partName */ public void remove(String packageName, String partName) { softReferences.remove(new PartKey(packageName, partName)); } private void removeClearedReferences() { SoftReferenceWithKey ref; while((ref = (SoftReferenceWithKey) referenceQueue.poll()) != null) { if(DEBUG) System.out.println("Removing cleared soft reference"); //$NON-NLS-1$ softReferences.remove(ref.key); } } }