blob: 473d5f4226da1db7f523bccd098770af9d34a43a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2017 Cloudsmith Inc. and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Cloudsmith Inc. - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.p2.tests.ql;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.equinox.internal.p2.director.PermissiveSlicer;
import org.eclipse.equinox.internal.p2.director.QueryableArray;
import org.eclipse.equinox.internal.p2.director.Slicer;
import org.eclipse.equinox.internal.p2.metadata.InstallableUnit;
import org.eclipse.equinox.internal.p2.metadata.expression.MatchIteratorFilter;
import org.eclipse.equinox.internal.p2.metadata.repository.CompositeMetadataRepository;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.metadata.IProvidedCapability;
import org.eclipse.equinox.p2.metadata.IRequirement;
import org.eclipse.equinox.p2.metadata.MetadataFactory;
import org.eclipse.equinox.p2.metadata.Version;
import org.eclipse.equinox.p2.metadata.VersionRange;
import org.eclipse.equinox.p2.metadata.expression.ExpressionUtil;
import org.eclipse.equinox.p2.metadata.expression.IExpressionParser;
import org.eclipse.equinox.p2.publisher.actions.JREAction;
import org.eclipse.equinox.p2.query.IQuery;
import org.eclipse.equinox.p2.query.IQueryResult;
import org.eclipse.equinox.p2.query.IQueryable;
import org.eclipse.equinox.p2.query.MatchQuery;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
import org.eclipse.equinox.p2.tests.AbstractProvisioningTest;
public class PerformanceTest extends AbstractProvisioningTest {
public void testParserPerformance() throws Exception {
IExpressionParser parser = ExpressionUtil.getParser();
long start = System.currentTimeMillis();
for (int i = 0; i < 50000; i++)
parser.parse("providedCapabilities.exists(x | x.name == foo)");
System.out.println("Parse of 50000 expressions took: " + (System.currentTimeMillis() - start) + " milliseconds");
}
public void testMatchQueryVersusExpressionPerformance() throws Exception {
IMetadataRepository repo = getMDR("/testData/galileoM7");
IQuery<IInstallableUnit> expressionQuery = QueryUtil.createMatchQuery("id ~= /com.ibm.*/");
IQuery<IInstallableUnit> matchQuery = new MatchQuery<IInstallableUnit>() {
@Override
public boolean isMatch(IInstallableUnit candidate) {
return candidate.getId().startsWith("com.ibm.");
}
};
IQueryResult<IInstallableUnit> result;
long matchQueryMS = 0;
long exprQueryMS = 0;
for (int i = 0; i < 5; ++i) {
long start = System.currentTimeMillis();
for (int idx = 0; idx < 200; ++idx) {
result = repo.query(expressionQuery, new NullProgressMonitor());
assertEquals(queryResultSize(result), 2);
}
exprQueryMS += (System.currentTimeMillis() - start);
start = System.currentTimeMillis();
for (int idx = 0; idx < 200; ++idx) {
result = repo.query(matchQuery, new NullProgressMonitor());
assertEquals(queryResultSize(result), 2);
}
matchQueryMS += (System.currentTimeMillis() - start);
}
System.out.println("ExpressionQuery took: " + exprQueryMS + " milliseconds");
System.out.println("MatchQuery took: " + matchQueryMS + " milliseconds");
System.out.println();
}
public void testMatchQueryVersusIndexedExpressionPerformance() throws Exception {
IMetadataRepository repo = getMDR("/testData/galileoM7");
IQuery<IInstallableUnit> expressionQuery = QueryUtil.createMatchQuery("id == 'org.eclipse.core.resources'");
IQuery<IInstallableUnit> matchQuery = new MatchQuery<IInstallableUnit>() {
@Override
public boolean isMatch(IInstallableUnit candidate) {
return candidate.getId().equals("org.eclipse.core.resources");
}
};
IQueryResult<IInstallableUnit> result;
long matchQueryMS = 0;
long exprQueryMS = 0;
for (int i = 0; i < 5; ++i) {
long start = System.currentTimeMillis();
for (int idx = 0; idx < 200; ++idx) {
result = repo.query(expressionQuery, new NullProgressMonitor());
assertEquals(queryResultSize(result), 1);
}
exprQueryMS += (System.currentTimeMillis() - start);
start = System.currentTimeMillis();
for (int idx = 0; idx < 200; ++idx) {
result = repo.query(matchQuery, new NullProgressMonitor());
assertEquals(queryResultSize(result), 1);
}
matchQueryMS += (System.currentTimeMillis() - start);
}
System.out.println("IndexedExpressionQuery took: " + exprQueryMS + " milliseconds");
System.out.println("MatchQuery took: " + matchQueryMS + " milliseconds");
System.out.println();
}
public void testMatchQueryVersusIndexedExpressionPerformance2() throws Exception {
IMetadataRepository repo = getMDR("/testData/galileoM7");
IQuery<IInstallableUnit> expressionQuery = QueryUtil.createMatchQuery("providedCapabilities.exists(x | x.namespace == 'org.eclipse.equinox.p2.iu' && x.name == 'org.eclipse.core.resources')");
IQuery<IInstallableUnit> matchQuery = new MatchQuery<IInstallableUnit>() {
@Override
public boolean isMatch(IInstallableUnit candidate) {
for (IProvidedCapability capability : candidate.getProvidedCapabilities())
if ("org.eclipse.equinox.p2.iu".equals(capability.getNamespace()) && "org.eclipse.core.resources".equals(capability.getName()))
return true;
return false;
}
};
IQueryResult<IInstallableUnit> result;
long matchQueryMS = 0;
long exprQueryMS = 0;
for (int i = 0; i < 5; ++i) {
long start = System.currentTimeMillis();
for (int idx = 0; idx < 200; ++idx) {
result = repo.query(expressionQuery, new NullProgressMonitor());
assertEquals(queryResultSize(result), 1);
}
exprQueryMS += (System.currentTimeMillis() - start);
start = System.currentTimeMillis();
for (int idx = 0; idx < 200; ++idx) {
result = repo.query(matchQuery, new NullProgressMonitor());
assertEquals(queryResultSize(result), 1);
}
matchQueryMS += (System.currentTimeMillis() - start);
}
System.out.println("IndexedExpressionQuery took: " + exprQueryMS + " milliseconds");
System.out.println("MatchQuery took: " + matchQueryMS + " milliseconds");
System.out.println();
}
public void testMatchQueryVersusMatchIteratorPerformance() throws Exception {
IMetadataRepository repo = getMDR("/testData/galileoM7");
IQuery<IInstallableUnit> matchQuery = new MatchQuery<IInstallableUnit>() {
@Override
public boolean isMatch(IInstallableUnit candidate) {
return candidate.getId().startsWith("org.eclipse.");
}
};
long matchFilterMS = 0;
long iterationFilterMS = 0;
long matchQueryMS = 0;
for (int i = 0; i < 5; ++i) {
long start = System.currentTimeMillis();
for (int idx = 0; idx < 80; ++idx) {
IQueryResult<IInstallableUnit> everything = repo.query(QueryUtil.createIUAnyQuery(), new NullProgressMonitor());
Iterator<IInstallableUnit> matchIter = new MatchIteratorFilter<IInstallableUnit>(everything.iterator()) {
@Override
protected boolean isMatch(IInstallableUnit candidate) {
return candidate.getId().startsWith("org.eclipse.");
}
};
int sz = 0;
while (matchIter.hasNext()) {
matchIter.next();
sz++;
}
assertEquals(sz, 3240);
}
matchFilterMS += (System.currentTimeMillis() - start);
start = System.currentTimeMillis();
for (int idx = 0; idx < 80; ++idx) {
int sz = 0;
for (Iterator<IInstallableUnit> iter = repo.query(QueryUtil.createIUAnyQuery(), new NullProgressMonitor()).iterator(); iter.hasNext();) {
IInstallableUnit candidate = iter.next();
if (candidate.getId().startsWith("org.eclipse."))
sz++;
}
assertEquals(sz, 3240);
}
iterationFilterMS += (System.currentTimeMillis() - start);
start = System.currentTimeMillis();
for (int idx = 0; idx < 80; ++idx) {
int sz = 0;
for (Iterator<IInstallableUnit> iter = repo.query(matchQuery, new NullProgressMonitor()).iterator(); iter.hasNext();) {
iter.next();
sz++;
}
assertEquals(sz, 3240);
}
matchQueryMS += (System.currentTimeMillis() - start);
}
System.out.println("MatchFilter took: " + matchFilterMS + " milliseconds");
System.out.println("IteratorFilter took: " + iterationFilterMS + " milliseconds");
System.out.println("MatchQuery took: " + matchQueryMS + " milliseconds");
System.out.println();
}
public void testCapabilityQueryPerformance() throws Exception {
IMetadataRepository repo = getMDR("/testData/galileoM7");
IRequirement capability = MetadataFactory.createRequirement("org.eclipse.equinox.p2.eclipse.type", "feature", new VersionRange("[1.0.0,2.0.0)"), null, false, false);
IQuery<IInstallableUnit> predicateQuery = QueryUtil.createMatchQuery("this ~= $0", capability);
IQuery<IInstallableUnit> capabilityQuery = QueryUtil.createMatchQuery(capability.getMatches());
IQueryResult<IInstallableUnit> result;
long tradQueryMS = 0;
long exprQueryMS = 0;
for (int i = 0; i < 5; ++i) {
long start = System.currentTimeMillis();
for (int idx = 0; idx < 80; ++idx) {
result = repo.query(capabilityQuery, new NullProgressMonitor());
assertEquals(queryResultSize(result), 487);
}
tradQueryMS += (System.currentTimeMillis() - start);
start = System.currentTimeMillis();
for (int idx = 0; idx < 80; ++idx) {
result = repo.query(predicateQuery, new NullProgressMonitor());
assertEquals(queryResultSize(result), 487);
}
exprQueryMS += (System.currentTimeMillis() - start);
}
System.out.println("CapabilityQuery took: " + tradQueryMS + " milliseconds");
System.out.println("PredicateQuery took: " + exprQueryMS + " milliseconds");
System.out.println();
}
public void testCapabilityQueryPerformanceEE() throws Exception {
IMetadataRepository repo = getMDR("/testData/galileoM7");
Version jreVersion = Version.parseVersion("1.8");
Map<String, Object> capAttrs = new HashMap<>();
capAttrs.put(JREAction.NAMESPACE_OSGI_EE, "JavaSE");
capAttrs.put(JREAction.VERSION_OSGI_EE, jreVersion);
IProvidedCapability jreCap = MetadataFactory.createProvidedCapability(JREAction.NAMESPACE_OSGI_EE, capAttrs);
IInstallableUnit jre8IU = createIU("a.jre.javase", jreVersion, new IProvidedCapability[] {jreCap});
repo.addInstallableUnits(Collections.singletonList(jre8IU));
jreVersion = Version.parseVersion("1.9");
capAttrs = new HashMap<>();
capAttrs.put(JREAction.NAMESPACE_OSGI_EE, "JavaSE");
capAttrs.put(JREAction.VERSION_OSGI_EE, jreVersion);
jreCap = MetadataFactory.createProvidedCapability(JREAction.NAMESPACE_OSGI_EE, capAttrs);
IInstallableUnit jre9IU = createIU("b.jre.anotherjavase", jreVersion, new IProvidedCapability[] {jreCap});
repo.addInstallableUnits(Collections.singletonList(jre9IU));
IRequirement capability = MetadataFactory.createRequirement(JREAction.NAMESPACE_OSGI_EE, "(&(osgi.ee=JavaSE)(version=1.8))", null, 0, 0, false);
IQuery<IInstallableUnit> capabilityQuery = QueryUtil.createMatchQuery(capability.getMatches());
IQueryResult<IInstallableUnit> result;
long tradQueryMS = 0;
for (int i = 0; i < 5; ++i) {
long start = System.currentTimeMillis();
for (int idx = 0; idx < 80; ++idx) {
result = repo.query(capabilityQuery, new NullProgressMonitor());
assertEquals(1, queryResultSize(result));
assertEquals(jre8IU, result.toUnmodifiableSet().iterator().next());
}
tradQueryMS += (System.currentTimeMillis() - start);
}
System.out.println("CapabilityQuery took: " + tradQueryMS + " milliseconds");
System.out.println();
}
public void testIUPropertyQueryPerformance() throws Exception {
IMetadataRepository repo = getMDR("/testData/galileoM7");
IQuery<IInstallableUnit> propertyQuery = QueryUtil.createIUPropertyQuery("df_LT.providerName", "Eclipse.org");
IQuery<IInstallableUnit> predicateQuery = QueryUtil.createMatchQuery("properties[$0] == $1", "df_LT.providerName", "Eclipse.org");
IQueryResult<IInstallableUnit> result;
long tradQueryMS = 0;
long exprQueryMS = 0;
for (int i = 0; i < 5; ++i) {
long start = System.currentTimeMillis();
for (int idx = 0; idx < 80; ++idx) {
result = repo.query(propertyQuery, new NullProgressMonitor());
assertEquals(queryResultSize(result), 965);
}
tradQueryMS += (System.currentTimeMillis() - start);
start = System.currentTimeMillis();
for (int idx = 0; idx < 80; ++idx) {
result = repo.query(predicateQuery, new NullProgressMonitor());
assertEquals(queryResultSize(result), 965);
}
exprQueryMS += (System.currentTimeMillis() - start);
}
System.out.println("IUPropertyQuery took: " + tradQueryMS + " milliseconds");
System.out.println("PredicateQuery took: " + exprQueryMS + " milliseconds");
System.out.println();
}
public void testSlicerPerformance() throws Exception {
HashMap<String, String> env = new HashMap<>();
env.put("osgi.os", "linux");
env.put("osgi.ws", "gtk");
env.put("osgi.arch", "x86");
IInstallableUnit envIU = InstallableUnit.contextIU(env);
IMetadataRepository repo = getMDR("/testData/galileoM7");
IQueryResult<IInstallableUnit> r = repo.query(QueryUtil.createIUQuery("org.eclipse.sdk.feature.group", Version.create("3.5.0.v20090423-7Q7bA7DPR-wM38__Q4iRsmx9z0KOjbpx3AbyvXd-Uq7J2")), new NullProgressMonitor());
Iterator<IInstallableUnit> itor = r.iterator();
assertTrue(itor.hasNext());
IInstallableUnit[] roots = new IInstallableUnit[] {itor.next()};
IQuery<IInstallableUnit> query = QueryUtil.createQuery( //
"$0.traverse(set(), _, { cache, parent | parent.requirements.unique(cache).select(rc | rc.filter == null || $1 ~= rc.filter).collect(rc | everything.select(iu | iu ~= rc)).flatten()})", roots, envIU);
long sliceTime = 0;
long traverseTime = 0;
IQueryable<IInstallableUnit> slice = null;
for (int idx = 0; idx < 100; ++idx) {
long startTime = System.currentTimeMillis();
r = repo.query(query, new NullProgressMonitor());
traverseTime += (System.currentTimeMillis() - startTime);
assertEquals(queryResultSize(r), 411);
startTime = System.currentTimeMillis();
Slicer slicer = new Slicer(new QueryableArray(gatherAvailableInstallableUnits(repo)), env, false);
slice = slicer.slice(roots, new NullProgressMonitor());
sliceTime += (System.currentTimeMillis() - startTime);
}
// Check the size of the last slice to verify that it's the same as the traverse size
r = slice.query(new MatchQuery<IInstallableUnit>() {
@Override
public boolean isMatch(IInstallableUnit value) {
return true;
}
}, new NullProgressMonitor());
assertEquals(queryResultSize(r), 411);
System.out.print("100 * Slicing took: ");
System.out.println(sliceTime);
System.out.print("100 * Indexed Traverse expression took: ");
System.out.println(traverseTime);
System.out.println();
}
public void testPermissiveSlicerPerformance() throws Exception {
HashMap<String, String> env = new HashMap<>();
//env.put("osgi.os", "linux");
//env.put("osgi.ws", "gtk");
//env.put("osgi.arch", "x86");
IInstallableUnit envIU = InstallableUnit.contextIU(env);
CompositeMetadataRepository compositeMetadataRepository = CompositeMetadataRepository.createMemoryComposite(getMetadataRepositoryManager().getAgent());
compositeMetadataRepository.addChild(new URI("http://download.eclipse.org/releases/galileo"));
IMetadataRepository repo = compositeMetadataRepository;
IQueryResult<IInstallableUnit> r = repo.query(QueryUtil.createIUQuery("org.eclipse.sdk.ide"), new NullProgressMonitor());
IInstallableUnit[] roots = r.toArray(IInstallableUnit.class);
IQuery<IInstallableUnit> query = QueryUtil.createQuery( //
"$0.traverse(set(), _, { cache, parent | parent.requirements.unique(cache).collect(rc | everything.select(iu | iu ~= rc)).flatten()})", roots, envIU);
long sliceTime = 0;
long traverseTime = 0;
IQueryable<IInstallableUnit> slice = null;
for (int idx = 0; idx < 10; ++idx) {
long startTime = System.currentTimeMillis();
r = repo.query(query, new NullProgressMonitor());
traverseTime += (System.currentTimeMillis() - startTime);
assertEquals(4704, queryResultSize(r));
startTime = System.currentTimeMillis();
Slicer slicer = new PermissiveSlicer(repo, env, true, true, true, false, false);
slice = slicer.slice(roots, new NullProgressMonitor());
sliceTime += (System.currentTimeMillis() - startTime);
}
// Check the size of the last slice to verify that it's the same as the traverse size
r = slice.query(new MatchQuery<IInstallableUnit>() {
@Override
public boolean isMatch(IInstallableUnit value) {
return true;
}
}, new NullProgressMonitor());
assertEquals(queryResultSize(r), 4704);
System.out.print("10 * Slicing took: ");
System.out.println(sliceTime);
System.out.print("10 * Indexed Traverse expression took: ");
System.out.println(traverseTime);
System.out.println();
}
private IMetadataRepository getMDR(String uri) throws Exception {
URI metadataRepo = getTestData("1.1", uri).toURI();
IMetadataRepositoryManager metadataManager = getAgent().getService(IMetadataRepositoryManager.class);
assertNotNull(metadataManager);
return metadataManager.loadRepository(metadataRepo, new NullProgressMonitor());
}
private IInstallableUnit[] gatherAvailableInstallableUnits(IQueryable<IInstallableUnit> queryable) {
ArrayList<IInstallableUnit> list = new ArrayList<>();
IQueryResult<IInstallableUnit> matches = queryable.query(QueryUtil.createIUAnyQuery(), null);
for (Iterator<IInstallableUnit> it = matches.iterator(); it.hasNext();)
list.add(it.next());
return list.toArray(new IInstallableUnit[list.size()]);
}
}