/******************************************************************************* * Copyright (c) 2000, 2007 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 * *******************************************************************************/ package org.eclipse.dltk.internal.core; import java.text.NumberFormat; import java.util.HashMap; import java.util.Map; import org.eclipse.dltk.core.DLTKCore; import org.eclipse.dltk.core.IModelElement; /** * The cache ofscriptelements to their respective info. */ public class ModelCache { public static final int DEFAULT_PROJECT_SIZE = 5; // average 25552 bytes // per project. public static final int DEFAULT_ROOT_SIZE = 50; // average 2590 bytes per // root -> maximum size : // 25900*BASE_VALUE bytes public static final int DEFAULT_PKG_SIZE = 500; // average 1782 bytes per // pkg -> maximum size : // 178200*BASE_VALUE bytes public static final int DEFAULT_OPENABLE_SIZE = 500; // average 6629 // bytes per // openable // (includes // children) -> // maximum size : // 662900*BASE_VALUE // bytes public static final int DEFAULT_CHILDREN_SIZE = 500 * 20; // average 20 // children per // openable /** * Active script Model Info */ protected ModelInfo modelInfo; /** * Cache of open projects. */ protected HashMap projectCache; /** * Cache of open package fragment roots. */ protected ElementCache rootCache; /** * Cache of open package fragments */ protected ElementCache pkgCache; /** * Cache of open compilation unit and class files */ protected ElementCache openableCache; /** * Cache of open children of openable script Model elements */ protected Map childrenCache; public ModelCache() { // set the size of the caches in function of the maximum amount of // memory available long maxMemory = Runtime.getRuntime().maxMemory(); // if max memory is infinite, set the ratio to 4d which corresponds to // the 256MB that Eclipse defaults to // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=111299) double ratio = maxMemory == Long.MAX_VALUE ? 4d : maxMemory / 64000000; // 64000000 // is // the // base // memory // for // most // JInterpreter this.projectCache = new HashMap(DEFAULT_PROJECT_SIZE); // NB: Don't use // a LRUCache // for projects // as they are // constantly // reopened // (e.g. during // delta // processing) this.rootCache = new ElementCache((int) (DEFAULT_ROOT_SIZE * ratio)); this.pkgCache = new ElementCache((int) (DEFAULT_PKG_SIZE * ratio)); this.openableCache = new ElementCache( (int) (DEFAULT_OPENABLE_SIZE * ratio)); this.childrenCache = new HashMap((int) (DEFAULT_CHILDREN_SIZE * ratio)); } /** * Returns the info for the element. */ public Object getInfo(IModelElement element) { switch (element.getElementType()) { case IModelElement.SCRIPT_MODEL: return this.modelInfo; case IModelElement.SCRIPT_PROJECT: return this.projectCache.get(element); case IModelElement.PROJECT_FRAGMENT: return this.rootCache.get(element); case IModelElement.SCRIPT_FOLDER: return this.pkgCache.get(element); case IModelElement.SOURCE_MODULE: case IModelElement.BINARY_MODULE: return this.openableCache.get(element); default: return this.childrenCache.get(element); } } /** * Returns the info for this element without disturbing the cache ordering. */ protected Object peekAtInfo(IModelElement element) { switch (element.getElementType()) { case IModelElement.SCRIPT_MODEL: return this.modelInfo; case IModelElement.SCRIPT_PROJECT: return this.projectCache.get(element); case IModelElement.PROJECT_FRAGMENT: return this.rootCache.peek(element); case IModelElement.SCRIPT_FOLDER: return this.pkgCache.peek(element); case IModelElement.SOURCE_MODULE: case IModelElement.BINARY_MODULE: return this.openableCache.peek(element); default: return this.childrenCache.get(element); } } /** * Remember the info for the element. */ protected void putInfo(IModelElement element, Object info) { switch (element.getElementType()) { case IModelElement.SCRIPT_MODEL: this.modelInfo = (ModelInfo) info; break; case IModelElement.SCRIPT_PROJECT: this.projectCache.put(element, info); this.rootCache.ensureSpaceLimit(((ModelElementInfo) info).size(), element); break; case IModelElement.PROJECT_FRAGMENT: this.rootCache.put(element, info); this.pkgCache.ensureSpaceLimit(((ModelElementInfo) info).size(), element); break; case IModelElement.SCRIPT_FOLDER: this.pkgCache.put(element, info); this.openableCache.ensureSpaceLimit(((ModelElementInfo) info) .size(), element); break; case IModelElement.SOURCE_MODULE: case IModelElement.BINARY_MODULE: this.openableCache.put(element, info); break; default: this.childrenCache.put(element, info); } } /** * Removes the info of the element from the cache. */ protected void removeInfo(IModelElement element) { switch (element.getElementType()) { case IModelElement.SCRIPT_MODEL: this.modelInfo = null; break; case IModelElement.SCRIPT_PROJECT: this.projectCache.remove(element); this.rootCache.resetSpaceLimit(DEFAULT_ROOT_SIZE, element); break; case IModelElement.PROJECT_FRAGMENT: this.rootCache.remove(element); this.pkgCache.resetSpaceLimit(DEFAULT_PKG_SIZE, element); break; case IModelElement.SCRIPT_FOLDER: this.pkgCache.remove(element); this.openableCache.resetSpaceLimit(DEFAULT_OPENABLE_SIZE, element); break; case IModelElement.SOURCE_MODULE: case IModelElement.BINARY_MODULE: this.openableCache.remove(element); break; default: this.childrenCache.remove(element); } } public String toStringFillingRation(String prefix) { final NumberFormat nf = NumberFormat.getInstance(); StringBuffer buffer = new StringBuffer(); buffer.append(prefix); buffer.append("Project cache: "); //$NON-NLS-1$ buffer.append(this.projectCache.size()); buffer.append(" projects\n"); //$NON-NLS-1$ buffer.append(prefix); buffer.append("Root cache["); //$NON-NLS-1$ buffer.append(this.rootCache.getSpaceLimit()); buffer.append("]: "); //$NON-NLS-1$ buffer.append(nf.format(this.rootCache.fillingRatio())); buffer.append("%\n"); //$NON-NLS-1$ buffer.append(prefix); buffer.append("Folder cache["); //$NON-NLS-1$ buffer.append(this.pkgCache.getSpaceLimit()); buffer.append("]: "); //$NON-NLS-1$ buffer.append(nf.format(this.pkgCache.fillingRatio())); buffer.append("%\n"); //$NON-NLS-1$ buffer.append(prefix); buffer.append("Openable cache["); //$NON-NLS-1$ buffer.append(this.openableCache.getSpaceLimit()); buffer.append("]: "); //$NON-NLS-1$ buffer.append(nf.format(this.openableCache.fillingRatio())); buffer.append("%\n"); //$NON-NLS-1$ return buffer.toString(); } protected void resetZIPTypeCache() { if (DLTKCore.DEBUG) { System.err.println("Add reset ZIP Type cache..."); //$NON-NLS-1$ } } }