From 79710ce4246b2d650e829983c4471c8004b9b331 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Fri, 6 Jul 2007 13:40:17 +0000 Subject: [PATCH] Fix for 195419, prevent recreation of pdoms during project delete. --- .../internal/tests/PositionTrackerTests.java | 10 +- .../internal/pdom/tests/PDOMCPPBugsTest.java | 7 +- .../org.eclipse.cdt.core/META-INF/MANIFEST.MF | 2 +- .../internal/core/model/CModelManager.java | 14 +- .../org/eclipse/cdt/core/dom/IPDOM.java | 5 +- .../cdt/internal/core/index/IndexFactory.java | 6 +- .../internal/core/pdom/CModelListener.java | 2 +- .../eclipse/cdt/internal/core/pdom/IPDOM.java | 27 +++ .../eclipse/cdt/internal/core/pdom/PDOM.java | 1 - .../cdt/internal/core/pdom/PDOMManager.java | 125 ++++++----- .../cdt/internal/core/pdom/PDOMProxy.java | 211 ++++++++++++++++++ .../core/pdom/TeamPDOMImportOperation.java | 9 +- .../cdt/internal/core/pdom/db/Chunk.java | 4 +- .../cdt/internal/core/pdom/db/Database.java | 37 +-- .../ui/indexview/CountNodeAction.java | 7 +- .../cdt/internal/ui/indexview/IndexView.java | 17 +- .../ui/indexview/IndexViewSearchQuery.java | 3 +- .../ui/indexview/OpenDefinitionAction.java | 3 +- 18 files changed, 381 insertions(+), 109 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IPDOM.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/PositionTrackerTests.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/PositionTrackerTests.java index 3037d8b4175..cf638e3b447 100644 --- a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/PositionTrackerTests.java +++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/internal/tests/PositionTrackerTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2007 Wind River Systems, Inc. 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 @@ -60,19 +60,19 @@ public class PositionTrackerTests extends TestCase { } public void testRandomDepth5() { - randomTest(20, 5, 5, 50000); + randomTest(20, 5, 5, 1000); } public void testRandomDepth10() { - randomTest(50, 10, 10, 50000); + randomTest(50, 10, 10, 1000); } public void testRandomDepth15() { - randomTest(100, 15, 15, 50000); + randomTest(100, 15, 15, 1000); } public void testRandomDepth20() { - randomTest(100, 15, 20, 50000); + randomTest(100, 15, 20, 1000); } public void testRetireDepth2() { diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMCPPBugsTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMCPPBugsTest.java index a4699ab2598..1e4a7ba58b0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMCPPBugsTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/PDOMCPPBugsTest.java @@ -61,8 +61,9 @@ public class PDOMCPPBugsTest extends BaseTestCase { } protected void setUp() throws Exception { - cproject= CProjectHelper.createCCProject("PDOMBugsTest"+System.currentTimeMillis(), "bin", IPDOMManager.ID_NO_INDEXER); super.setUp(); + cproject= CProjectHelper.createCCProject("PDOMBugsTest"+System.currentTimeMillis(), "bin", IPDOMManager.ID_FAST_INDEXER); + assertTrue(CCorePlugin.getIndexManager().joinIndexer(8000, NPM)); } protected void tearDown() throws Exception { @@ -73,7 +74,7 @@ public class PDOMCPPBugsTest extends BaseTestCase { } public void testPDOMProperties() throws Exception { - IWritableIndexFragment pdom = (IWritableIndexFragment) CCoreInternals.getPDOMManager().getPDOM(cproject); + PDOM pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject); pdom.acquireWriteLock(0); try { WritablePDOM wpdom = (WritablePDOM) pdom; @@ -89,7 +90,7 @@ public class PDOMCPPBugsTest extends BaseTestCase { } public void testProjectPDOMProperties() throws Exception { - IWritableIndexFragment pdom = (IWritableIndexFragment) CCoreInternals.getPDOMManager().getPDOM(cproject); + PDOM pdom = (PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject); pdom.acquireReadLock(); try { String id= pdom.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID); diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF index 81d9531f208..f470cc6f9a9 100644 --- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF @@ -48,7 +48,7 @@ Export-Package: org.eclipse.cdt.core, org.eclipse.cdt.internal.core.dom.parser.c;x-friends:="org.eclipse.cdt.refactoring", org.eclipse.cdt.internal.core.dom.parser.cpp;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring", org.eclipse.cdt.internal.core.envvar, - org.eclipse.cdt.internal.core.index;x-internal:=true, + org.eclipse.cdt.internal.core.index;x-friends:="org.eclipse.cdt.ui", org.eclipse.cdt.internal.core.index.provider, org.eclipse.cdt.internal.core.language, org.eclipse.cdt.internal.core.model;x-friends:="org.eclipse.cdt.ui,org.eclipse.cdt.refactoring", diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java index cad08875353..bc016d8517f 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelManager.java @@ -93,7 +93,7 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe protected DeltaProcessor fDeltaProcessor = new DeltaProcessor(); /** - * Queue of deltas created explicily by the C Model that + * Queue of deltas created explicitly by the C Model that * have yet to be fired. */ List fCModelDeltas = Collections.synchronizedList(new ArrayList()); @@ -758,7 +758,7 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe if (resource.getType() == IResource.PROJECT && ( ((IProject)resource).hasNature(CProjectNature.C_NATURE_ID) || ((IProject)resource).hasNature(CCProjectNature.CC_NATURE_ID) )){ - this.deleting((IProject) resource, delta);} + this.preDeleteProject((IProject) resource);} } catch (CoreException e) { } break; @@ -768,7 +768,7 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe if (resource.getType() == IResource.PROJECT && ( ((IProject)resource).hasNature(CProjectNature.C_NATURE_ID) || ((IProject)resource).hasNature(CCProjectNature.CC_NATURE_ID) )){ - this.closing((IProject) resource, delta);} + this.preCloseProject((IProject) resource);} } catch (CoreException e) { } break; @@ -1182,18 +1182,18 @@ public class CModelManager implements IResourceChangeListener, ICDescriptorListe } } - private void deleting(IProject project, IResourceDelta delta) { + private void preDeleteProject(IProject project) { // stop the binary runner for this project removeBinaryRunner(project); // stop indexing jobs for this project - CCoreInternals.getPDOMManager().deleteProject(create(project)); + CCoreInternals.getPDOMManager().preDeleteProject(create(project)); } - private void closing(IProject project, IResourceDelta delta) { + private void preCloseProject(IProject project) { // stop the binary runner for this project removeBinaryRunner(project); // stop indexing jobs for this project - CCoreInternals.getPDOMManager().closeProject(create(project)); + CCoreInternals.getPDOMManager().preCloseProject(create(project)); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOM.java index 6adfc229efb..d198ea46738 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/IPDOM.java @@ -14,9 +14,6 @@ package org.eclipse.cdt.core.dom; import org.eclipse.core.runtime.IAdaptable; /** - * This is the reader interface to the PDOM. It is used by general - * clients that need access to the information stored there. - * - * @author Doug Schaefer + * @deprecated use IIndex instead. */ public interface IPDOM extends IAdaptable {} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java index e2b3249ab8c..9d2421f6274 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IndexFactory.java @@ -64,7 +64,7 @@ public class IndexFactory { HashMap fragments= new LinkedHashMap(); for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) { ICProject cproject = (ICProject) iter.next(); - IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject); + IIndexFragment pdom= fPDOMManager.getPDOM(cproject); if (pdom != null) { safeAddFragment(fragments, pdom); @@ -86,7 +86,7 @@ public class IndexFactory { selectedProjects= getProjects(projects, true, false, map, new Integer(2)); for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) { ICProject cproject = (ICProject) iter.next(); - IWritableIndexFragment pdom= (IWritableIndexFragment) fPDOMManager.getPDOM(cproject); + IIndexFragment pdom= fPDOMManager.getPDOM(cproject); safeAddFragment(fragments, pdom); if(!skipProvided) { @@ -117,7 +117,7 @@ public class IndexFactory { for (Iterator iter = selectedProjects.iterator(); iter.hasNext(); ) { ICProject cproject = (ICProject) iter.next(); - safeAddFragment(readOnlyFrag, (IIndexFragment) fPDOMManager.getPDOM(cproject)); + safeAddFragment(readOnlyFrag, fPDOMManager.getPDOM(cproject)); } if (fragments.isEmpty()) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/CModelListener.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/CModelListener.java index a99421a151a..c1bfe1cef94 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/CModelListener.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/CModelListener.java @@ -66,7 +66,7 @@ public class CModelListener implements IElementChangedListener, IResourceChangeL fManager.changeProject(project, delta); break; case ICElementDelta.REMOVED: - // handled on pre-close and pre-delete + fManager.removeProject(project, delta); break; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IPDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IPDOM.java new file mode 100644 index 00000000000..57e668b3735 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IPDOM.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems, Inc. 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 + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom; + +import org.eclipse.cdt.internal.core.index.IIndexFragment; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; + +/** + * Interface for the IndexView to bridge between PDOM and PDOMProxy + */ +public interface IPDOM extends IIndexFragment { + + PDOMLinkage[] getLinkageImpls(); + + void addListener(PDOM.IListener listener); + + void removeListener(PDOM.IListener indexView); + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java index e7f3a76bb63..4507ff123bb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java @@ -29,7 +29,6 @@ import java.util.regex.Pattern; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.IName; -import org.eclipse.cdt.core.dom.IPDOM; import org.eclipse.cdt.core.dom.IPDOMNode; import org.eclipse.cdt.core.dom.IPDOMVisitor; import org.eclipse.cdt.core.dom.ast.IASTName; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java index 0ff9e3127a1..db0f876e1f4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java @@ -30,7 +30,6 @@ import java.util.Properties; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePreferenceConstants; -import org.eclipse.cdt.core.dom.IPDOM; import org.eclipse.cdt.core.dom.IPDOMIndexer; import org.eclipse.cdt.core.dom.IPDOMIndexerTask; import org.eclipse.cdt.core.dom.IPDOMManager; @@ -265,6 +264,22 @@ public class PDOMManager implements IWritableIndexManager, IListener { return fIndexProviderManager; } + /** + * Returns the pdom for the project. + * @throws CoreException + */ + public IPDOM getPDOM(ICProject project) throws CoreException { + synchronized (fProjectToPDOM) { + IProject rproject = project.getProject(); + IPDOM pdom = (IPDOM) fProjectToPDOM.get(rproject); + if (pdom == null) { + pdom= new PDOMProxy(); + fProjectToPDOM.put(rproject, pdom); + } + return pdom; + } + } + /** * Returns the pdom for the project. The call to the method may cause * opening the database. In case there is a version mismatch the data @@ -272,12 +287,12 @@ public class PDOMManager implements IWritableIndexManager, IListener { * case a pdom ready to use is returned. * @throws CoreException */ - public IPDOM getPDOM(ICProject project) throws CoreException { + private WritablePDOM getOrCreatePDOM(ICProject project) throws CoreException { synchronized (fProjectToPDOM) { IProject rproject = project.getProject(); - WritablePDOM pdom = (WritablePDOM) fProjectToPDOM.get(rproject); - if (pdom != null) { - return pdom; + IPDOM pdomProxy= (IPDOM) fProjectToPDOM.get(rproject); + if (pdomProxy instanceof WritablePDOM) { + return (WritablePDOM) pdomProxy; } String dbName= rproject.getPersistentProperty(dbNameProperty); @@ -292,49 +307,48 @@ public class PDOMManager implements IWritableIndexManager, IListener { ICProject currentCOwner= (ICProject) fFileToProject.get(dbFile); if (currentCOwner != null) { IProject currentOwner= currentCOwner.getProject(); - if (currentOwner.exists()) { - dbName= null; - dbFile= null; - } - else { - pdom= (WritablePDOM) fProjectToPDOM.remove(currentOwner); + if (!currentOwner.exists()) { fFileToProject.remove(dbFile); + dbFile.delete(); } + dbName= null; + dbFile= null; } } } - if (pdom == null) { - boolean fromScratch= false; - if (dbName == null) { - dbName = createNewDatabaseName(project); - dbFile= fileFromDatabaseName(dbName); - storeDatabaseName(rproject, dbName); - fromScratch= true; - } - - pdom= new WritablePDOM(dbFile, new PDOMProjectIndexLocationConverter(rproject), LanguageManager.getInstance().getPDOMLinkageFactoryMappings()); - if (pdom.versionMismatch() || fromScratch) { - try { - pdom.acquireWriteLock(); - } catch (InterruptedException e) { - throw new CoreException(CCorePlugin.createStatus(Messages.PDOMManager_creationOfIndexInterrupted, e)); - } - if (fromScratch) { - pdom.setCreatedFromScratch(true); - } - else { - pdom.clear(); - pdom.setClearedBecauseOfVersionMismatch(true); - } - writeProjectPDOMProperties(pdom, rproject); - pdom.releaseWriteLock(); - } - pdom.addListener(this); + boolean fromScratch= false; + if (dbName == null) { + dbName = createNewDatabaseName(project); + dbFile= fileFromDatabaseName(dbName); + storeDatabaseName(rproject, dbName); + fromScratch= true; } + + WritablePDOM pdom= new WritablePDOM(dbFile, new PDOMProjectIndexLocationConverter(rproject), LanguageManager.getInstance().getPDOMLinkageFactoryMappings()); + if (pdom.versionMismatch() || fromScratch) { + try { + pdom.acquireWriteLock(); + } catch (InterruptedException e) { + throw new CoreException(CCorePlugin.createStatus(Messages.PDOMManager_creationOfIndexInterrupted, e)); + } + if (fromScratch) { + pdom.setCreatedFromScratch(true); + } + else { + pdom.clear(); + pdom.setClearedBecauseOfVersionMismatch(true); + } + writeProjectPDOMProperties(pdom, rproject); + pdom.releaseWriteLock(); + } + pdom.addListener(this); fFileToProject.put(dbFile, project); fProjectToPDOM.put(rproject, pdom); + if (pdomProxy instanceof PDOMProxy) { + ((PDOMProxy) pdomProxy).setDelegate(pdom); + } return pdom; } } @@ -470,7 +484,7 @@ public class PDOMManager implements IWritableIndexManager, IListener { IProject prj= project.getProject(); try { synchronized (fUpdatePolicies) { - WritablePDOM pdom= (WritablePDOM) getPDOM(project); + WritablePDOM pdom= getOrCreatePDOM(project); Properties props= IndexerPreferences.getProperties(prj); IPDOMIndexer indexer= createIndexer(project, getIndexerId(project), props); @@ -721,32 +735,33 @@ public class PDOMManager implements IWritableIndexManager, IListener { } } - public void deleteProject(ICProject cproject) { - removeProject(cproject, true); + public void preDeleteProject(ICProject cproject) { + preRemoveProject(cproject, true); } - public void closeProject(ICProject cproject) { - removeProject(cproject, false); + public void preCloseProject(ICProject cproject) { + preRemoveProject(cproject, false); } - private void removeProject(ICProject cproject, final boolean delete) { + private void preRemoveProject(ICProject cproject, final boolean delete) { assert !Thread.holdsLock(fProjectToPDOM); IPDOMIndexer indexer= getIndexer(cproject); if (indexer != null) { stopIndexer(indexer); } unregisterPreferenceListener(cproject); - WritablePDOM pdom= null; + Object pdom= null; synchronized (fProjectToPDOM) { IProject rproject= cproject.getProject(); - pdom = (WritablePDOM) fProjectToPDOM.remove(rproject); - if (pdom != null) { - fFileToProject.remove(pdom.getDB().getLocation()); + pdom = fProjectToPDOM.remove(rproject); + // if the project is closed allow to reuse the pdom. + if (pdom instanceof WritablePDOM && !delete) { + fFileToProject.remove(((WritablePDOM) pdom).getDB().getLocation()); } } - if (pdom != null) { - final WritablePDOM finalpdom= pdom; + if (pdom instanceof WritablePDOM) { + final WritablePDOM finalpdom= (WritablePDOM) pdom; Job job= new Job(Messages.PDOMManager_ClosePDOMJob) { protected IStatus run(IProgressMonitor monitor) { try { @@ -775,6 +790,14 @@ public class PDOMManager implements IWritableIndexManager, IListener { fUpdatePolicies.remove(cproject); } } + + void removeProject(ICProject cproject, ICElementDelta delta) { + synchronized (fProjectToPDOM) { + IProject rproject= cproject.getProject(); + fProjectToPDOM.remove(rproject); + // don't remove the location, because it may not be reused when the project was deleted. + } + } private void stopIndexer(IPDOMIndexer indexer) { assert !Thread.holdsLock(fProjectToPDOM); @@ -1080,7 +1103,7 @@ public class PDOMManager implements IWritableIndexManager, IListener { } try { // copy it - PDOM pdom= (PDOM) getPDOM(cproject); + PDOM pdom= getOrCreatePDOM(cproject); pdom.acquireReadLock(); String oldID= null; try { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java new file mode 100644 index 00000000000..3501b8471b8 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMProxy.java @@ -0,0 +1,211 @@ +/******************************************************************************* + * Copyright (c) 2007 Wind River Systems, Inc. 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 + * + * Contributors: + * Markus Schorn - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.pdom; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.regex.Pattern; + +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.index.IIndexFileLocation; +import org.eclipse.cdt.core.index.IIndexLinkage; +import org.eclipse.cdt.core.index.IndexFilter; +import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; +import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; +import org.eclipse.cdt.internal.core.index.IIndexFragmentInclude; +import org.eclipse.cdt.internal.core.index.IIndexFragmentName; +import org.eclipse.cdt.internal.core.pdom.PDOM.IListener; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * The PDOMProxy is returned by the PDOMManager before the indexer kicks in. Also and more + * importantly it is returned when the indexer has been shut down (clients may not be aware + * of this yet). Doing that prevents the creation of empty pdoms for deleted projects. + */ +public class PDOMProxy implements IPDOM { + private PDOM fDelegate; + private int fReadLockCount; + private Set fListeners= new HashSet(); + + public synchronized void acquireReadLock() throws InterruptedException { + if (fDelegate != null) + fDelegate.acquireReadLock(); + else { + fReadLockCount++; + } + } + + public synchronized IIndexFragmentBinding adaptBinding(IBinding binding) throws CoreException { + if (fDelegate != null) + return fDelegate.adaptBinding(binding); + return null; + } + + public synchronized IIndexFragmentBinding adaptBinding(IIndexFragmentBinding proxy) throws CoreException { + if (fDelegate != null) + return fDelegate.adaptBinding(proxy); + return null; + } + + public synchronized IIndexFragmentBinding findBinding(IASTName astName) throws CoreException { + if (fDelegate != null) + return fDelegate.findBinding(astName); + return null; + } + + public synchronized IIndexFragmentBinding[] findBindings(char[][] names, IndexFilter filter, + IProgressMonitor monitor) throws CoreException { + if (fDelegate != null) + return fDelegate.findBindings(names, filter, monitor); + + return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY; + } + + public synchronized IIndexFragmentBinding[] findBindings(Pattern[] patterns, boolean isFullyQualified, + IndexFilter filter, IProgressMonitor monitor) throws CoreException { + if (fDelegate != null) + return fDelegate.findBindings(patterns, isFullyQualified, filter, monitor); + + return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY; + } + + public synchronized IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix, boolean filescope, + IndexFilter filter, IProgressMonitor monitor) throws CoreException { + if (fDelegate != null) + return fDelegate.findBindingsForPrefix(prefix, filescope, filter, monitor); + + return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY; + } + + public synchronized IIndexFragmentInclude[] findIncludedBy(IIndexFragmentFile file) throws CoreException { + if (fDelegate != null) + return fDelegate.findIncludedBy(file); + + return new IIndexFragmentInclude[0]; + } + + public synchronized IIndexFragmentName[] findNames(IIndexFragmentBinding binding, int flags) + throws CoreException { + if (fDelegate != null) + return fDelegate.findNames(binding, flags); + + return IIndexFragmentName.EMPTY_NAME_ARRAY; + } + + public synchronized long getCacheHits() { + if (fDelegate != null) + return fDelegate.getCacheHits(); + + return 0; + } + + public synchronized long getCacheMisses() { + if (fDelegate != null) + return fDelegate.getCacheMisses(); + + return 0; + } + + public synchronized IIndexFragmentFile getFile(IIndexFileLocation location) throws CoreException { + if (fDelegate != null) + return fDelegate.getFile(location); + + return null; + } + + public synchronized long getLastWriteAccess() { + if (fDelegate != null) + return fDelegate.getLastWriteAccess(); + + return 0; + } + + public synchronized IIndexLinkage[] getLinkages() { + if (fDelegate != null) + return fDelegate.getLinkages(); + + return new IIndexLinkage[0]; + } + + public synchronized String getProperty(String propertyName) throws CoreException { + if (fDelegate != null) + return fDelegate.getProperty(propertyName); + + return null; + } + + public synchronized void releaseReadLock() { + if (fDelegate != null) + fDelegate.releaseReadLock(); + else { + fReadLockCount--; + } + } + + public synchronized void resetCacheCounters() { + if (fDelegate != null) + fDelegate.resetCacheCounters(); + } + + public synchronized Object getAdapter(Class adapter) { + if (adapter.isAssignableFrom(PDOMProxy.class)) { + return this; + } + return null; + } + + public synchronized void addListener(IListener listener) { + if (fDelegate != null) + fDelegate.addListener(listener); + else { + fListeners.add(listener); + } + } + + public synchronized PDOMLinkage[] getLinkageImpls() { + if (fDelegate != null) + return fDelegate.getLinkageImpls(); + + return new PDOMLinkage[0]; + } + + public synchronized void removeListener(IListener listener) { + if (fDelegate != null) + fDelegate.removeListener(listener); + else { + fListeners.remove(listener); + } + } + + public synchronized void setDelegate(WritablePDOM pdom) { + fDelegate= pdom; + try { + while (fReadLockCount-- > 0) { + pdom.acquireReadLock(); + } + for (Iterator iterator = fListeners.iterator(); iterator.hasNext();) { + IListener listener = (IListener) iterator.next(); + pdom.addListener(listener); + } + } + catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + for (Iterator iterator = fListeners.iterator(); iterator.hasNext();) { + IListener listener = (IListener) iterator.next(); + listener.handleChange(fDelegate); + } + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMImportOperation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMImportOperation.java index e238e3499b9..fa03036f143 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMImportOperation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/TeamPDOMImportOperation.java @@ -194,8 +194,13 @@ public class TeamPDOMImportOperation implements IWorkspaceRunnable { private void checkIndex(Map checksums, IProgressMonitor monitor) throws CoreException, InterruptedException { List filesToCheck= new ArrayList(); - - WritablePDOM pdom= (WritablePDOM) CCoreInternals.getPDOMManager().getPDOM(fProject); + + IPDOM obj= CCoreInternals.getPDOMManager().getPDOM(fProject); + if (!(obj instanceof WritablePDOM)) { + return; + } + + WritablePDOM pdom= (WritablePDOM) obj; pdom.acquireReadLock(); try { if (pdom.versionMismatch()) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java index 83c3a28fed4..3e32ffdc12c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Chunk.java @@ -39,7 +39,7 @@ final class Chunk { void read() throws CoreException { try { final ByteBuffer buf= ByteBuffer.wrap(fBuffer); - fDatabase.getFileChannel().read(buf, fSequenceNumber*Database.CHUNK_SIZE); + fDatabase.read(buf, fSequenceNumber*Database.CHUNK_SIZE); } catch (IOException e) { throw new CoreException(new DBStatus(e)); } @@ -48,7 +48,7 @@ final class Chunk { void flush() throws CoreException { try { final ByteBuffer buf= ByteBuffer.wrap(fBuffer); - fDatabase.getFileChannel().write(buf, fSequenceNumber*Database.CHUNK_SIZE); + fDatabase.write(buf, fSequenceNumber*Database.CHUNK_SIZE); } catch (IOException e) { throw new CoreException(new DBStatus(e)); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java index dbb664827e1..6135b4e1bc1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/db/Database.java @@ -60,8 +60,8 @@ import org.eclipse.core.runtime.Status; */ public class Database { - private final File location; - private final RandomAccessFile file; + private final File fLocation; + private final RandomAccessFile fFile; private boolean fExclusiveLock= false; // necessary for any write operation private boolean fLocked; // necessary for any operation. private boolean fIsMarkedIncomplete= false; @@ -98,33 +98,38 @@ public class Database { */ public Database(File location, ChunkCache cache, int version, boolean openReadOnly) throws CoreException { try { - this.location = location; - this.file = new RandomAccessFile(location, openReadOnly ? "r" : "rw"); //$NON-NLS-1$ //$NON-NLS-2$ - this.fCache= cache; + fLocation = location; + fFile = new RandomAccessFile(location, openReadOnly ? "r" : "rw"); //$NON-NLS-1$ //$NON-NLS-2$ + fCache= cache; - int nChunks = Math.max(1, (int) (file.length() / CHUNK_SIZE)); + int nChunksOnDisk = (int) (fFile.length() / CHUNK_SIZE); fHeaderChunk= new Chunk(this, 0); fHeaderChunk.fLocked= true; // never makes it into the cache, needed to satisfy assertions - fChunks = new Chunk[nChunks]; // chunk[0] is unused. - if (nChunks == 0) { + if (nChunksOnDisk <= 0) { fVersion= version; + fChunks= new Chunk[1]; } else { fHeaderChunk.read(); fVersion= fHeaderChunk.getInt(0); + fChunks = new Chunk[nChunksOnDisk]; // chunk[0] is unused. } } catch (IOException e) { throw new CoreException(new DBStatus(e)); } } - - FileChannel getFileChannel() { - return file.getChannel(); + + void read(ByteBuffer buf, int i) throws IOException { + fFile.getChannel().read(buf, i); + } + + void write(ByteBuffer buf, int i) throws IOException { + fFile.getChannel().write(buf, i); } public void transferTo(FileChannel target) throws IOException { assert fLocked; - final FileChannel from= file.getChannel(); + final FileChannel from= fFile.getChannel(); from.transferTo(0, from.size(), target); } @@ -153,7 +158,7 @@ public class Database { fChunks = new Chunk[] {null}; try { fHeaderChunk.flush(); // zero out header chunk - file.getChannel().truncate(CHUNK_SIZE); // truncate database + fFile.getChannel().truncate(CHUNK_SIZE); // truncate database } catch (IOException e) { CCorePlugin.log(e); @@ -424,7 +429,7 @@ public class Database { fHeaderChunk.fDirty= false; fChunks= new Chunk[] {null}; try { - file.close(); + fFile.close(); } catch (IOException e) { throw new CoreException(new DBStatus(e)); } @@ -434,7 +439,7 @@ public class Database { * This method is public for testing purposes only. */ public File getLocation() { - return location; + return fLocation; } /** @@ -582,7 +587,7 @@ public class Database { fIsMarkedIncomplete= true; try { final ByteBuffer buf= ByteBuffer.wrap(new byte[4]); - file.getChannel().write(buf, 0); + fFile.getChannel().write(buf, 0); } catch (IOException e) { throw new CoreException(new DBStatus(e)); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java index e30e8d2bec4..9c487c40e02 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/CountNodeAction.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.core.CCoreInternals; +import org.eclipse.cdt.internal.core.pdom.IPDOM; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.IBTreeVisitor; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; @@ -72,7 +73,11 @@ public class CountNodeAction extends IndexAction { continue; ICProject project = (ICProject)objs[i]; - final PDOM pdom = (PDOM)CCoreInternals.getPDOMManager().getPDOM(project); + IPDOM ipdom= CCoreInternals.getPDOMManager().getPDOM(project); + if (!(ipdom instanceof PDOM)) { + continue; + } + final PDOM pdom = (PDOM) ipdom; //pdom.getDB().reportFreeBlocks(); pdom.acquireReadLock(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java index a9bdbdf3181..0353b7b0d62 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexView.java @@ -55,6 +55,7 @@ import org.eclipse.cdt.core.model.IElementChangedListener; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.core.CCoreInternals; +import org.eclipse.cdt.internal.core.pdom.IPDOM; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; @@ -217,7 +218,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang ICProject cproject= node.getProject(); if (cproject != null && cproject.getProject().isOpen()) { Long ts= (Long) fTimestampPerProject.get(cproject.getElementName()); - PDOM pdom= (PDOM)CCoreInternals.getPDOMManager().getPDOM(cproject); + IPDOM pdom= CCoreInternals.getPDOMManager().getPDOM(cproject); pdom.acquireReadLock(); try { if (ts == null || ts.longValue() == pdom.getLastWriteAccess()) { @@ -238,7 +239,7 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang } private Object[] computeChildren(ICProject cproject) throws CoreException, InterruptedException { - PDOM pdom = (PDOM)CCoreInternals.getPDOMManager().getPDOM(cproject); + IPDOM pdom = CCoreInternals.getPDOMManager().getPDOM(cproject); pdom.acquireReadLock(); try { fTimestampPerProject.put(cproject.getElementName(), new Long(pdom.getLastWriteAccess())); @@ -291,8 +292,8 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang try { ICProject[] projects = model.getCProjects(); for (int i = 0; i < projects.length; ++i) { - PDOM pdom = (PDOM)CCoreInternals.getPDOMManager().getPDOM(projects[i]); - pdom.addListener(this); + IPDOM pdom = CCoreInternals.getPDOMManager().getPDOM(projects[i]); + pdom.addListener(this); } } catch (CoreException e) { CUIPlugin.getDefault().log(e); @@ -334,8 +335,8 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang try { ICProject[] projects = model.getCProjects(); for (int i = 0; i < projects.length; ++i) { - PDOM pdom = (PDOM)CCoreInternals.getPDOMManager().getPDOM(projects[i]); - pdom.removeListener(this); + IPDOM pdom = CCoreInternals.getPDOMManager().getPDOM(projects[i]); + pdom.removeListener(this); } } catch (CoreException e) { CUIPlugin.getDefault().log(e); @@ -443,9 +444,9 @@ public class IndexView extends ViewPart implements PDOM.IListener, IElementChang switch (delta.getKind()) { case ICElementDelta.ADDED: try { - PDOM pdom = ((PDOM)CCoreInternals.getPDOMManager().getPDOM((ICProject)delta.getElement())); + IPDOM pdom = CCoreInternals.getPDOMManager().getPDOM((ICProject)delta.getElement()); pdom.addListener(this); - handleChange(pdom); + handleChange(null); } catch (CoreException e) { } break; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexViewSearchQuery.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexViewSearchQuery.java index 1a66d8b0948..ad55e2ed460 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexViewSearchQuery.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/IndexViewSearchQuery.java @@ -25,7 +25,6 @@ import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.core.CCoreInternals; -import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.ui.search.PDOMSearchQuery; @@ -51,7 +50,7 @@ public class IndexViewSearchQuery extends PDOMSearchQuery { public IStatus runWithIndex(IIndex index, IProgressMonitor monitor) throws OperationCanceledException { try { - if (((PDOM) CCoreInternals.getPDOMManager().getPDOM(fProject)).getLastWriteAccess() == fLastWrite) { + if (CCoreInternals.getPDOMManager().getPDOM(fProject).getLastWriteAccess() == fLastWrite) { createMatches(index, fBinding); } return Status.OK_STATUS; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/OpenDefinitionAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/OpenDefinitionAction.java index 4b6609c51ad..fff28af39cc 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/OpenDefinitionAction.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/indexview/OpenDefinitionAction.java @@ -34,7 +34,6 @@ import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.internal.core.CCoreInternals; -import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.ui.util.EditorUtility; @@ -88,7 +87,7 @@ public class OpenDefinitionAction extends IndexAction { throws InterruptedException, CoreException, CModelException, PartInitException { index.acquireReadLock(); try { - if (indexView.getLastWriteAccess(cproject) != ((PDOM) CCoreInternals.getPDOMManager().getPDOM(cproject)).getLastWriteAccess()) { + if (indexView.getLastWriteAccess(cproject) != CCoreInternals.getPDOMManager().getPDOM(cproject).getLastWriteAccess()) { return true; } IIndexName[] defs= index.findDefinitions((IIndexBinding) bindingNode.fObject);