| /******************************************************************************* |
| * 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$ |
| } |
| } |
| } |