From 675904073901db65acb7a1dec7660bb05ab2b872 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Tue, 22 Mar 2005 17:00:43 +0000 Subject: [PATCH] Patch for Devin Steffler. Code Reader Cache for new parser framework. --- .../core/parser/tests/ast2/CDOMBaseTest.java | 58 ++++ .../tests/ast2/CodeReaderCacheTest.java | 143 +++++++++ .../parser/tests/ast2/DOMParserTestSuite.java | 1 + .../core/util/OverflowingLRUCache.java | 10 + .../cdt/core/dom/ICodeReaderFactory.java | 7 + .../cdt/core/parser/CodeReaderCache.java | 299 ++++++++++++++++++ .../cdt/core/parser/EmptyCodeReaderCache.java | 64 ++++ .../cdt/core/parser/ICodeReaderCache.java | 48 +++ .../scanner2/FileCodeReaderFactory.java | 22 +- .../PartialWorkingCopyCodeReaderFactory.java | 16 +- .../core/dom/SavedCodeReaderFactory.java | 29 +- core/org.eclipse.cdt.ui/plugin.properties | 1 + core/org.eclipse.cdt.ui/plugin.xml | 5 + .../ui/preferences/CParserPreferencePage.java | 167 ++++++++++ .../PreferencesMessages.properties | 4 + .../contentassist/CCompletionProcessor2.java | 5 + .../cdt/ui/CUIPreferenceInitializer.java | 2 + 17 files changed, 866 insertions(+), 15 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CDOMBaseTest.java create mode 100644 core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CodeReaderCacheTest.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/CodeReaderCache.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/EmptyCodeReaderCache.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ICodeReaderCache.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/CParserPreferencePage.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CDOMBaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CDOMBaseTest.java new file mode 100644 index 00000000000..04a0079129f --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CDOMBaseTest.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.parser.tests.ast2; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.dom.CDOM; +import org.eclipse.cdt.core.dom.IASTServiceProvider.UnsupportedDialectException; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.parser.tests.FileBasePluginTest; +import org.eclipse.core.resources.IFile; + +/** + * @author dsteffle + */ +public class CDOMBaseTest extends FileBasePluginTest { + + public CDOMBaseTest(String name, Class className) { + super(name, className); + } + + protected IASTTranslationUnit parse(String fileName, String contents) { + IFile file = null; + + try { + file = importFile(fileName, contents); + } catch (Exception e) { + e.printStackTrace(); + } + + return parse(file); + } + + protected IASTTranslationUnit parse(IFile file) { + IASTTranslationUnit tu = null; + + try { + tu = CDOM.getInstance().getASTService().getTranslationUnit( + file, + CDOM.getInstance().getCodeReaderFactory( + CDOM.PARSE_SAVED_RESOURCES)); + } catch (UnsupportedDialectException e) { + e.printStackTrace(); + } + + return tu; + } + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CodeReaderCacheTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CodeReaderCacheTest.java new file mode 100644 index 00000000000..c0d32dc1a03 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CodeReaderCacheTest.java @@ -0,0 +1,143 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.core.parser.tests.ast2; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.eclipse.cdt.core.dom.CDOM; +import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.cdt.core.parser.CodeReaderCache; +import org.eclipse.cdt.core.parser.ICodeReaderCache; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; + +/** + * @author dsteffle + */ +public class CodeReaderCacheTest extends CDOMBaseTest { + + public CodeReaderCacheTest(String name) { + super(name, CodeReaderCacheTest.class); + } + + public static Test suite() { + TestSuite suite = new TestSuite( CodeReaderCacheTest.class ); + suite.addTest( new CodeReaderCacheTest("cleanupProject") ); //$NON-NLS-1$ + return suite; + } + + private class UpdateFileJob extends Job { + private IFile file = null; + private String fileName = null; + private String code = null; + + public UpdateFileJob(String name, IFile file, String fileName, String code) { + super(name); + this.file = file; + this.fileName = fileName; + this.code = code; + } + + protected IStatus run(IProgressMonitor monitor) { + while(!monitor.isCanceled()) { + try { + file = importFile(fileName, code); + } catch (Exception e) { + } + } + + return Status.OK_STATUS; + } + + public IFile getFile() { + return file; + } + } + + // THIS MUST BE RUN FIRST IN THIS TEST + public void testSetCacheSize() { + ICodeReaderCache cache = CDOM.getInstance().getCodeReaderFactory(CDOM.PARSE_SAVED_RESOURCES).getCodeReaderCache(); + // update the size of the cache... must be done for the first test since other test suites use 0MB cache size + assertTrue(cache instanceof CodeReaderCache); + ((CodeReaderCache)cache).setCacheSize(CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB); + } + + public void testSimpleCacheFunctionality() { + StringBuffer code = new StringBuffer(); + code.append("int x;"); //$NON-NLS-1$ + + IFile file = null; + try { + file = importFile("test.c", code.toString()); //$NON-NLS-1$ + } catch (Exception e) { + e.printStackTrace(); + } + + parse(file); + + ICodeReaderCache cache = CDOM.getInstance().getCodeReaderFactory(CDOM.PARSE_SAVED_RESOURCES).getCodeReaderCache(); + CodeReader reader = cache.get(file.getLocation().toOSString()); + assertNotNull(reader); + assertEquals(cache.getCurrentSpace(), 1); + assertEquals(String.valueOf(reader.filename), file.getLocation().toOSString()); + cache.remove(String.valueOf(reader.filename)); + assertEquals(cache.getCurrentSpace(), 0); + } + + public void testResourceChangedUpdate() { + boolean hasPassed = false; + StringBuffer code = new StringBuffer(); + code.append("int x;"); //$NON-NLS-1$ + ICodeReaderCache cache = CDOM.getInstance().getCodeReaderFactory(CDOM.PARSE_SAVED_RESOURCES).getCodeReaderCache(); + + IFile file = null; + + try { + file = importFile("test.c", code.toString()); //$NON-NLS-1$ + } catch (Exception e) { + e.printStackTrace(); + } + + // start a new job that repeatedly updates the file... + UpdateFileJob job = new UpdateFileJob("updater", file, "test.c", code.toString()); //$NON-NLS-1$ //$NON-NLS-2$ + job.schedule(); + + while(!hasPassed) { + if (file != null) { + parse(file); + } + + try { + Thread.sleep(1000); // give the updater thread some time to update the resource + file = job.getFile(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + if (cache.getCurrentSpace() == 0) // item was properly removed by the updater thread + hasPassed = true; + } + + job.cancel(); + } + + // THIS MUST BE RUN LAST IN THIS TEST + public void testClearCache() { + ICodeReaderCache cache = CDOM.getInstance().getCodeReaderFactory(CDOM.PARSE_SAVED_RESOURCES).getCodeReaderCache(); + // now that the + assertTrue(cache instanceof CodeReaderCache); + ((CodeReaderCache)cache).setCacheSize(0); + } +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java index 82f5c48c216..3453eac76d9 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMParserTestSuite.java @@ -35,6 +35,7 @@ public class DOMParserTestSuite extends TestCase { suite.addTestSuite( AST2UtilTests.class ); suite.addTestSuite( AST2UtilOldTests.class ); suite.addTestSuite( AST2SelectionParseTest.class ); + suite.addTestSuite( CodeReaderCacheTest.class ); return suite; } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/util/OverflowingLRUCache.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/util/OverflowingLRUCache.java index 39801a96b65..647ec195905 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/util/OverflowingLRUCache.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/util/OverflowingLRUCache.java @@ -64,6 +64,16 @@ public abstract class OverflowingLRUCache extends LRUCache { * Inital load factor of one third. */ protected double fLoadFactor = 0.333; + /** + * Creates an OverflowingLRUCache with default sizes. + * + * This is required to create a cache with a hash map that is not + * dependent on the initial size of the cache (i.e. if the cache is + * relative to size of entries and not the number of entries). + */ + public OverflowingLRUCache() { + super(); + } /** * Creates a OverflowingLRUCache. * @param size Size limit of cache. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ICodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ICodeReaderFactory.java index 83fe29cefe8..a45a3231fb1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ICodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ICodeReaderFactory.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.core.dom; import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.cdt.core.parser.ICodeReaderCache; /** * This is the interface that an AST Service uses to delegate the construction @@ -42,4 +43,10 @@ public interface ICodeReaderFactory { * @return CodeReader for contents at that path. */ public CodeReader createCodeReaderForInclusion(String path); + + /** + * Returns the ICodeReaderCache used for this ICodeReaderFacotry. + * @return the ICodeReaderCache used for this ICodeReaderFacotry + */ + public ICodeReaderCache getCodeReaderCache(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/CodeReaderCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/CodeReaderCache.java new file mode 100644 index 00000000000..cc29de971f1 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/CodeReaderCache.java @@ -0,0 +1,299 @@ +/******************************************************************************* + * Copyright (c) 2005 Rational Software Corporation and others. All rights + * reserved. This program and the accompanying materials are made available + * under the terms of the Common Public License v0.5 which accompanies this + * distribution, and is available at http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: Rational Software - Initial API and implementation + ******************************************************************************/ + +package org.eclipse.cdt.core.parser; + +import org.eclipse.cdt.internal.core.parser.InternalParserUtil; +import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator; +import org.eclipse.cdt.internal.core.util.ILRUCacheable; +import org.eclipse.cdt.internal.core.util.LRUCache; +import org.eclipse.cdt.internal.core.util.OverflowingLRUCache; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceChangeEvent; +import org.eclipse.core.resources.IResourceChangeListener; +import org.eclipse.core.resources.IResourceDelta; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; + +/** + * This is the CodeReaderBuffer used to cache CodeReaders for the ICodeReaderFactory + * when working with saved copies (primarily SavedCodeReaderFactory). + * + * @author dsteffle + */ +public class CodeReaderCache implements ICodeReaderCache { + /** + * The string used to identify this CodeReaderCache. Mainly used for preferences. + */ + public static final String CODE_READER_BUFFER="CODE_READER_CACHE"; //$NON-NLS-1$ + + /** + * The default size of the cache in MB. + */ + public static final int DEFAULT_CACHE_SIZE_IN_MB = 64; + + /** + * A String value of the default size of the cache. + */ + public static final String DEFAULT_CACHE_SIZE_IN_MB_STRING = String.valueOf(DEFAULT_CACHE_SIZE_IN_MB); + private static final int MB_TO_KB_FACTOR = 1024; + private CodeReaderLRUCache cache = null; // the actual cache + + private class UpdateCodeReaderCacheListener implements IResourceChangeListener { + ICodeReaderCache cache = null; + + /** + * Create the UpdateCodeReaderCacheListener used to dispatch events to remove CodeReaders + * from the cache when a resource is changed and detected in Eclipse. + * @param cache + */ + public UpdateCodeReaderCacheListener(ICodeReaderCache cache) { + this.cache = cache; + } + + private class RemoveCacheJob extends Job { + private static final String REMOVE_CACHE = "Remove Cache"; //$NON-NLS-1$ + ICodeReaderCache cache = null; + IResourceChangeEvent event = null; + + /** + * Create a RemoveCacheJob used to run as a separate thread to remove a CodeReader from the cache. + * @param cache + * @param event + * @param mutex + */ + public RemoveCacheJob(ICodeReaderCache cache, IResourceChangeEvent event) { + super(REMOVE_CACHE); + this.cache = cache; + this.event = event; + } + + protected IStatus run(IProgressMonitor monitor) { + String key = null; + + if (event.getSource() instanceof IWorkspace && event.getDelta() != null) { + IResourceDelta[] projects = event.getDelta().getAffectedChildren(); + for(int i=0; i 0) + ret = cache.get(key); + + // not in the cache + if (ret == null) { + ret = ParserUtil.createReader(key, EmptyIterator.EMPTY_ITERATOR); + + if (cache.getSpaceLimit() > 0) + put(ret); + } + + return ret; + } + + /** + * Put a CodeReader into the Cache. + * @param key + * @param value + * @return + */ + private synchronized CodeReader put(CodeReader value) { + if (value==null) return null; + return cache.put(String.valueOf(value.filename), value); + } + + /** + * Sets the max cache size of this cache in terms of MB. + * @param size + */ + public void setCacheSize(int size) { + cache.setSpaceLimit(size * MB_TO_KB_FACTOR); + } + + /** + * This class is a wrapper/implementor class for OverflowingLRUCache. + * + * It uses CodeReaderCacheEntry (which implements ILRUCacheable) to specify that the size of + * the cache should be relative to the size of the entries and not the number of entries. + * + * @author dsteffle + * + */ + private class CodeReaderLRUCache extends OverflowingLRUCache { + + /** + * This is a wrapper for entries to put into the OverflowingLRUCache (required to determine the + * size of entries relative to the CodeReader's file size). + * + * Although the size of the CodeReaderCache is specified in terms of MB, the actual granularity of + * the cache is KB. + * + * @author dsteffle + * + */ + private class CodeReaderCacheEntry implements ILRUCacheable { + + private static final double CHAR_TO_KB_FACTOR = 1024; + CodeReader reader = null; + int size = 0; // used to specify the size of the CodeReader in terms of KB + + public CodeReaderCacheEntry(CodeReader value) { + this.reader = value; + size = (int)Math.ceil(reader.buffer.length / CHAR_TO_KB_FACTOR); // get the size of the file in terms of KB + } + + public int getCacheFootprint() { + return size; + } + + public CodeReader getCodeReader() { + return reader; + } + } + + /** + * Creates a new CodeReaderLRUCache with a specified initial maximum size. + * @param size the maximum size of the cache in terms of MB + */ + public CodeReaderLRUCache(int size) { + super(); // need to initialize the LRUCache with super() so that the size of the hashtable isn't relative to the size in MB + this.setSpaceLimit(size); + } + + // must be overloaded, required to remove entries from the cache + protected boolean close(LRUCacheEntry entry) { + Object obj = remove(entry._fKey); + + if (obj != null) + return true; + + return false; + } + + protected LRUCache newInstance(int size, int overflow) { + return null; + } + + /** + * Removes an entry from the cache and returns the entry that was removed if found. + * Otherwise null is returned. + * @param key + * @return + */ + public CodeReader remove(String key) { + Object removed = removeKey(key); + + if (removed instanceof CodeReaderCacheEntry) + return ((CodeReaderCacheEntry)removed).getCodeReader(); + + return null; + } + + /** + * Puts a CodeReader into the cache by wrapping it with a CodeReaderCacheEntry first. + * This way the proper size of the element in the cache can be determined + * via the CodeReaderCacheEntry. + * @param key + * @param value + * @return + */ + public CodeReader put(Object key, CodeReader value) { + Object entry = new CodeReaderCacheEntry(value); + + Object ret = put(key, entry); + + if (ret instanceof CodeReaderCacheEntry) + return ((CodeReaderCacheEntry)ret).getCodeReader(); + + return null; + } + + /** + * Retrieves a CodeReader from the cache corresponding to the path specified by the key. + * @param key + * @return + */ + public CodeReader get(String key) { + Object obj = peek(key); + if (obj instanceof CodeReaderCacheEntry) + return ((CodeReaderCacheEntry)obj).getCodeReader(); + + return null; + } + + } + + /** + * Removes the CodeReader from the cache corresponding to the path specified by the key and + * returns the CodeReader that was removed. If no CodeReader is removed then null is returned. + * @param key + */ + public synchronized CodeReader remove(String key) { + return cache.remove(key); + } + + /** + * Returns the current size of the cache. For the CodeReaderCache this is in MB. + * @return + */ + public int getCurrentSpace() { + return cache.getCurrentSpace(); + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/EmptyCodeReaderCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/EmptyCodeReaderCache.java new file mode 100644 index 00000000000..fa511fc1669 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/EmptyCodeReaderCache.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2005 Rational Software Corporation and others. All rights + * reserved. This program and the accompanying materials are made available + * under the terms of the Common Public License v0.5 which accompanies this + * distribution, and is available at http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: Rational Software - Initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.core.parser; + +import java.util.Iterator; + +import org.eclipse.cdt.internal.core.parser.InternalParserUtil; +import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator; + +/** + * This is an empty implementation of the ICodeReaderCache interface. It is used to implement a + * cache for the interface that isn't actually a cache, but rather always creates new CodeReaders + * everytime a CodeReader is retrieved. + * + * This cache is not optimized to be run from within Eclipse (i.e. it ignores IResources). + * + * @author dsteffle + */ +public class EmptyCodeReaderCache implements ICodeReaderCache { + + /** + * Creates a new CodeReader and returns it. + * @param key + * @return + */ + public CodeReader get(String key) { + CodeReader ret = null; + ret = InternalParserUtil.createFileReader(key); + return ret; + } + + /** + * This provides support for PartialWorkingCopyCodeReaderFactory. + * @param finalPath + * @param workingCopies + * @return + */ + public CodeReader createReader( String finalPath, Iterator workingCopies ) { + return ParserUtil.createReader(finalPath, workingCopies); + } + + /** + * Returns null. + * @param key + * @return + */ + public CodeReader remove(String key) { + return null; + } + + /** + * Returns 0. + */ + public int getCurrentSpace() { + return 0; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ICodeReaderCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ICodeReaderCache.java new file mode 100644 index 00000000000..a3b71c1d937 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ICodeReaderCache.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2005 Rational Software Corporation and others. All rights + * reserved. This program and the accompanying materials are made available + * under the terms of the Common Public License v0.5 which accompanies this + * distribution, and is available at http://www.eclipse.org/legal/cpl-v05.html + * + * Contributors: Rational Software - Initial API and implementation + ******************************************************************************/ +package org.eclipse.cdt.core.parser; + +/** + * This is the interface to a cache for CodeReaders. + * + * For thread safety the implementations of this interface must ensure that their methods are thread safe. + * + * @author dsteffle + */ +public interface ICodeReaderCache { + + /** + * Retrieves the CodeReader corresponding to the key specified that represents the + * path for that CodeReader. If no CodeReader is found in the cache then a new CodeReader + * is created for the path and then returned. + * + * @param key the path corresponding to the CodeReader, generally: + * fileToParse.getLocation().toOSString() + * @return the CodeReader corresponding to the path specified by the key + */ + public CodeReader get(String key); + + /** + * Used to remove the CodeReader corresponding to the path specified by key from the cache. + * + * @param key the path of the CodeReader to be removed + * @return the removed CodeReader or null if not found + */ + public CodeReader remove(String key); + + /** + * Returns the amount of space that the cache is using. + * The units are relative to the implementation of the cache. It could be + * the total number of objects in the cache, or the total space the cache is + * using in MB. + * + * @return + */ + public int getCurrentSpace(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FileCodeReaderFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FileCodeReaderFactory.java index a60a52e50a1..bfaf470f8de 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FileCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/FileCodeReaderFactory.java @@ -12,7 +12,9 @@ package org.eclipse.cdt.internal.core.parser.scanner2; import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.parser.CodeReader; -import org.eclipse.cdt.internal.core.parser.InternalParserUtil; +import org.eclipse.cdt.core.parser.CodeReaderCache; +import org.eclipse.cdt.core.parser.EmptyCodeReaderCache; +import org.eclipse.cdt.core.parser.ICodeReaderCache; /** * @author jcamelon @@ -20,9 +22,11 @@ import org.eclipse.cdt.internal.core.parser.InternalParserUtil; public class FileCodeReaderFactory implements ICodeReaderFactory { private static FileCodeReaderFactory instance; + private ICodeReaderCache cache = null; - private FileCodeReaderFactory() + private FileCodeReaderFactory(ICodeReaderCache cache) { + this.cache = cache; } /* (non-Javadoc) @@ -36,23 +40,27 @@ public class FileCodeReaderFactory implements ICodeReaderFactory { * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForTranslationUnit(java.lang.String) */ public CodeReader createCodeReaderForTranslationUnit(String path) { - return InternalParserUtil.createFileReader(path); - } + return cache.get(path); + } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForInclusion(java.lang.String) */ public CodeReader createCodeReaderForInclusion(String path) { - return InternalParserUtil.createFileReader(path); - } + return cache.get(path); + } /** * @return */ public static FileCodeReaderFactory getInstance() { if( instance == null ) - instance = new FileCodeReaderFactory(); + instance = new FileCodeReaderFactory(new EmptyCodeReaderCache()); return instance; } + public ICodeReaderCache getCodeReaderCache() { + return cache; + } + } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java index 9a42e070bd2..7c941f541a8 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/PartialWorkingCopyCodeReaderFactory.java @@ -17,7 +17,8 @@ import org.eclipse.cdt.core.browser.IWorkingCopyProvider; import org.eclipse.cdt.core.dom.CDOM; import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.parser.CodeReader; -import org.eclipse.cdt.core.parser.ParserUtil; +import org.eclipse.cdt.core.parser.EmptyCodeReaderCache; +import org.eclipse.cdt.core.parser.ICodeReaderCache; import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator; /** @@ -27,12 +28,14 @@ public class PartialWorkingCopyCodeReaderFactory implements ICodeReaderFactory { private final IWorkingCopyProvider provider; + private ICodeReaderCache cache = null; /** * @param provider */ public PartialWorkingCopyCodeReaderFactory(IWorkingCopyProvider provider) { this.provider = provider; + cache = new EmptyCodeReaderCache(); } /* (non-Javadoc) @@ -46,14 +49,14 @@ public class PartialWorkingCopyCodeReaderFactory * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForTranslationUnit(java.lang.String) */ public CodeReader createCodeReaderForTranslationUnit(String path) { - return ParserUtil.createReader( path, createWorkingCopyIterator() ); + return ((EmptyCodeReaderCache)cache).createReader( path, createWorkingCopyIterator() ); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForInclusion(java.lang.String) */ public CodeReader createCodeReaderForInclusion(String path) { - return ParserUtil.createReader( path, EmptyIterator.EMPTY_ITERATOR ); + return cache.get( path ); } /** @@ -64,4 +67,11 @@ public class PartialWorkingCopyCodeReaderFactory return Arrays.asList( provider.getWorkingCopies() ).iterator(); } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#getCodeReaderCache() + */ + public ICodeReaderCache getCodeReaderCache() { + return cache; + } + } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java index 78cf35d28b1..2a421db9847 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/SavedCodeReaderFactory.java @@ -10,17 +10,20 @@ **********************************************************************/ package org.eclipse.cdt.internal.core.dom; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.CDOM; import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.parser.CodeReader; -import org.eclipse.cdt.core.parser.ParserUtil; -import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator; +import org.eclipse.cdt.core.parser.CodeReaderCache; +import org.eclipse.cdt.core.parser.ICodeReaderCache; /** * @author jcamelon */ public class SavedCodeReaderFactory implements ICodeReaderFactory { + private ICodeReaderCache cache = null; + public static SavedCodeReaderFactory getInstance() { return instance; @@ -30,6 +33,16 @@ public class SavedCodeReaderFactory implements ICodeReaderFactory { private SavedCodeReaderFactory() { + int size=0; + if (CCorePlugin.getDefault() == null || CCorePlugin.getDefault().getPluginPreferences() == null) + size = CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB; + else + size = CCorePlugin.getDefault().getPluginPreferences().getInt(CodeReaderCache.CODE_READER_BUFFER); + + if (size >= 0) + cache = new CodeReaderCache(size); + else + cache = new CodeReaderCache(CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#getUniqueIdentifier() @@ -42,14 +55,20 @@ public class SavedCodeReaderFactory implements ICodeReaderFactory { * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForTranslationUnit(java.lang.String) */ public CodeReader createCodeReaderForTranslationUnit(String path) { - return ParserUtil.createReader( path, EmptyIterator.EMPTY_ITERATOR ); + return cache.get(path); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForInclusion(java.lang.String) */ public CodeReader createCodeReaderForInclusion(String path) { - return ParserUtil.createReader( path, EmptyIterator.EMPTY_ITERATOR ); + return cache.get(path); } - + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ICodeReaderFactory#createCodeReaderForInclusion(java.lang.String) + */ + public ICodeReaderCache getCodeReaderCache() { + return cache; + } } diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index 88d0ed99407..7761e757f6a 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -222,6 +222,7 @@ HideMacrodirective.description= Hides Macro directives WorkInProgress.name=Work In Progress CDTSearch.name=Search +CDTParser.name=Parser CDTIndexerProperty.name=C/C++ Indexer diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index 16ccc1141fc..1bb5fa00e7b 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -617,6 +617,11 @@ class="org.eclipse.cdt.internal.ui.preferences.CFileTypesPreferencePage" id="org.eclipse.cdt.ui.preferences.CFileTypesPreferences"> + = 0) { + ((CodeReaderCache)cache).setCacheSize(size); + } else { + ((CodeReaderCache)cache).setCacheSize(CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB); + prefs.setValue(CodeReaderCache.CODE_READER_BUFFER, CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB); + fOverlayStore.setValue(CodeReaderCache.CODE_READER_BUFFER, CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB); + } + } catch (NumberFormatException ex){ + ((CodeReaderCache)cache).setCacheSize(CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB); + prefs.setValue(CodeReaderCache.CODE_READER_BUFFER, CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB); + fOverlayStore.setValue(CodeReaderCache.CODE_READER_BUFFER, CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB); + } + } + + fOverlayStore.propagate(); + CCorePlugin.getDefault().savePluginPreferences(); + + return true; + } + + /** + * @param store + */ + public static void initDefaults(IPreferenceStore store) { + store.setDefault(CodeReaderCache.CODE_READER_BUFFER,CodeReaderCache.DEFAULT_CACHE_SIZE_IN_MB_STRING); + } + + /* + * @see PreferencePage#performDefaults() + */ + protected void performDefaults() { + fOverlayStore.loadDefaults(); + initialize(); + super.performDefaults(); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties index 22d3d60ff90..52acc358847 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/PreferencesMessages.properties @@ -181,6 +181,10 @@ CSearchPreferences.ExternalSearchLinks.Invisible=Invisible CSearchPreferences.IndexerTimeout.IndexerTimeoutGroup=Indexer Timeout CSearchPreferences.IndexerTimeout.Timeout=Timeout (ms) +#Buffer Preferences +CBufferPreferences.CodeReaderBuffer.CodeReaderBufferGroup=CodeReader Buffer Size +CBufferPreferences.CodeReaderBuffer.Size=Size (MB) + #Open Type Preferences CEditorPreferencePage.Navigation.OpenType=Open Type CEditorPreferencePage.Navigation.CacheTypesInBackground=Cache types in background diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java index bbd7dfe4ab1..00535976d7e 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.IASTServiceProvider.UnsupportedDialectException; import org.eclipse.cdt.core.dom.ast.ASTCompletionNode; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.cdt.core.parser.ICodeReaderCache; import org.eclipse.cdt.core.parser.ParserUtil; import org.eclipse.cdt.internal.ui.text.CParameterListValidator; import org.eclipse.cdt.ui.CUIPlugin; @@ -73,6 +74,10 @@ public class CCompletionProcessor2 implements IContentAssistProcessor { public int getUniqueIdentifier() { return 99; } + public ICodeReaderCache getCodeReaderCache() { + // TODO this is useless + return null; + } } ); long stopTime = System.currentTimeMillis(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPreferenceInitializer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPreferenceInitializer.java index 56d0955359a..271f002fa12 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPreferenceInitializer.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPreferenceInitializer.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.ui; import org.eclipse.cdt.internal.ui.cview.CView; import org.eclipse.cdt.internal.ui.preferences.BuildConsolePreferencePage; import org.eclipse.cdt.internal.ui.preferences.CEditorPreferencePage; +import org.eclipse.cdt.internal.ui.preferences.CParserPreferencePage; import org.eclipse.cdt.internal.ui.preferences.CPluginPreferencePage; import org.eclipse.cdt.internal.ui.preferences.CodeAssistPreferencePage; import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; @@ -37,6 +38,7 @@ public class CUIPreferenceInitializer extends AbstractPreferenceInitializer { CPluginPreferencePage.initDefaults(store); BuildConsolePreferencePage.initDefaults(store); CView.initDefaults(store); + CParserPreferencePage.initDefaults(store); CEditorPreferencePage.initDefaults(store); CodeAssistPreferencePage.initDefaults(store);