All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aspectj.org.eclipse.jdt.internal.core.JavaModelCache Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Terry Parker  (Google Inc.)  https://bugs.eclipse.org/365499
 *     Stephan Herrmann - Contribution for
 *								Bug 440477 - [null] Infrastructure for feeding external annotations into compilation
 *******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.core;
import java.util.HashMap;
import java.util.Map;

import org.aspectj.org.eclipse.jdt.core.IJavaElement;
import org.aspectj.org.eclipse.jdt.core.IJavaProject;
import org.aspectj.org.eclipse.jdt.core.IPackageFragment;
import org.aspectj.org.eclipse.jdt.core.IPackageFragmentRoot;
import org.aspectj.org.eclipse.jdt.core.ITypeRoot;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryInfo;
import org.aspectj.org.eclipse.jdt.internal.compiler.env.IElementInfo;
import org.aspectj.org.eclipse.jdt.internal.core.util.LRUCache;
import org.aspectj.org.eclipse.jdt.internal.core.util.Util;

/**
 * The cache of java elements to their respective info.
 */
public class JavaModelCache {
	public static boolean VERBOSE = false;
	public static boolean DEBUG_CACHE_INSERTIONS = false;

	public static final int DEFAULT_ROOT_SIZE = 2_000;
	public static final int DEFAULT_PKG_SIZE = 20_000;
	public static final int DEFAULT_OPENABLE_SIZE = 200_000;

	public static final String RATIO_PROPERTY = "org.eclipse.jdt.core.javamodelcache.ratio"; //$NON-NLS-1$
	public static final String JAR_TYPE_RATIO_PROPERTY = "org.eclipse.jdt.core.javamodelcache.jartyperatio"; //$NON-NLS-1$

	public static final IBinaryInfo NON_EXISTING_JAR_TYPE_INFO = new IBinaryInfo() {/*empty marker instance only*/};

	/*
	 * The memory ratio that should be applied to the above constants.
	 */
	protected double memoryRatio = -1;

	/**
	 * Active Java Model Info
	 */
	protected JavaElementInfo 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 Java Model Java elements
	 */
	protected Map childrenCache;

	/**
	 * Cache of open binary type (inside a jar) that have a non-open parent
	 * Values are either instance of IBinaryType or Object (see {@link #NON_EXISTING_JAR_TYPE_INFO})
	 */
	protected LRUCache jarTypeCache;

public JavaModelCache() {
	double openableRatio = getOpenableRatio();
	int rootCacheSize = sizeLimit(DEFAULT_ROOT_SIZE * openableRatio);
	int packageCacheeSize = sizeLimit(DEFAULT_PKG_SIZE * openableRatio);
	int openableCacheSize = sizeLimit(DEFAULT_OPENABLE_SIZE * openableRatio);

	// NB: Don't use a LRUCache for projects as they are
	// constantly reopened (e.g. during delta processing)
	this.projectCache = new HashMap<>();  // HashMap size adjusts automatically
	if (VERBOSE) {
		this.rootCache = new VerboseElementCache<>(rootCacheSize, "Root cache"); //$NON-NLS-1$
		this.pkgCache = new VerboseElementCache<>(packageCacheeSize, "Package cache"); //$NON-NLS-1$
		this.openableCache = new VerboseElementCache<>(openableCacheSize, "Openable cache"); //$NON-NLS-1$
	} else {
		this.rootCache = new ElementCache<>(rootCacheSize);
		this.pkgCache = new ElementCache<>(packageCacheeSize);
		this.openableCache = new ElementCache<>(openableCacheSize);
	}
	this.childrenCache = new HashMap<>(); // HashMap size adjusts automatically
	resetJarTypeCache();
}

private int sizeLimit(double d) {
	return (int) Double.min(Integer.MAX_VALUE/2,d);
}

private double getOpenableRatio() {
	return getRatioForProperty(RATIO_PROPERTY);
}

private double getJarTypeRatio() {
	return getRatioForProperty(JAR_TYPE_RATIO_PROPERTY);
}

private double getRatioForProperty(String propertyName) {
	String property = System.getProperty(propertyName);
	if (property != null) {
		try {
			return Double.parseDouble(property);
		} catch (NumberFormatException e) {
			// ignore
			Util.log(e, "Could not parse value for " + propertyName + ": " + property); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}
	return 1.0;
}

/**
 *  Returns the info for the element.
 */
public IElementInfo getInfo(IJavaElement element) {
	switch (element.getElementType()) {
		case IJavaElement.JAVA_MODEL:
			return this.modelInfo;
		case IJavaElement.JAVA_PROJECT:
			return this.projectCache.get(element);
		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
			return this.rootCache.get((IPackageFragmentRoot) element);
		case IJavaElement.PACKAGE_FRAGMENT:
			return this.pkgCache.get((IPackageFragment) element);
		case IJavaElement.COMPILATION_UNIT:
		case IJavaElement.CLASS_FILE:
			return this.openableCache.get((ITypeRoot) element);
		case IJavaElement.TYPE:
			IElementInfo result = this.jarTypeCache.get(element);
			if (result != null)
				return result;
			else
				return this.childrenCache.get(element);
		default:
			return this.childrenCache.get(element);
	}
}

/*
 *  Returns the existing element that is equal to the given element if present in the cache.
 *  Returns the given element otherwise.
 */
public IJavaElement getExistingElement(IJavaElement element) {
	switch (element.getElementType()) {
		case IJavaElement.JAVA_MODEL:
			return element;
		case IJavaElement.JAVA_PROJECT:
			return element; // projectCache is a Hashtable and Hashtables don't support getKey(...)
		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
			return this.rootCache.getKey((IPackageFragmentRoot) element);
		case IJavaElement.PACKAGE_FRAGMENT:
			return this.pkgCache.getKey((IPackageFragment) element);
		case IJavaElement.COMPILATION_UNIT:
		case IJavaElement.CLASS_FILE:
			return this.openableCache.getKey((ITypeRoot) element);
		case IJavaElement.TYPE:
			return element; // jarTypeCache or childrenCache are Hashtables and Hashtables don't support getKey(...)
		default:
			return element; // childrenCache is a Hashtable and Hashtables don't support getKey(...)
	}
}

/**
 *  Returns the info for this element without
 *  disturbing the cache ordering.
 */
protected IElementInfo peekAtInfo(IJavaElement element) {
	switch (element.getElementType()) {
		case IJavaElement.JAVA_MODEL:
			return this.modelInfo;
		case IJavaElement.JAVA_PROJECT:
			return this.projectCache.get(element);
		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
			return this.rootCache.peek((IPackageFragmentRoot) element);
		case IJavaElement.PACKAGE_FRAGMENT:
			return this.pkgCache.peek((IPackageFragment) element);
		case IJavaElement.COMPILATION_UNIT:
		case IJavaElement.CLASS_FILE:
			return this.openableCache.peek((ITypeRoot) element);
		case IJavaElement.TYPE:
			IElementInfo result = this.jarTypeCache.peek(element);
			if (result != null)
				return result;
			else
				return this.childrenCache.get(element);
		default:
			return this.childrenCache.get(element);
	}
}

/**
 * Remember the info for the element.
 */
protected void putInfo(IJavaElement element, IElementInfo info) {
	switch (element.getElementType()) {
		case IJavaElement.JAVA_MODEL:
			this.modelInfo = (JavaElementInfo) info;
			break;
		case IJavaElement.JAVA_PROJECT:
			this.projectCache.put((IJavaProject) element, (JavaElementInfo) info);
			this.rootCache.ensureSpaceLimit((JavaElementInfo) info, element);
			break;
		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
			this.rootCache.put((IPackageFragmentRoot) element, (JavaElementInfo) info);
			this.pkgCache.ensureSpaceLimit((JavaElementInfo) info, element);
			break;
		case IJavaElement.PACKAGE_FRAGMENT:
			this.pkgCache.put((IPackageFragment) element, (JavaElementInfo) info);
			this.openableCache.ensureSpaceLimit((JavaElementInfo) info, element);
			break;
		case IJavaElement.COMPILATION_UNIT:
		case IJavaElement.CLASS_FILE:
			this.openableCache.put((ITypeRoot) element, (JavaElementInfo) info);
			break;
		default:
			this.childrenCache.put(element, info);
			return; // don't trace children -- too many
	}
	if (DEBUG_CACHE_INSERTIONS) {
		JavaModelManager.trace(Thread.currentThread() + " cache putInfo " + getCacheType(element) + " " + element.getElementName() + ", " + info.getClass().getSimpleName());  //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
	}
}

static String getCacheType(IJavaElement element) {
	String elementType;
	switch (element.getElementType()) {
		case IJavaElement.JAVA_MODEL:
			elementType = "JAVA_MODEL"; //$NON-NLS-1$
			break;
		case IJavaElement.JAVA_PROJECT:
			elementType = "JAVA_PROJECT"; //$NON-NLS-1$
			break;
		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
			elementType = "PACKAGE_FRAGMENT_ROOT"; //$NON-NLS-1$
			break;
		case IJavaElement.PACKAGE_FRAGMENT:
			elementType = "PACKAGE_FRAGMENT"; //$NON-NLS-1$
			break;
		case IJavaElement.CLASS_FILE:
			elementType = "CLASS_FILE"; //$NON-NLS-1$
			break;
		case IJavaElement.COMPILATION_UNIT:
			elementType = "COMPILATION_UNIT"; //$NON-NLS-1$
			break;
		default:
			elementType = "CHILD"; //$NON-NLS-1$
	}
	return elementType + ", " + element.getClass().getSimpleName(); //$NON-NLS-1$
}

/**
 * Removes the info of the element from the cache.
 */
protected void removeInfo(JavaElement element) {
	switch (element.getElementType()) {
		case IJavaElement.JAVA_MODEL:
			this.modelInfo = null;
			break;
		case IJavaElement.JAVA_PROJECT:
			this.projectCache.remove((IJavaProject)element);
			this.rootCache.resetSpaceLimit(element);
			break;
		case IJavaElement.PACKAGE_FRAGMENT_ROOT:
			this.rootCache.remove((IPackageFragmentRoot) element);
			this.pkgCache.resetSpaceLimit(element);
			break;
		case IJavaElement.PACKAGE_FRAGMENT:
			this.pkgCache.remove((IPackageFragment) element);
			this.openableCache.resetSpaceLimit(element);
			break;
		case IJavaElement.COMPILATION_UNIT:
		case IJavaElement.CLASS_FILE:
			this.openableCache.remove((ITypeRoot) element);
			break;
		default:
			this.childrenCache.remove(element);
			return; // don't trace children -- too many
	}
	if (DEBUG_CACHE_INSERTIONS) {
		JavaModelManager.trace(Thread.currentThread() + " cache removeInfo " + getCacheType(element) + " " + element.getElementName());  //$NON-NLS-1$//$NON-NLS-2$
	}
}
protected void resetJarTypeCache() {
	int jarTypeCacheSize = sizeLimit(DEFAULT_OPENABLE_SIZE * getJarTypeRatio());
	this.jarTypeCache = new LRUCache<>(jarTypeCacheSize);
}
protected void removeFromJarTypeCache(BinaryType type) {
	this.jarTypeCache.flush(type);
}
@Override
public String toString() {
	return toStringFillingRation(""); //$NON-NLS-1$
}
public String toStringFillingRation(String prefix) {
	StringBuilder buffer = new StringBuilder();
	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(this.rootCache.toStringFillingRation("Root cache")); //$NON-NLS-1$
	buffer.append('\n');
	buffer.append(prefix);
	buffer.append(this.pkgCache.toStringFillingRation("Package cache")); //$NON-NLS-1$
	buffer.append('\n');
	buffer.append(prefix);
	buffer.append(this.openableCache.toStringFillingRation("Openable cache")); //$NON-NLS-1$
	buffer.append('\n');
	buffer.append(prefix);
	buffer.append(this.jarTypeCache.toStringFillingRation("Jar type cache")); //$NON-NLS-1$
	buffer.append('\n');
	return buffer.toString();
}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy