Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Arthorne2009-12-18 20:51:01 +0000
committerJohn Arthorne2009-12-18 20:51:01 +0000
commitae810b22032c9b8cffd5e58e82dadab913585341 (patch)
treedca4eaaebd37c4325880e80a4dcc6763bf69d975
parent05d2b20f5b78107ed8b356d8472f760449465d38 (diff)
downloadrt.equinox.p2-ae810b22032c9b8cffd5e58e82dadab913585341.tar.gz
rt.equinox.p2-ae810b22032c9b8cffd5e58e82dadab913585341.tar.xz
rt.equinox.p2-ae810b22032c9b8cffd5e58e82dadab913585341.zip
Bug 298216 - Reconciler performance when installing large number of features.
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/IUMap.java107
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/LocalMetadataRepository.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/URLMetadataRepository.java9
-rw-r--r--bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/PublisherResult.java17
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/MetadataRepositoryPerformanceTest.java69
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/ProvisioningPerformanceTest.java31
-rw-r--r--bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/PublisherPerformanceTest.java53
7 files changed, 289 insertions, 6 deletions
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/IUMap.java b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/IUMap.java
new file mode 100644
index 000000000..c629f0086
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/IUMap.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.internal.p2.metadata.repository;
+
+import java.util.*;
+import org.eclipse.equinox.internal.provisional.p2.metadata.query.Collector;
+import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+
+/**
+ * A map that stores {@link IInstallableUnit} instances in a way that is efficient to query
+ */
+public class IUMap {
+ /**
+ * Iterator over all the {@link IInstallableUnit} instances in the map.
+ */
+ public class MapIterator implements Iterator {
+ //iterator over the keys in UIMap
+ private Iterator unitIterator;
+ //iterator over the Set inside a single value of the IUMap
+ private Iterator currentBucket;
+
+ MapIterator() {
+ super();
+ unitIterator = units.keySet().iterator();
+ }
+
+ public boolean hasNext() {
+ return unitIterator.hasNext() || (currentBucket != null && currentBucket.hasNext());
+ }
+
+ public Object next() {
+ if (currentBucket == null || !currentBucket.hasNext())
+ currentBucket = ((Set) units.get(unitIterator.next())).iterator();
+ return currentBucket.next();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Map<String,Set<IInstallableUnit>> mapping IU id to iu's with that id.
+ */
+ final Map units = new HashMap();
+
+ public void add(IInstallableUnit unit) {
+ Set matching = (Set) units.get(unit.getId());
+ if (matching == null) {
+ matching = new HashSet(2);
+ units.put(unit.getId(), matching);
+ }
+ matching.add(unit);
+ }
+
+ public void addAll(IInstallableUnit[] toAdd) {
+ for (int i = 0; i < toAdd.length; i++)
+ add(toAdd[i]);
+ }
+
+ public void clear() {
+ units.clear();
+ }
+
+ public Iterator iterator() {
+ return new MapIterator();
+ }
+
+ public Collector query(InstallableUnitQuery query) {
+ //iterate over the entire map, or just the IU's with the given id
+ Collector result = new Collector();
+ Iterator candidates;
+ if (query.getId() == null)
+ candidates = iterator();
+ else {
+ Collection bucket = ((Collection) units.get(query.getId()));
+ if (bucket == null)
+ return result;
+ candidates = bucket.iterator();
+ }
+ return query.perform(candidates, result);
+
+ }
+
+ public void remove(IInstallableUnit unit) {
+ Set matching = (Set) units.get(unit.getId());
+ if (matching == null)
+ return;
+ matching.remove(unit);
+ if (matching.isEmpty())
+ units.remove(unit.getId());
+ }
+
+ public void removeAll(Collection toRemove) {
+ for (Iterator it = toRemove.iterator(); it.hasNext();)
+ remove((IInstallableUnit) it.next());
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/LocalMetadataRepository.java b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/LocalMetadataRepository.java
index 629016f71..c7445d897 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/LocalMetadataRepository.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/LocalMetadataRepository.java
@@ -22,6 +22,7 @@ import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.Collector;
+import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
import org.eclipse.equinox.internal.provisional.p2.repository.RepositoryEvent;
import org.eclipse.equinox.internal.provisional.spi.p2.metadata.repository.AbstractMetadataRepository;
import org.eclipse.equinox.internal.provisional.spi.p2.metadata.repository.RepositoryReference;
@@ -44,7 +45,7 @@ public class LocalMetadataRepository extends AbstractMetadataRepository {
static final private String JAR_EXTENSION = ".jar"; //$NON-NLS-1$
static final private String XML_EXTENSION = ".xml"; //$NON-NLS-1$
- protected HashSet units = new LinkedHashSet();
+ protected IUMap units = new IUMap();
protected HashSet repositories = new HashSet();
private static File getActualLocation(URI location, String extension) {
@@ -89,7 +90,7 @@ public class LocalMetadataRepository extends AbstractMetadataRepository {
public synchronized void addInstallableUnits(IInstallableUnit[] installableUnits) {
if (installableUnits == null || installableUnits.length == 0)
return;
- units.addAll(Arrays.asList(installableUnits));
+ units.addAll(installableUnits);
save();
}
@@ -107,7 +108,7 @@ public class LocalMetadataRepository extends AbstractMetadataRepository {
this.description = state.Description;
this.location = state.Location;
this.properties = state.Properties;
- this.units.addAll(Arrays.asList(state.Units));
+ this.units.addAll(state.Units);
this.repositories.addAll(Arrays.asList(state.Repositories));
}
publishRepositoryReferences();
@@ -145,6 +146,8 @@ public class LocalMetadataRepository extends AbstractMetadataRepository {
}
public synchronized IQueryResult query(IQuery query, IProgressMonitor monitor) {
+ if (query instanceof InstallableUnitQuery)
+ return units.query((InstallableUnitQuery) query);
return query.perform(units.iterator(), new Collector());
}
diff --git a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/URLMetadataRepository.java b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/URLMetadataRepository.java
index f7756012c..d06b2e8a4 100644
--- a/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/URLMetadataRepository.java
+++ b/bundles/org.eclipse.equinox.p2.metadata.repository/src/org/eclipse/equinox/internal/p2/metadata/repository/URLMetadataRepository.java
@@ -12,10 +12,11 @@
package org.eclipse.equinox.internal.p2.metadata.repository;
import java.net.URI;
-import java.util.*;
+import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.URIUtil;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.Collector;
+import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
import org.eclipse.equinox.internal.provisional.spi.p2.metadata.repository.AbstractMetadataRepository;
import org.eclipse.equinox.p2.metadata.query.IQuery;
import org.eclipse.equinox.p2.metadata.query.IQueryResult;
@@ -31,7 +32,7 @@ public class URLMetadataRepository extends AbstractMetadataRepository {
private static final Integer REPOSITORY_VERSION = new Integer(1);
transient protected URI content;
- protected HashSet units = new LinkedHashSet();
+ protected IUMap units = new IUMap();
public static URI getActualLocation(URI base) {
return getActualLocation(base, XML_EXTENSION);
@@ -65,7 +66,7 @@ public class URLMetadataRepository extends AbstractMetadataRepository {
this.description = state.Description;
this.location = state.Location;
this.properties = state.Properties;
- this.units.addAll(Arrays.asList(state.Units));
+ this.units.addAll(state.Units);
}
// Use this method to setup any transient fields etc after the object has been restored from a stream
@@ -79,6 +80,8 @@ public class URLMetadataRepository extends AbstractMetadataRepository {
}
public synchronized IQueryResult query(IQuery query, IProgressMonitor monitor) {
+ if (query instanceof InstallableUnitQuery)
+ return units.query((InstallableUnitQuery) query);
return query.perform(units.iterator(), new Collector());
}
}
diff --git a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/PublisherResult.java b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/PublisherResult.java
index 754f66b9c..35390bff3 100644
--- a/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/PublisherResult.java
+++ b/bundles/org.eclipse.equinox.p2.publisher/src/org/eclipse/equinox/p2/publisher/PublisherResult.java
@@ -13,6 +13,7 @@ package org.eclipse.equinox.p2.publisher;
import java.util.*;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.equinox.internal.provisional.p2.metadata.Version;
+import org.eclipse.equinox.internal.provisional.p2.metadata.VersionRange;
import org.eclipse.equinox.internal.provisional.p2.metadata.query.*;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.query.IQuery;
@@ -140,8 +141,24 @@ public class PublisherResult implements IPublisherResult {
* Queries both the root and non root IUs
*/
public IQueryResult query(IQuery query, IProgressMonitor monitor) {
+ //optimize for installable unit query
+ if (query instanceof InstallableUnitQuery)
+ return queryIU((InstallableUnitQuery) query, monitor);
IQueryable nonRootQueryable = new QueryableMap(nonRootIUs);
IQueryable rootQueryable = new QueryableMap(rootIUs);
return new CompoundQueryable(new IQueryable[] {nonRootQueryable, rootQueryable}).query(query, monitor);
}
+
+ private IQueryResult queryIU(InstallableUnitQuery query, IProgressMonitor monitor) {
+ Collector result = new Collector();
+ Collection matches = getIUs(query.getId(), null);
+ VersionRange queryRange = query.getRange();
+ for (Iterator it = matches.iterator(); it.hasNext();) {
+ IInstallableUnit match = (IInstallableUnit) it.next();
+ if (queryRange == null || queryRange.isIncluded(match.getVersion()))
+ if (!result.accept(match))
+ break;
+ }
+ return result;
+ }
}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/MetadataRepositoryPerformanceTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/MetadataRepositoryPerformanceTest.java
new file mode 100644
index 000000000..41189a030
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/MetadataRepositoryPerformanceTest.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.tests.perf;
+
+import java.io.File;
+import org.eclipse.core.tests.harness.PerformanceTestRunner;
+import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.query.IQuery;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
+
+/**
+ * Performance tests for metadata repositories
+ */
+public class MetadataRepositoryPerformanceTest extends ProvisioningPerformanceTest {
+ private static final int REPEATS = 5;
+ protected File repoLocation;
+ IMetadataRepository repository;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ String tempDir = System.getProperty("java.io.tmpdir");
+ repoLocation = new File(tempDir, "MetadataRepositoryPerformanceTest");
+ delete(repoLocation);
+ repoLocation.mkdir();
+ IMetadataRepositoryManager manager = getMetadataRepositoryManager();
+ repository = manager.createRepository(repoLocation.toURI(), "TestRepo", IMetadataRepositoryManager.TYPE_SIMPLE_REPOSITORY, null);
+ }
+
+ protected void tearDown() throws Exception {
+ getMetadataRepositoryManager().removeRepository(repoLocation.toURI());
+ delete(repoLocation);
+ super.tearDown();
+ }
+
+ public void testQueryLocalRepository() {
+ final int IU_COUNT = 3000;
+ new PerformanceTestRunner() {
+ IQuery[] queries = new IQuery[IU_COUNT];
+
+ protected void setUp() {
+ IInstallableUnit[] ius = new IInstallableUnit[IU_COUNT];
+ for (int i = 0; i < ius.length; i++) {
+ ius[i] = generateIU(i);
+ queries[i] = new InstallableUnitQuery(ius[i].getId(), ius[i].getVersion());
+ }
+ repository.addInstallableUnits(ius);
+ }
+
+ protected void tearDown() {
+ }
+
+ protected void test() {
+ for (int i = 0; i < queries.length; i++) {
+ repository.query(queries[i], null);
+ }
+ }
+ }.run(this, "Test query local metadata repo for " + IU_COUNT + " ius", REPEATS, 10);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/ProvisioningPerformanceTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/ProvisioningPerformanceTest.java
new file mode 100644
index 000000000..75eab3a4b
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/ProvisioningPerformanceTest.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.tests.perf;
+
+import org.eclipse.equinox.internal.provisional.p2.metadata.MetadataFactory;
+import org.eclipse.equinox.internal.provisional.p2.metadata.Version;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+
+import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
+
+/**
+ *
+ */
+public class ProvisioningPerformanceTest extends AbstractProvisioningTest {
+
+ protected IInstallableUnit generateIU(int i) {
+ MetadataFactory.InstallableUnitDescription desc = new MetadataFactory.InstallableUnitDescription();
+ desc.setId("org.eclipse.someiu" + i);
+ desc.setVersion(Version.createOSGi(1, 1, i));
+ return MetadataFactory.createInstallableUnit(desc);
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/PublisherPerformanceTest.java b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/PublisherPerformanceTest.java
new file mode 100644
index 000000000..a85f8c8f7
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.tests/src/org/eclipse/equinox/p2/tests/perf/PublisherPerformanceTest.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2009 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.equinox.p2.tests.perf;
+
+import org.eclipse.core.tests.harness.PerformanceTestRunner;
+import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery;
+import org.eclipse.equinox.p2.metadata.IInstallableUnit;
+import org.eclipse.equinox.p2.metadata.query.IQuery;
+import org.eclipse.equinox.p2.publisher.IPublisherResult;
+import org.eclipse.equinox.p2.publisher.PublisherResult;
+
+/**
+ * Performance tests for the p2 publisher
+ */
+public class PublisherPerformanceTest extends ProvisioningPerformanceTest {
+ private static final int REPEATS = 5;
+
+ public void testQueryPublisherResult() {
+ final int IU_COUNT = 3000;
+ new PerformanceTestRunner() {
+ IQuery[] queries = new IQuery[IU_COUNT];
+ PublisherResult result;
+
+ protected void setUp() {
+ IInstallableUnit[] ius = new IInstallableUnit[IU_COUNT];
+ result = new PublisherResult();
+ for (int i = 0; i < ius.length; i++) {
+ ius[i] = generateIU(i);
+ result.addIU(ius[i], IPublisherResult.ROOT);
+ queries[i] = new InstallableUnitQuery(ius[i].getId(), ius[i].getVersion());
+ }
+ }
+
+ protected void tearDown() {
+ }
+
+ protected void test() {
+ for (int i = 0; i < queries.length; i++) {
+ result.query(queries[i], null);
+ }
+ }
+ }.run(this, "Test query PublisherResult for " + IU_COUNT + " ius", REPEATS, 10);
+
+ }
+}

Back to the top