blob: ccc1b0237893d4d2b087623636924d9bb80ea306 [file] [log] [blame]
/*******************************************************************************
* 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$
}
}
}