Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java112
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexProviderManagerTest.java201
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java31
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/IndexProviderManager.java180
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/Messages.java1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/PDOMCache.java55
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/messages.properties1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java95
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java10
-rw-r--r--doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning.html350
-rw-r--r--doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning_files/image001.jpgbin0 -> 37182 bytes
-rw-r--r--doc/org.eclipse.cdt.doc.isv/topics_Guide.xml1
12 files changed, 915 insertions, 122 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java
new file mode 100644
index 00000000000..a2e41c70274
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/EmptyIndexFragment.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Symbian Software Ltd. 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:
+ * Andrew Ferguson (Symbian) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.index.tests;
+
+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.IIndexFragment;
+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.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+
+/**
+ * An empty index fragment implementation
+ * @since 4.0.1
+ */
+public class EmptyIndexFragment implements IIndexFragment {
+ public void acquireReadLock() throws InterruptedException {}
+
+ public IIndexFragmentBinding adaptBinding(IBinding binding)
+ throws CoreException {
+ return null;
+ }
+
+ public IIndexFragmentBinding adaptBinding(IIndexFragmentBinding proxy)
+ throws CoreException {
+ return null;
+ }
+
+ public IIndexFragmentBinding findBinding(IASTName astName) throws CoreException {
+ return null;
+ }
+
+ public IIndexFragmentBinding[] findBindings(Pattern[] patterns,
+ boolean isFullyQualified, IndexFilter filter,
+ IProgressMonitor monitor) throws CoreException {
+ return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY;
+ }
+
+ public IIndexFragmentBinding[] findBindings(char[][] names,
+ IndexFilter filter, IProgressMonitor monitor) throws CoreException {
+ return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY;
+ }
+
+ public IIndexFragmentBinding[] findBindingsForPrefix(char[] prefix,
+ boolean filescope, IndexFilter filter, IProgressMonitor monitor)
+ throws CoreException {
+ return IIndexFragmentBinding.EMPTY_INDEX_BINDING_ARRAY;
+ }
+
+ public IIndexFragmentInclude[] findIncludedBy(IIndexFragmentFile file)
+ throws CoreException {
+ return IIndexFragmentInclude.EMPTY_FRAGMENT_INCLUDES_ARRAY;
+ }
+
+ public IIndexFragmentName[] findNames(IIndexFragmentBinding binding,
+ int flags) throws CoreException {
+ return IIndexFragmentName.EMPTY_NAME_ARRAY;
+ }
+
+ public long getCacheHits() {
+ return 0;
+ }
+
+ public long getCacheMisses() {
+ return 0;
+ }
+
+ public IIndexFragmentFile getFile(IIndexFileLocation location)
+ throws CoreException {
+ return null;
+ }
+
+ public long getLastWriteAccess() {
+ return 0;
+ }
+
+ public IIndexLinkage[] getLinkages() {
+ return IIndexLinkage.EMPTY_INDEX_LINKAGE_ARRAY;
+ }
+
+ public String getProperty(String key) throws CoreException {
+ if(IIndexFragment.PROPERTY_FRAGMENT_ID.equals(key)) {
+ return "org.eclipse.cdt.internal.core.index.EmptyIndexFragment"; //$NON-NLS-1$
+ }
+ if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(key)) {
+ return "org.eclipse.cdt.internal.core.index.EmptyIndexFragmentFormat"; //$NON-NLS-1$
+ }
+ if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(key)) {
+ return "0"; //$NON-NLS-1$
+ }
+ return null;
+ }
+
+ public void releaseReadLock() {}
+ public void resetCacheCounters() {}
+}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexProviderManagerTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexProviderManagerTest.java
index 0859add59cf..8d2df68f928 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexProviderManagerTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexProviderManagerTest.java
@@ -11,10 +11,6 @@
package org.eclipse.cdt.internal.index.tests;
import java.io.File;
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -55,6 +51,7 @@ import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.provider.IIndexFragmentProvider;
import org.eclipse.cdt.internal.core.index.provider.IndexProviderManager;
+import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
@@ -63,6 +60,7 @@ import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.osgi.service.resolver.VersionRange;
/**
* Example usage and test for IIndexProvider
@@ -76,6 +74,14 @@ public class IndexProviderManagerTest extends IndexTestBase {
final static Class DP5= Providers.Dummy5.class;
final static Class[] DPS= new Class[] {DP4, DP2, DP1, DP3, DP5};
+ /*
+ * Fictional compatibility ranges for testing
+ */
+ final static VersionRange VERSION_400= new VersionRange("36");
+ final static VersionRange VERSION_401= new VersionRange("[36,37]");
+ final static VersionRange VERSION_405= new VersionRange("[37,39]");
+ final static VersionRange VERSION_502= new VersionRange("[89,91]");
+
final CCorePlugin core= CCorePlugin.getDefault();
public IndexProviderManagerTest() {
@@ -86,6 +92,11 @@ public class IndexProviderManagerTest extends IndexTestBase {
return suite(IndexProviderManagerTest.class);
}
+ protected void tearDown() throws Exception {
+ IndexProviderManager ipm= ((PDOMManager)CCorePlugin.getIndexManager()).getIndexProviderManager();
+ ipm.reset(); ipm.startup();
+ }
+
public void testProvider_SimpleLifeCycle_200958() throws Exception {
for(int i=0; i<DPS.length; i++)
DPT.reset(DPS[i]);
@@ -170,6 +181,136 @@ public class IndexProviderManagerTest extends IndexTestBase {
}
}
+ public void testVersioning_IncompatibleIgnored() throws Exception {
+ IndexProviderManager ipm= ((PDOMManager)CCorePlugin.getIndexManager()).getIndexProviderManager();
+
+ ICProject cproject = null;
+ try {
+ cproject= CProjectHelper.createCCProject("IndexFactoryConfigurationUsageTest", IPDOMManager.ID_NO_INDEXER);
+ IProject project= cproject.getProject();
+
+
+ MockState mockState = new MockState(cproject);
+ mockState.setConfig(MockState.REL_V1_ID);
+
+ IIndexProvider provider1= new IIndexFragmentProvider() {
+ IIndexFragment[] fragments= new IIndexFragment[] {
+ new MockPDOM("contentID.contentA", "36"),
+ new MockPDOM("contentID.contentA", "37"),
+ new MockPDOM("contentID.foo", "90"),
+ new MockPDOM("contentID.bar", "91"),
+ new MockPDOM("contentID.baz", "89")
+ };
+ public IIndexFragment[] getIndexFragments(ICConfigurationDescription config) {
+ return fragments;
+ }
+ public boolean providesFor(ICProject project) throws CoreException {
+ return true;
+ }
+ };
+ IIndexProvider provider2= new IIndexFragmentProvider() {
+ IIndexFragment[] fragments= new IIndexFragment[] {
+ new MockPDOM("contentID.baz", "90"),
+ new MockPDOM("contentID.contentA", "38"),
+ };
+ public IIndexFragment[] getIndexFragments(ICConfigurationDescription config) {
+ return fragments;
+ }
+ public boolean providesFor(ICProject project) throws CoreException {
+ return true;
+ }
+ };
+
+ CCorePlugin.getIndexManager().joinIndexer(8000, NPM); // ensure IPM is called only once under test conditions
+ setExpectedNumberOfLoggedNonOKStatusObjects(3); // foo, bar and baz have no compatible fragments available
+
+ ipm.reset(VERSION_405); ipm.startup();
+ ipm.addIndexProvider(provider1); ipm.addIndexProvider(provider2);
+
+ IIndexFragment[] actual = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
+ assertEquals(1, actual.length);
+ assertFragmentPresent("contentID.contentA", "38", actual);
+ } finally {
+ if(cproject!=null) {
+ cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
+ }
+ }
+ }
+
+ public void testVersioning_NoCompatibleVersionsFound() throws Exception {
+ IndexProviderManager ipm= ((PDOMManager)CCorePlugin.getIndexManager()).getIndexProviderManager();
+
+ ICProject cproject = null;
+ try {
+ cproject= CProjectHelper.createCCProject("IndexFactoryConfigurationUsageTest", IPDOMManager.ID_NO_INDEXER);
+ IProject project= cproject.getProject();
+
+
+ MockState mockState = new MockState(cproject);
+ mockState.setConfig(MockState.REL_V1_ID);
+
+ IIndexProvider provider1= new IIndexFragmentProvider() {
+ IIndexFragment[] fragments= new IIndexFragment[] {
+ new MockPDOM("contentID.contentA", "36"),
+ new MockPDOM("contentID.contentA", "37"),
+ new MockPDOM("contentID.foo", "90"),
+ new MockPDOM("contentID.bar", "91"),
+ new MockPDOM("contentID.baz", "89")
+ };
+ public IIndexFragment[] getIndexFragments(ICConfigurationDescription config) {
+ return fragments;
+ }
+ public boolean providesFor(ICProject project) throws CoreException {
+ return true;
+ }
+ };
+ IIndexProvider provider2= new IIndexFragmentProvider() {
+ IIndexFragment[] fragments= new IIndexFragment[] {
+ new MockPDOM("contentID.contentA", "41"),
+ };
+ public IIndexFragment[] getIndexFragments(ICConfigurationDescription config) {
+ return fragments;
+ }
+ public boolean providesFor(ICProject project) throws CoreException {
+ return true;
+ }
+ };
+
+ CCorePlugin.getIndexManager().joinIndexer(8000, NPM); // ensure IPM is called only once under test conditions
+ setExpectedNumberOfLoggedNonOKStatusObjects(1); // contentA has no compatible fragments available
+
+ ipm.reset(VERSION_502); ipm.startup();
+ ipm.addIndexProvider(provider1); ipm.addIndexProvider(provider2);
+
+ IIndexFragment[] actual = ipm.getProvidedIndexFragments(mockState.getCurrentConfig());
+ assertEquals(3, actual.length);
+ assertFragmentPresent("contentID.foo", "90", actual);
+ assertFragmentPresent("contentID.bar", "91", actual);
+ assertFragmentPresent("contentID.baz", "89", actual);
+ } finally {
+ if(cproject!=null) {
+ cproject.getProject().delete(IResource.FORCE | IResource.ALWAYS_DELETE_PROJECT_CONTENT, new NullProgressMonitor());
+ }
+ }
+ }
+
+ private void assertFragmentPresent(String id, String version, IIndexFragment[] fragments) throws Exception {
+ for(int i=0; i<fragments.length; i++) {
+ IIndexFragment candidate= fragments[i];
+ String cid= null, csver= null;
+ try {
+ candidate.acquireReadLock();
+ cid= candidate.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID);
+ csver= candidate.getProperty(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION);
+ } finally {
+ candidate.releaseReadLock();
+ }
+ if(id.equals(cid) && version.equals(csver))
+ return;
+ }
+ fail("Fragment matching (id="+id+",version="+version+") was not present");
+ }
+
public void testIndexFactoryConfigurationUsage() throws Exception {
IIndex index;
@@ -372,10 +513,9 @@ class MockStateIndexProvider implements IIndexProvider {
}
class MockStateIndexFragmentProvider extends MockStateIndexProvider implements IIndexFragmentProvider {
- IIndexFragment[] fragments;
- int[] mcounts;
- boolean invert;
-
+ private boolean invert;
+ final IIndexFragment[] fragments;
+
public void invert() {
invert = !invert;
}
@@ -384,9 +524,8 @@ class MockStateIndexFragmentProvider extends MockStateIndexProvider implements I
super(cproject);
fragments = new IIndexFragment[MockState.states.size()];
- mcounts = new int[MockState.states.size()];
for(int i=0; i<MockState.states.size(); i++) {
- fragments[i] = createMockFragment(mcounts, i);
+ fragments[i] = new MockPDOM("mock.test.index."+System.identityHashCode(this)+"."+i, ""+PDOM.CURRENT_VERSION);
}
}
@@ -401,22 +540,6 @@ class MockStateIndexFragmentProvider extends MockStateIndexProvider implements I
return new IIndexFragment[] {fragments[index]};
}
}
-
- public IIndexFragment createMockFragment(final int[] mcounts, final int index) {
- return (IIndexFragment) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {IIndexFragment.class}, new InvocationHandler(){
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Object result = null;
- if(method.getReturnType().isArray()) {
- result = Array.newInstance(method.getReturnType().getComponentType(), 0);
- }
- if(method.getName().equals("toString")) {
- return "[Mock index fragment #"+index+"]";
- }
- mcounts[index]++;
- return result;
- }
- });
- }
}
class MockConfig implements ICConfigurationDescription {
@@ -589,3 +712,29 @@ class MockState {
}
}
+class MockPDOM extends EmptyIndexFragment {
+ String id;
+ String version;
+
+ MockPDOM(String id, String version) {
+ this.id= id;
+ this.version= version;
+ }
+
+ public String getProperty(String propertyName) throws CoreException {
+ if(IIndexFragment.PROPERTY_FRAGMENT_ID.equals(propertyName)) {
+ return id;
+ }
+ if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName)) {
+ return PDOM.FRAGMENT_PROPERTY_VALUE_FORMAT_ID;
+ }
+ if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(propertyName)) {
+ return version;
+ }
+ return null;
+ }
+
+ public String toString() {
+ return "[Mock index fragment "+id+"."+System.identityHashCode(this)+"]";
+ }
+} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
index e33a81980a3..c79d3bf8407 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/IIndexFragment.java
@@ -52,16 +52,33 @@ public interface IIndexFragment {
final int FIND_ALL_OCCURENCES = IIndex.FIND_ALL_OCCURENCES;
/**
- * Property key constant for the fragment ID. The fragment ID should uniquely identify the fragments usage within
+ * Property key for the fragment ID. The fragment ID should uniquely identify the fragments usage within
* a logical index.
+ * @since 4.0
*/
public static final String PROPERTY_FRAGMENT_ID= "org.eclipse.cdt.internal.core.index.fragment.id"; //$NON-NLS-1$
+
+ /**
+ * Property key for the fragment format ID. The fragment format ID should uniquely identify a format of an index fragment
+ * up to version information. That is, as a particular format changes version its ID should remain the same.
+ * @since 4.0.1
+ */
+ public static final String PROPERTY_FRAGMENT_FORMAT_ID= "org.eclipse.cdt.internal.core.index.fragment.format.id"; //$NON-NLS-1$
+
+ /**
+ * Property key for the fragment format's version. Version numbers belonging to the same format (identified by format ID) should be
+ * comparable with each other. The version scheme exposed should be compatible with the OSGi framework's
+ * version scheme - i.e. it should be successfully parsed by org.osgi.framework.Version.parseVersion(String). A null value
+ * for this property is interpreted as Version(0.0.0)
+ * @since 4.0.1
+ */
+ public static final String PROPERTY_FRAGMENT_FORMAT_VERSION= "org.eclipse.cdt.internal.core.index.fragment.format.version"; //$NON-NLS-1$
/**
* Returns the file for the given location. May return <code>null</code>, if no such file exists.
- * This method may only return files that are actually managed by this fragement.
+ * This method may only return files that are actually managed by this fragment.
* @param location the IIndexFileLocation representing the location of the file
- * @return the file for the location
+ * @return the file for the location, or <code>null</code> if the file is not present in the index
* @throws CoreException
*/
IIndexFragmentFile getFile(IIndexFileLocation location) throws CoreException;
@@ -167,11 +184,17 @@ public interface IIndexFragment {
/**
* Read the named property in this fragment. All fragments are expected to return a non-null value for
- * <pre>PROPERTY_FRAGMENT_ID</pre>
+ * <ul>
+ * <li>PROPERTY_FRAGMENT_ID</li>
+ * <li>PROPERTY_FRAGMENT_FORMAT_ID</li>
+ * <li>PROPERTY_FRAGMENT_FORMAT_VERSION</li>
+ * </ul>
* @param key a case-sensitive identifier for a property, or null
* @return the value associated with the key, or null if either no such property is set, or the specified key was null
* @throws CoreException
* @see IIndexFragment#PROPERTY_FRAGMENT_ID
+ * @see IIndexFragment#PROPERTY_FRAGMENT_FORMAT_ID
+ * @see IIndexFragment#PROPERTY_FRAGMENT_FORMAT_VERSION
*/
public String getProperty(String propertyName) throws CoreException;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/IndexProviderManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/IndexProviderManager.java
index aadc4ed83eb..0a134b6dc9e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/IndexProviderManager.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/IndexProviderManager.java
@@ -13,11 +13,12 @@ package org.eclipse.cdt.internal.core.index.provider;
import java.text.MessageFormat;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.provider.IIndexProvider;
@@ -28,31 +29,70 @@ import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICElementDelta;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IElementChangedListener;
+import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
+import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
-
+import org.eclipse.core.runtime.Status;
+import org.eclipse.osgi.service.resolver.VersionRange;
+import org.osgi.framework.Version;
/**
* The IndexProviderManager is responsible for maintaining the set of index
* fragments contributed via the CIndex extension point.
* <p>
* It is an internal class, and is public only for testing purposes.
+ * @since 4.0
+ */
+/*
+ * For bug 196338, the role of this class was extended. It now has responsibility to
+ * look at the pool of fragments available depending on their IDs, and select the most appropriate.
+ * The following rules are applied
+ * (i) If its not compatible, don't use it
+ * (ii) If multiple are compatible, pick the latest
+ *
+ * A warning is logged if a fragment is contributed which is incompatible, and for which there is
+ * no compatible equivalent.
*/
public final class IndexProviderManager implements IElementChangedListener {
- public static final String READ_ONLY_PDOM_PROVIDER= "ReadOnlyPDOMProvider"; //$NON-NLS-1$
- private IIndexFragmentProvider[] allProviders= {};
- private Map provisionMap= new HashMap();
+ private static final String ELEMENT_RO_PDOMPROVIDER= "ReadOnlyPDOMProvider"; //$NON-NLS-1$
+ private static final String ATTRIBUTE_CLASS = "class"; //$NON-NLS-1$
+
+ private IIndexFragmentProvider[] allProviders;
+ private Map/*<List,Boolean>*/ provisionMap;
+ private Set/*<String>*/ compatibleFragmentUnavailable;
+ private VersionRange pdomVersionRange;
public IndexProviderManager() {
+ reset();
+ }
+
+ /**
+ * <b>Note: This method should not be called by clients for purposes other than testing</b>
+ */
+ public void reset() {
+ reset(new VersionRange("["+PDOM.MIN_SUPPORTED_VERSION+','+PDOM.CURRENT_VERSION+']')); //$NON-NLS-1$
}
+ /**
+ * <b>Note: This method should not be called by clients for purposes other than testing</b>
+ * @param pdomVersionRange
+ */
+ public void reset(VersionRange pdomVersionRange) {
+ this.allProviders= new IIndexFragmentProvider[0];
+ this.provisionMap= new HashMap();
+ this.pdomVersionRange= pdomVersionRange;
+ this.compatibleFragmentUnavailable= new HashSet();
+ }
+
public void startup() {
List providers = new ArrayList();
IExtensionRegistry registry = Platform.getExtensionRegistry();
@@ -63,8 +103,9 @@ public final class IndexProviderManager implements IElementChangedListener {
try {
IConfigurationElement[] ce = extension.getConfigurationElements();
for(int j=0; j<ce.length; j++) {
- if(ce[j].getName().equals(READ_ONLY_PDOM_PROVIDER)) {
- IIndexProvider provider = (IIndexProvider) ce[j].createExecutableExtension("class"); //$NON-NLS-1$
+ if(ce[j].getName().equals(ELEMENT_RO_PDOMPROVIDER)) {
+ IIndexProvider provider = (IIndexProvider) ce[j].createExecutableExtension(ATTRIBUTE_CLASS);
+
if(provider instanceof IReadOnlyPDOMProvider) {
provider = new ReadOnlyPDOMProviderBridge((IReadOnlyPDOMProvider)provider);
providers.add(provider);
@@ -90,29 +131,126 @@ public final class IndexProviderManager implements IElementChangedListener {
* registered IIndexProvider objects for the specified project, and
* for the current state of the project.
* Order in the array is not significant.
- * @param project
+ * @param config
* @return the array of IIndexFragment objects for the current state
*/
public IIndexFragment[] getProvidedIndexFragments(ICConfigurationDescription config) throws CoreException {
- List preResult = new ArrayList();
+ Map id2fragment = new HashMap();
IProject project= config.getProjectDescription().getProject();
for(int i=0; i<allProviders.length; i++) {
try {
if(providesForProject(allProviders[i], project)) {
- preResult.addAll(Arrays.asList(allProviders[i].getIndexFragments(config)));
+ IIndexFragment[] fragments= allProviders[i].getIndexFragments(config);
+ for(int j=0; j<fragments.length; j++) {
+ try {
+ processCandidate(id2fragment, fragments[j]);
+ } catch(InterruptedException ie) {
+ CCorePlugin.log(ie); // continue with next candidate
+ } catch(CoreException ce) {
+ CCorePlugin.log(ce); // continue with next candidate
+ }
+ }
}
} catch(CoreException ce) {
- CCorePlugin.log(ce);
+ CCorePlugin.log(ce); // move to next provider
+ }
+ }
+
+ // Make log entries for any fragments which have no compatible equivalents
+ List preresult= new ArrayList();
+ for(Iterator i=id2fragment.entrySet().iterator(); i.hasNext(); ) {
+ Map.Entry entry= (Map.Entry) i.next();
+ if(entry.getValue()==null) {
+ String key= (String) entry.getKey();
+ if(!compatibleFragmentUnavailable.contains(key)) {
+ String msg= MessageFormat.format(
+ Messages.IndexProviderManager_NoCompatibleFragmentsAvailable,
+ new Object[]{key}
+ );
+ IStatus status= new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID, IStatus.WARNING, msg, null);
+ CCorePlugin.log(status);
+ compatibleFragmentUnavailable.add(key);
+ }
+ } else {
+ preresult.add(entry.getValue());
}
}
+ return (IIndexFragment[]) preresult.toArray(new IIndexFragment[preresult.size()]);
+ }
+
+ /**
+ * Returns the version range supported by the format identified by the specified formatID.
+ * @param formatID
+ */
+ private VersionRange getCurrentlySupportedVersionRangeForFormat(String formatID) {
+ /*
+ * TODO - at the point we support alternate IIndexFragment implementations, this method will need
+ * to be altered to lookup version ranges for the contributed format via an extension point.
+ */
+ if(!PDOM.FRAGMENT_PROPERTY_VALUE_FORMAT_ID.equals(formatID)) {
+ throw new IllegalArgumentException("Non-PDOM formats are currently unsupported"); //$NON-NLS-1$
+ }
+ return pdomVersionRange;
+ }
+
+ /**
+ * Examines the candidate fragment, adding it to the map (using its fragment id as key) if
+ * it compatible with the current run-time, and it is better than any existing fragments for
+ * the same fragment id.
+ * @param id2fragment
+ * @param candidate
+ */
+ private void processCandidate(Map id2fragment, IIndexFragment candidate) throws InterruptedException, CoreException {
+ String cid= null, csver= null, cformatID= null;
+ try {
+ candidate.acquireReadLock();
+ cid= candidate.getProperty(IIndexFragment.PROPERTY_FRAGMENT_ID);
+ csver= candidate.getProperty(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION);
+ cformatID= candidate.getProperty(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID);
+ } finally {
+ candidate.releaseReadLock();
+ }
+ assert cid!=null && csver!=null && cformatID!=null;
- IIndexFragment[] result = (IIndexFragment[]) preResult.toArray(new IIndexFragment[preResult.size()]);
- return result;
+ Version cver= Version.parseVersion(csver); // illegal argument exception
+ IIndexFragment existing= (IIndexFragment) id2fragment.get(cid);
+
+ if(getCurrentlySupportedVersionRangeForFormat(cformatID).isIncluded(cver)) {
+ if(existing != null) {
+ String esver= null, eformatID= null;
+ try {
+ existing.acquireReadLock();
+ esver= existing.getProperty(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION);
+ eformatID= existing.getProperty(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID);
+ } finally {
+ existing.releaseReadLock();
+ }
+
+ if(eformatID.equals(cformatID)) {
+ Version ever= Version.parseVersion(esver); // illegal argument exception
+ if(ever.compareTo(cver) < 0) {
+ id2fragment.put(cid, candidate);
+ }
+ } else {
+ /*
+ * In future we could allow users to specify
+ * how format (i.e. PDOM -> custom IIndexFragment implementation)
+ * changes are coped with.
+ */
+ }
+ } else {
+ id2fragment.put(cid, candidate);
+ }
+ } else {
+ if(existing==null) {
+ id2fragment.put(cid, null); // signifies candidate is unusable
+ }
+ }
}
/**
- * This is only public for test purposes
+ * <b>Note: This method should not be called for purposes other than testing</b>
* @param provider
*/
public void addIndexProvider(IIndexProvider provider) {
@@ -131,6 +269,20 @@ public final class IndexProviderManager implements IElementChangedListener {
allProviders = newAllProviders;
}
+ /**
+ * Removes the specified provider by object identity
+ * <b>Note: This method should not be called for purposes other than testing</b>
+ * @param provider
+ */
+ public void removeIndexProvider(IIndexProvider provider) {
+ ArrayUtil.remove(allProviders, provider);
+ if(allProviders[allProviders.length-1]==null) {
+ IIndexFragmentProvider[] newAllProviders = new IIndexFragmentProvider[allProviders.length-1];
+ System.arraycopy(allProviders, 0, newAllProviders, 0, allProviders.length-1);
+ allProviders= newAllProviders;
+ }
+ }
+
private boolean providesForProject(IIndexProvider provider, IProject project) {
List key = new ArrayList();
key.add(provider);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/Messages.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/Messages.java
index fe1cf9091f3..f448a387f74 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/Messages.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/Messages.java
@@ -15,6 +15,7 @@ import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.cdt.internal.core.index.provider.messages"; //$NON-NLS-1$
public static String IndexProviderManager_0;
+ public static String IndexProviderManager_NoCompatibleFragmentsAvailable;
public static String OfflinePDOMProviderBridge_UnsupportedUsage;
public static String PDOMCache_VersionTooOld;
static {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/PDOMCache.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/PDOMCache.java
index 382a7a0821b..7b56eef267c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/PDOMCache.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/PDOMCache.java
@@ -12,11 +12,8 @@
package org.eclipse.cdt.internal.core.index.provider;
import java.io.File;
-import java.text.MessageFormat;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
-import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
@@ -29,17 +26,15 @@ import org.eclipse.core.runtime.IPath;
* Internal singleton map maintained for non-project PDOM objects
*/
class PDOMCache {
- private Map/*<File, PDOM>*/ path2pdom; // gives the pdom for a particular path
- private Set/*<File>*/ versionMismatch;
-
+ private Map/*<File, PDOM>*/ path2pdom; // gives the PDOM for a particular path
+
private static PDOMCache singleton;
private static Object singletonMutex = new Object();
private PDOMCache() {
this.path2pdom = new HashMap();
- this.versionMismatch = new HashSet();
}
-
+
/**
* Returns the instance of the cache
* @return
@@ -54,48 +49,30 @@ class PDOMCache {
}
/**
- * Returns the mapped pdom for the path specified, if such a pdom is not already known about
+ * Returns the mapped PDOM for the path specified, if such a pdom is not already known about
* then one is created using the location converter specified.
* @param path
* @param converter
- * @return a pdom instance or null if the pdom version was too old
+ * @return a PDOM instance or null if the PDOM version was too old
*/
public PDOM getPDOM(IPath path, IIndexLocationConverter converter) {
PDOM result= null;
File file = path.toFile();
- if(!versionMismatch.contains(file)) {
- synchronized(path2pdom) {
- if(path2pdom.containsKey(file)) {
- result = (PDOM) path2pdom.get(file);
- }
- if(result==null) {
- try {
- result = new PDOM(file, converter, LanguageManager.getInstance().getPDOMLinkageFactoryMappings());
-
- result.acquireReadLock();
- try {
- if(!result.isSupportedVersion()) {
- versionMismatch.add(file);
- String msg= MessageFormat.format(Messages.PDOMCache_VersionTooOld, new Object[] {file});
- CCorePlugin.log(msg);
- return null;
- } else {
- path2pdom.put(file, result);
- }
- } finally {
- result.releaseReadLock();
- }
- } catch(CoreException ce) {
- CCorePlugin.log(ce);
- } catch(InterruptedException ie) {
- CCorePlugin.log(ie);
- }
+ synchronized(path2pdom) {
+ if(path2pdom.containsKey(file)) {
+ result = (PDOM) path2pdom.get(file);
+ }
+ if(result==null) {
+ try {
+ result = new PDOM(file, converter, LanguageManager.getInstance().getPDOMLinkageFactoryMappings());
+ path2pdom.put(file, result);
+ } catch(CoreException ce) {
+ CCorePlugin.log(ce);
}
-
}
}
return result;
}
-}
+} \ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/messages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/messages.properties
index a0e7f83d6c8..87063621795 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/messages.properties
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/provider/messages.properties
@@ -11,3 +11,4 @@
IndexProviderManager_0=Ignoring unrecognized implementation of IIndexProvider contributed by {0}
OfflinePDOMProviderBridge_UnsupportedUsage=Unsupported usage of IOfflinePDOMProvider
PDOMCache_VersionTooOld=External index (PDOM) version is not supported: {0}
+IndexProviderManager_NoCompatibleFragmentsAvailable=No compatible index fragment found for fragment id: {0}
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 47fe62dd09c..65df7b909e0 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
@@ -73,47 +73,60 @@ import org.eclipse.core.runtime.Status;
public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
protected Database db;
+ /**
+ * Identifier for PDOM format
+ * @see IIndexFragment#PROPERTY_FRAGMENT_FORMAT_ID
+ */
+ public static final String FRAGMENT_PROPERTY_VALUE_FORMAT_ID= "org.eclipse.cdt.internal.core.pdom.PDOM"; //$NON-NLS-1$
+
public static final int CURRENT_VERSION = 37;
public static final int MIN_SUPPORTED_VERSION= 36;
public static final int MIN_VERSION_TO_WRITE_NESTED_BINDINGS_INDEX= 37; // to be removed in 4.1
- // 0 - the beginning of it all
- // 1 - first change to kick off upgrades
- // 2 - added file inclusions
- // 3 - added macros and change string implementation
- // 4 - added parameters in C++
- // 5 - added types and restructured nodes a bit
- // 6 - function style macros.
- // 7 - class key
- // 8 - enumerators
- // 9 - base classes
- // 10 - typedefs, types on C++ variables
- // 11 - changed how members work
- // 12 - one more change for members (is-a list -> has-a list)
- // 13 - CV-qualifiers, storage class specifiers, function/method annotations
- // 14 - added timestamps for files (bug 149571)
- // 15 - fixed offsets for pointer types and qualifier types and PDOMCPPVariable (bug 160540).
- // 16 - have PDOMCPPField store type information, and PDOMCPPNamespaceAlias store what it is aliasing
- // 17 - use single linked list for names in file, adds a link to enclosing definition name.
- // 18 - distinction between c-unions and c-structs.
- // 19 - alter representation of paths in the pdom (162172)
- // 20 - add pointer to member types, array types, return types for functions
- // 21 - change representation of paths in the pdom (167549)
- // 22 - fix inheritance relations (167396)
- // 23 - types on c-variables, return types on c-functions
- // 24 - file local scopes (161216)
- // 25 - change ordering of bindings (175275)
- // 26 - add properties storage
- // 27 - templates: classes, functions, limited nesting support, only template type parameters
- // 28 - templates: class instance/specialization base classes
- // 29 - includes: fixed modeling of unresolved includes (180159)
- // 30 - templates: method/constructor templates, typedef specializations
- // 31 - macros: added file locations
- // 32 - support stand-alone function types (181936)
- // 33 - templates: constructor instances
- // 34 - fix for base classes represented by qualified names (183843)
- // 35 - add scanner configuration hash-code (62366)
- // 36 - changed chunk size back to 4K (184892)
- // 37 - added index for nested bindings (189811), compatible with version 36.
+
+ /*
+ * PDOM internal format history
+ *
+ * #x# = the version was used in an official release
+ *
+ * 0 - the beginning of it all
+ * 1 - first change to kick off upgrades
+ * 2 - added file inclusions
+ * 3 - added macros and change string implementation
+ * 4 - added parameters in C++
+ * 5 - added types and restructured nodes a bit
+ * 6 - function style macros
+ * # 7#- class key - <<CDT 3.1>>
+ * 8 - enumerators
+ * 9 - base classes
+ * 10 - typedefs, types on C++ variables
+ * #11#- changed how members work - <<CDT 3.1.1>>, <<CDT 3.1.2>>
+ * 12 - one more change for members (is-a list -> has-a list)
+ * 13 - CV-qualifiers, storage class specifiers, function/method annotations
+ * 14 - added timestamps for files (bug 149571)
+ * 15 - fixed offsets for pointer types and qualifier types and PDOMCPPVariable (bug 160540).
+ * 16 - have PDOMCPPField store type information, and PDOMCPPNamespaceAlias store what it is aliasing
+ * 17 - use single linked list for names in file, adds a link to enclosing definition name.
+ * 18 - distinction between c-unions and c-structs.
+ * 19 - alter representation of paths in the pdom (162172)
+ * 20 - add pointer to member types, array types, return types for functions
+ * 21 - change representation of paths in the pdom (167549)
+ * 22 - fix inheritance relations (167396)
+ * 23 - types on c-variables, return types on c-functions
+ * 24 - file local scopes (161216)
+ * 25 - change ordering of bindings (175275)
+ * 26 - add properties storage
+ * 27 - templates: classes, functions, limited nesting support, only template type parameters
+ * 28 - templates: class instance/specialization base classes
+ * 29 - includes: fixed modeling of unresolved includes (180159)
+ * 30 - templates: method/constructor templates, typedef specializations
+ * 31 - macros: added file locations
+ * 32 - support stand-alone function types (181936)
+ * 33 - templates: constructor instances
+ * 34 - fix for base classes represented by qualified names (183843)
+ * 35 - add scanner configuration hash-code (62366)
+ * #36#- changed chunk size back to 4K (184892) - <<CDT 4.0>>
+ * #37#- added index for nested bindings (189811), compatible with version 36 - <<CDT 4.0.1>>
+ */
public static final int LINKAGES = Database.DATA_AREA;
public static final int FILE_INDEX = Database.DATA_AREA + 4;
@@ -760,6 +773,12 @@ public class PDOM extends PlatformObject implements IIndexFragment, IPDOM {
}
public String getProperty(String propertyName) throws CoreException {
+ if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName)) {
+ return FRAGMENT_PROPERTY_VALUE_FORMAT_ID;
+ }
+ if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(propertyName)) {
+ return ""+db.getVersion(); //$NON-NLS-1$
+ }
return new DBProperties(db, PROPERTIES).getProperty(propertyName);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
index 158c70591d2..508bde45d3b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/WritablePDOM.java
@@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.index.IIndexFileLocation;
import org.eclipse.cdt.core.index.IIndexLocationConverter;
+import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentFile;
import org.eclipse.cdt.internal.core.index.IWritableIndexFragment;
import org.eclipse.cdt.internal.core.index.IWritableIndex.IncludeInformation;
@@ -88,11 +89,18 @@ public class WritablePDOM extends PDOM implements IWritableIndexFragment {
return result;
}
+ /*
+ * (non-Javadoc)
+ * @see org.eclipse.cdt.internal.core.index.IWritableIndexFragment#setProperty(java.lang.String, java.lang.String)
+ */
public void setProperty(String propertyName, String value) throws CoreException {
+ if(IIndexFragment.PROPERTY_FRAGMENT_FORMAT_ID.equals(propertyName)
+ || IIndexFragment.PROPERTY_FRAGMENT_FORMAT_VERSION.equals(propertyName)) {
+ throw new IllegalArgumentException("Property "+value+" may not be written to"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
new DBProperties(db, PROPERTIES).setProperty(propertyName, value);
}
-
/**
* Use the specified location converter to update each internal representation of a file location.
* The file index is rebuilt with the new representations. Individual PDOMFile records are unmoved so
diff --git a/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning.html b/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning.html
new file mode 100644
index 00000000000..dc319b7243c
--- /dev/null
+++ b/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning.html
@@ -0,0 +1,350 @@
+<html xmlns:v="urn:schemas-microsoft-com:vml"
+xmlns:o="urn:schemas-microsoft-com:office:office"
+xmlns:w="urn:schemas-microsoft-com:office:word"
+xmlns="http://www.w3.org/TR/REC-html40">
+
+<head>
+<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
+<meta name=ProgId content=Word.Document>
+<meta name=Generator content="Microsoft Word 10">
+<meta name=Originator content="Microsoft Word 10">
+<link rel=File-List href="prebuiltVersioning_files/filelist.xml">
+<link rel=Edit-Time-Data href="prebuiltVersioning_files/editdata.mso">
+<!--[if !mso]>
+<style>
+v\:* {behavior:url(#default#VML);}
+o\:* {behavior:url(#default#VML);}
+w\:* {behavior:url(#default#VML);}
+.shape {behavior:url(#default#VML);}
+</style>
+<![endif]-->
+<title>Versioning pre-built indexes</title>
+<!--[if gte mso 9]><xml>
+ <w:WordDocument>
+ <w:Zoom>80</w:Zoom>
+ <w:SpellingState>Clean</w:SpellingState>
+ <w:GrammarState>Clean</w:GrammarState>
+ <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
+ </w:WordDocument>
+</xml><![endif]-->
+<style>
+<!--
+ /* Style Definitions */
+ p.MsoNormal, li.MsoNormal, div.MsoNormal
+ {mso-style-parent:"";
+ margin:0cm;
+ margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:12.0pt;
+ font-family:"Times New Roman";
+ mso-fareast-font-family:"Times New Roman";}
+h1
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0cm;
+ margin-bottom:3.0pt;
+ margin-left:0cm;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:1;
+ font-size:16.0pt;
+ font-family:Arial;
+ mso-font-kerning:16.0pt;}
+h2
+ {mso-style-next:Normal;
+ margin-top:12.0pt;
+ margin-right:0cm;
+ margin-bottom:3.0pt;
+ margin-left:0cm;
+ mso-pagination:widow-orphan;
+ page-break-after:avoid;
+ mso-outline-level:2;
+ font-size:14.0pt;
+ font-family:Arial;
+ font-style:italic;}
+a:link, span.MsoHyperlink
+ {color:blue;
+ text-decoration:underline;
+ text-underline:single;}
+a:visited, span.MsoHyperlinkFollowed
+ {color:#606420;
+ text-decoration:underline;
+ text-underline:single;}
+span.SpellE
+ {mso-style-name:"";
+ mso-spl-e:yes;}
+span.GramE
+ {mso-style-name:"";
+ mso-gram-e:yes;}
+@page Section1
+ {size:612.0pt 792.0pt;
+ margin:72.0pt 90.0pt 72.0pt 90.0pt;
+ mso-header-margin:35.4pt;
+ mso-footer-margin:35.4pt;
+ mso-paper-source:0;}
+div.Section1
+ {page:Section1;}
+-->
+</style>
+<!--[if gte mso 10]>
+<style>
+ /* Style Definitions */
+ table.MsoNormalTable
+ {mso-style-name:"Table Normal";
+ mso-tstyle-rowband-size:0;
+ mso-tstyle-colband-size:0;
+ mso-style-noshow:yes;
+ mso-style-parent:"";
+ mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
+ mso-para-margin:0cm;
+ mso-para-margin-bottom:.0001pt;
+ mso-pagination:widow-orphan;
+ font-size:10.0pt;
+ font-family:"Times New Roman";}
+</style>
+<![endif]--><!--[if gte mso 9]><xml>
+ <o:shapedefaults v:ext="edit" spidmax="3074"/>
+</xml><![endif]--><!--[if gte mso 9]><xml>
+ <o:shapelayout v:ext="edit">
+ <o:idmap v:ext="edit" data="1"/>
+ </o:shapelayout></xml><![endif]-->
+</head>
+
+<body lang=EN-GB link=blue vlink="#606420" style='tab-interval:36.0pt'>
+
+<div class=Section1>
+
+<h1 align=center style='text-align:center'>Versioning of pre-built indexes</h1>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal style='text-align:justify'>In CDT 4.0.1 support for
+versioning of pre-built indexes was added. This means that if you release
+pre-built indexes for the same content (for example, the same SDK version), but
+they were built with different versions of CDT, then a suitable version will
+now be used automatically. The previous behaviour assumed only one format
+version of any particular content would be provided via the <span class=SpellE>CIndex</span>
+extension point.</p>
+
+<p class=MsoNormal style='text-align:justify'>&nbsp;</p>
+
+<p class=MsoNormal style='text-align:justify'>It is important to distinguish
+between two versions: the content version and the index format version. A
+content version refers to the version of the source code being indexed
+independent of how it is represented in the index e.g. SDK v1.0 and SDK v1.2.
+The index format version is the version of the internal representation of the
+index. This document is about coping with the latter.</p>
+
+<p class=MsoNormal style='text-align:justify'>&nbsp;</p>
+
+<p class=MsoNormal style='text-align:justify'>Our versioning policy for index
+formats is that they should be compatible within major (yearly) release
+versions. That is if you build an index using CDT 4.0.X it should work with CDT
+4.0.Y. This policy should mean that ISVs do not need to worry about index
+format versioning, but this page describes how to handle it should it be
+necessary (for example <span class=SpellE>bugzilla</span> 189811).Each
+pre-built index carries a string ID which identifies it uniquely within a
+logical index - i.e. it identifies the content (<span class=SpellE>e.g</span> <span
+class=SpellE>MySDK</span> v1.2). When multiple pre-built indexes are provided
+with the same ID, the particular one for use is disambiguated automatically by
+CDT which chooses the most recent compatible version.</p>
+
+<h2><span style='font-style:normal;mso-bidi-font-style:italic'>Compatibility
+Table<o:p></o:p></span></h2>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal style='text-align:justify'>This table shows the
+compatibility of pre-built indexes built with one version of CDT and used with
+another. “Built With” is the vertical axis.</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<table class=MsoNormalTable border=0 cellspacing=0 cellpadding=0 width=516
+ style='width:387.0pt;margin-left:23.4pt;border-collapse:collapse;mso-padding-alt:
+ 0cm 0cm 0cm 0cm'>
+ <tr style='mso-yfti-irow:0'>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal><b><span style='font-size:8.0pt'>Built With \ Use With</span></b></p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>CDT 4.0</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>CDT 4.0.1</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>CDT Next**</p>
+ </td>
+ <td width=44 valign=top style='width:32.8pt;border:none;border-bottom:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal><b>&nbsp;</b></p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:1'>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>CDT 4.0</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>Yes*</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>Yes*</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>No</p>
+ </td>
+ <td width=44 valign=top style='width:32.8pt;border:none;border-bottom:solid white 2.25pt;
+ background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>&nbsp;</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:2'>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>CDT 4.0.1</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>Yes*</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>Yes</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>No</p>
+ </td>
+ <td width=44 valign=top style='width:32.8pt;border:none;border-bottom:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>&nbsp;</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:3'>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>CDT Next**</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>No</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>No</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border-top:none;border-left:
+ none;border-bottom:solid white 2.25pt;border-right:solid white 2.25pt;
+ background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>Yes</p>
+ </td>
+ <td width=44 valign=top style='width:32.8pt;border:none;border-bottom:solid white 2.25pt;
+ background:#F2F2F2;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>&nbsp;</p>
+ </td>
+ </tr>
+ <tr style='mso-yfti-irow:4;mso-yfti-lastrow:yes'>
+ <td width=118 valign=top style='width:88.55pt;border:none;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>&nbsp;</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border:none;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>&nbsp;</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border:none;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>&nbsp;</p>
+ </td>
+ <td width=118 valign=top style='width:88.55pt;border:none;border-right:solid white 2.25pt;
+ background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>&nbsp;</p>
+ </td>
+ <td width=44 valign=top style='width:32.8pt;background:#CCCCCC;padding:0cm 5.4pt 0cm 5.4pt'>
+ <p class=MsoNormal>&nbsp;</p>
+ </td>
+ </tr>
+</table>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal style='text-align:justify'>Note that even though in the PDOM
+format has its own internal versioning scheme, consumers of official CDT
+releases need only be aware of compatibility constraints between these
+releases.</p>
+
+<p class=MsoNormal>&nbsp;</p>
+
+<p class=MsoNormal><span style='font-size:8.0pt'>* <span class=GramE>with</span>
+performance issues in very large projects. See <a
+href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=189811">https://bugs.eclipse.org/bugs/show_bug.cgi?id=189811</a></span></p>
+
+<p class=MsoNormal><span class=GramE><span style='font-size:8.0pt'>** represents
+the next major release of CDT.</span></span><span style='font-size:8.0pt'> It
+is assumed significant changes to the PDOM database will occur.<o:p></o:p></span></p>
+
+<p class=MsoNormal><span style='font-size:8.0pt'><o:p>&nbsp;</o:p></span></p>
+
+<h2><span style='font-style:normal;mso-bidi-font-style:italic'>Example scenario<o:p></o:p></span></h2>
+
+<p class=MsoNormal><o:p>&nbsp;</o:p></p>
+
+<span style='font-size:12.0pt;font-family:"Times New Roman";mso-fareast-font-family:
+"Times New Roman";mso-ansi-language:EN-GB;mso-fareast-language:EN-GB;
+mso-bidi-language:AR-SA'><br clear=all style='page-break-before:always'>
+</span>
+
+<p class=MsoNormal align=center style='text-align:center'>&nbsp;</p>
+
+<p class=MsoNormal align=center style='text-align:center'><img border=0
+width=421 height=653 id="_x0000_i1025"
+src="prebuiltVersioning_files/image001.jpg"></p>
+
+<p class=MsoNormal align=center style='text-align:center'>&nbsp;</p>
+
+<p class=MsoNormal style='text-align:justify'>The figure above shows an example
+scenario where pre-built indexes are contributed by multiple <span class=GramE>plug-ins</span>.
+The same content is contributed in multiple index format versions. The versions
+selected for use by each version of CDT are highlighted in <span class=SpellE>gray</span>.</p>
+
+<p class=MsoNormal style='text-align:justify'><o:p>&nbsp;</o:p></p>
+
+<p class=MsoNormal style='text-align:justify'><o:p>&nbsp;</o:p></p>
+
+<p class=MsoNormal style='text-align:justify'><o:p>&nbsp;</o:p></p>
+
+<p class=MsoNormal><span style='font-size:10.0pt'>Versioning <span
+class=SpellE>Bugzilla</span>: <a
+href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=196338">https://bugs.eclipse.org/bugs/show_bug.cgi?id=196338</a></span></p>
+
+<p class=MsoNormal style='text-align:justify'><o:p>&nbsp;</o:p></p>
+
+</div>
+
+</body>
+
+</html>
diff --git a/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning_files/image001.jpg b/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning_files/image001.jpg
new file mode 100644
index 00000000000..0acc405f981
--- /dev/null
+++ b/doc/org.eclipse.cdt.doc.isv/guide/dom/index/prebuiltVersioning_files/image001.jpg
Binary files differ
diff --git a/doc/org.eclipse.cdt.doc.isv/topics_Guide.xml b/doc/org.eclipse.cdt.doc.isv/topics_Guide.xml
index c81a1aaac09..ae30603660c 100644
--- a/doc/org.eclipse.cdt.doc.isv/topics_Guide.xml
+++ b/doc/org.eclipse.cdt.doc.isv/topics_Guide.xml
@@ -6,6 +6,7 @@
<toc label="Guide">
<topic label="CDT DOM" href="guide/dom/index.html">
<topic label="Prebuilt Indexes in CDT 4.0" href="guide/dom/index/prebuiltIndexes.html"/>
+ <topic label="Versioning of Prebuilt Indexes" href="guide/dom/index/prebuiltVersioning.html"/>
</topic>
<topic label="Managed Build System Extensibility Document" href="guide/mbs/extensibilityGuide/Managed_Build_Extensibility.html"/>
<topic label="Project Template Engine" href="guide/projectTemplateEngine/index.html"/>

Back to the top