Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff McAffer2007-11-09 04:22:59 +0000
committerJeff McAffer2007-11-09 04:22:59 +0000
commitfcea91b2f7245eed48cd1567632b3abdeaef85c6 (patch)
treedb4d3df7796765a629a0ce3721b07a22b13919a6 /bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox
parentfc90971ca172753f1bbb91cedb638771fdab18fd (diff)
downloadrt.equinox.p2-fcea91b2f7245eed48cd1567632b3abdeaef85c6.tar.gz
rt.equinox.p2-fcea91b2f7245eed48cd1567632b3abdeaef85c6.tar.xz
rt.equinox.p2-fcea91b2f7245eed48cd1567632b3abdeaef85c6.zip
update the JarDelta optimizer/processors, integrate with JBdiff and add some tests
Diffstat (limited to 'bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox')
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/Activator.java (renamed from bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Activator.java)5
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Activator.java30
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Application.java20
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/DeltaComputer.java56
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/JarDeltaOptimizerStep.java122
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Optimizer.java241
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/AbstractDeltaDiffStep.java1
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Application.java1
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Optimizer.java6
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Activator.java30
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Application.java1
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Optimizer.java13
-rw-r--r--bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Pack200Step.java1
13 files changed, 436 insertions, 91 deletions
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Activator.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/Activator.java
index c451de00a..cfcd1e8d9 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Activator.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/Activator.java
@@ -7,14 +7,13 @@
* Contributors: IBM Corporation - initial API and implementation
******************************************************************************/
-package org.eclipse.equinox.internal.p2.artifact.optimizers.jbdiff;
+package org.eclipse.equinox.internal.p2.artifact.optimizers;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
-
- public static final String ID = "org.eclipse.equinox.p2.artifact.optimizer.jbdiff"; //$NON-NLS-1$
+ public static final String ID = "org.eclipse.equinox.p2.artifact.optimizers"; //$NON-NLS-1$
private static BundleContext context = null;
public static BundleContext getContext() {
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Activator.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Activator.java
deleted file mode 100644
index e23c1354c..000000000
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Activator.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007 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.artifact.optimizers.jardelta;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-public class Activator implements BundleActivator {
- public static final String ID = "org.eclipse.equinox.p2.artifact.optimizer.jardelta"; //$NON-NLS-1$
- private static BundleContext context = null;
-
- public static BundleContext getContext() {
- return context;
- }
-
- public void start(BundleContext context) throws Exception {
- Activator.context = context;
- }
-
- public void stop(BundleContext context) throws Exception {
- }
-
-}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Application.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Application.java
index 02944bf90..d16090f38 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Application.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Application.java
@@ -12,19 +12,25 @@ import java.net.URL;
import java.util.Map;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.equinox.internal.p2.artifact.optimizers.Activator;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.p2.artifact.repository.IArtifactRepository;
import org.eclipse.equinox.p2.artifact.repository.IArtifactRepositoryManager;
+/**
+ * The optimizer <code>Application</code> for JBDiff based optimizations.
+ */
public class Application implements IApplication {
private URL artifactRepositoryLocation;
+ private int width = 1;
+ private int depth = 1;
public Object start(IApplicationContext context) throws Exception {
Map args = context.getArguments();
- initializeFromArguments((String[]) args.get("application.args"));
+ initializeFromArguments((String[]) args.get("application.args")); //$NON-NLS-1$
IArtifactRepository repository = setupRepository(artifactRepositoryLocation);
- // TODO add the processing in here.
+ new Optimizer(repository, width, depth).run();
return null;
}
@@ -37,6 +43,7 @@ public class Application implements IApplication {
}
public void stop() {
+ // nothing to do yet
}
public void initializeFromArguments(String[] args) throws Exception {
@@ -54,8 +61,15 @@ public class Application implements IApplication {
continue;
String arg = args[++i];
- if (args[i - 1].equalsIgnoreCase("-artifactRepository") | args[i - 1].equalsIgnoreCase("-ar"))
+ if (args[i - 1].equalsIgnoreCase("-artifactRepository") || args[i - 1].equalsIgnoreCase("-ar")) //$NON-NLS-1$ //$NON-NLS-2$
artifactRepositoryLocation = new URL(arg);
+
+ if (args[i - 1].equalsIgnoreCase("-depth")) //$NON-NLS-1$
+ depth = Integer.parseInt(arg);
+
+ if (args[i - 1].equalsIgnoreCase("-width")) //$NON-NLS-1$
+ width = Integer.parseInt(arg);
+
}
}
}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/DeltaComputer.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/DeltaComputer.java
index bb101d077..a176e939a 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/DeltaComputer.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/DeltaComputer.java
@@ -1,3 +1,13 @@
+/*******************************************************************************
+ * Copyright (c) 2007 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.artifact.optimizers.jardelta;
import java.io.*;
@@ -34,18 +44,23 @@ public class DeltaComputer {
private void writeDelta() {
JarOutputStream result = null;
try {
- result = new JarOutputStream(new FileOutputStream(destination));
- // write out the removals. These are all the entries left in the baseEntries
- // since they were not seen in the targetJar. Here just write out an empty
- // entry with a name that signals the delta processor to delete.
- for (Iterator i = baseEntries.iterator(); i.hasNext();)
- writeEntry(result, new JarEntry(((JarEntry) i.next()).getName() + ".delete"), null);
- // write out the additions.
- for (Iterator i = additions.iterator(); i.hasNext();)
- writeEntry(result, (JarEntry) i.next(), targetJar);
- // write out the changes.
- for (Iterator i = changes.iterator(); i.hasNext();)
- writeEntry(result, (JarEntry) i.next(), targetJar);
+ try {
+ result = new JarOutputStream(new FileOutputStream(destination));
+ // write out the removals. These are all the entries left in the baseEntries
+ // since they were not seen in the targetJar. Here just write out an empty
+ // entry with a name that signals the delta processor to delete.
+ for (Iterator i = baseEntries.iterator(); i.hasNext();)
+ writeEntry(result, new JarEntry(((String) i.next()) + ".delete"), null);
+ // write out the additions.
+ for (Iterator i = additions.iterator(); i.hasNext();)
+ writeEntry(result, (JarEntry) i.next(), targetJar);
+ // write out the changes.
+ for (Iterator i = changes.iterator(); i.hasNext();)
+ writeEntry(result, (JarEntry) i.next(), targetJar);
+ } finally {
+ if (result != null)
+ result.close();
+ }
} catch (IOException e) {
e.printStackTrace();
return;
@@ -95,8 +110,8 @@ public class DeltaComputer {
}
private void computeDelta() {
- ArrayList changes = new ArrayList();
- ArrayList additions = new ArrayList();
+ changes = new ArrayList();
+ additions = new ArrayList();
// start out assuming that all the base entries are being removed
baseEntries = getEntries(baseJar);
for (Enumeration e = targetJar.entries(); e.hasMoreElements();) {
@@ -145,25 +160,30 @@ public class DeltaComputer {
return;
}
// now we know each JAR has an entry for the name, compare and see how/if they differ
- boolean changed = equals(entry, baseEntry);
+ boolean changed = !equals(entry, baseEntry);
if (changed)
changes.add(entry);
- baseEntries.remove(baseEntry);
+ baseEntries.remove(baseEntry.getName());
}
// compare the two entries. We already know that they have the same name.
private boolean equals(JarEntry entry, JarEntry baseEntry) {
if (entry.getSize() != baseEntry.getSize())
return false;
- if (entry.getTime() != baseEntry.getTime())
+ // make sure the entries are of the same type
+ if (entry.isDirectory() != baseEntry.isDirectory())
return false;
+ // if the entries are files then compare the times.
+ if (!entry.isDirectory())
+ if (entry.getTime() != baseEntry.getTime())
+ return false;
return true;
}
private Set getEntries(JarFile jar) {
HashSet result = new HashSet(jar.size());
for (Enumeration e = jar.entries(); e.hasMoreElements();)
- result.add(e.nextElement());
+ result.add(((JarEntry) e.nextElement()).getName());
return result;
}
}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/JarDeltaOptimizerStep.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/JarDeltaOptimizerStep.java
new file mode 100644
index 000000000..968bb77e9
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/JarDeltaOptimizerStep.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+* Copyright (c) 2007 compeople AG 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:
+* compeople AG (Stefan Liebig) - initial API and implementation
+* IBM - continuing development
+*******************************************************************************/
+package org.eclipse.equinox.internal.p2.artifact.optimizers.jardelta;
+
+import java.io.*;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.artifact.optimizers.Activator;
+import org.eclipse.equinox.internal.p2.artifact.optimizers.jbdiff.AbstractDeltaDiffStep;
+import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
+import org.eclipse.equinox.p2.artifact.repository.*;
+
+/**
+ * The Pack200Packer expects an input containing normal ".jar" data.
+ */
+public class JarDeltaOptimizerStep extends AbstractDeltaDiffStep {
+ private static final String JAR_SUFFIX = ".jar"; //$NON-NLS-1$
+
+ private File incoming;
+ private OutputStream tempStream;
+
+ protected JarDeltaOptimizerStep(IArtifactRepository repository) {
+ super(repository);
+ }
+
+ public void write(int b) throws IOException {
+ OutputStream stream = getOutputStream();
+ stream.write(b);
+ }
+
+ private OutputStream getOutputStream() throws IOException {
+ if (tempStream != null)
+ return tempStream;
+ // store input stream in temporary file
+ incoming = File.createTempFile("p2.jardelta.optimizer.incoming", JAR_SUFFIX);
+ tempStream = new BufferedOutputStream(new FileOutputStream(incoming));
+ return tempStream;
+ }
+
+ private void performOptimization() throws IOException {
+ File predecessor = null;
+ File resultFile = null;
+ try {
+ // get the predecessor and perform the optimization into a temp file
+ predecessor = fetchPredecessor(new ArtifactDescriptor(key));
+ resultFile = File.createTempFile("p2.jardelta.optimizer.result", JAR_SUFFIX);
+ new DeltaComputer(predecessor, incoming, resultFile).run();
+
+ // now write the optimized content to the destination
+ if (resultFile.length() > 0) {
+ InputStream resultStream = new BufferedInputStream(new FileInputStream(resultFile));
+ FileUtils.copyStream(resultStream, true, destination, false);
+ } else {
+ status = new Status(IStatus.ERROR, Activator.ID, "Empty optimized file: " + resultFile);
+ }
+ } finally {
+ // if we have a predecessor and it is our temp file then clean up the file
+ if (predecessor != null && predecessor.getAbsolutePath().indexOf("p2.jardelta.predecessor") > -1)
+ predecessor.delete();
+ if (resultFile != null)
+ resultFile.delete();
+ }
+ }
+
+ private File fetchPredecessor(ArtifactDescriptor descriptor) {
+ if (repository instanceof IFileArtifactRepository)
+ return ((IFileArtifactRepository) repository).getArtifactFile(descriptor);
+ File result = null;
+ OutputStream resultStream = null;
+ try {
+ try {
+ result = File.createTempFile("p2.jardelta.predecessor", JAR_SUFFIX);
+ resultStream = new BufferedOutputStream(new FileOutputStream(result));
+ status = repository.getArtifact(descriptor, resultStream, monitor);
+ return result;
+ } finally {
+ if (resultStream != null)
+ resultStream.close();
+ }
+ } catch (IOException e) {
+ }
+ return null;
+ }
+
+ public void close() throws IOException {
+ // When we go to close we must have seen all the content we are going to see.
+ // If no one wrote to the temp stream then there is nothing to do. Be sure to delete the
+ // the temporary file if any.
+ if (tempStream == null) {
+ if (incoming != null)
+ incoming.delete();
+ return;
+ }
+
+ // So there is content. Close the temporary stream and perform the optimization.
+ // Performing the optimization should result in the new content being written to
+ // the destination. Make sure we delete the temporary file if any.
+ try {
+ tempStream.close();
+ performOptimization();
+ } finally {
+ if (incoming != null)
+ incoming.delete();
+ }
+
+ super.close();
+ // TODO need to get real status here. sometimes the optimizers do not give
+ // any reasonable return status
+ if (status == null)
+ status = Status.OK_STATUS;
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Optimizer.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Optimizer.java
new file mode 100644
index 000000000..a321cd804
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jardelta/Optimizer.java
@@ -0,0 +1,241 @@
+/*******************************************************************************
+* Copyright (c) 2007 compeople AG 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:
+* compeople AG (Stefan Liebig) - initial API and implementation
+* IBM Corporation - adaptation to JAR deltas and on-going development
+*******************************************************************************/
+package org.eclipse.equinox.internal.p2.artifact.optimizers.jardelta;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.*;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.equinox.internal.p2.artifact.optimizers.jbdiff.ArtifactKeyDeSerializer;
+import org.eclipse.equinox.internal.p2.metadata.ArtifactKey;
+import org.eclipse.equinox.p2.artifact.repository.*;
+import org.eclipse.equinox.p2.artifact.repository.processing.*;
+import org.eclipse.equinox.p2.metadata.IArtifactKey;
+import org.osgi.framework.Version;
+
+public class Optimizer {
+
+ private IArtifactRepository repository;
+ private int width;
+ private int depth;
+
+ private static final String JAR_DELTA_FORMAT = "jarDelta"; //$NON-NLS-1$
+ private static final String JAR_DELTA_PATCH_STEP = "org.eclipse.equinox.p2.processing.JarDeltaPatchStep"; //$NON-NLS-1$
+
+ private static final Comparator ARTIFACT_DESCRIPTOR_VERSION_COMPARATOR = new ArtifactDescriptorVersionComparator();
+ private static final Comparator ARTIFACT_KEY_VERSION_COMPARATOR = new ArtifactKeyVersionComparator();
+
+ /**
+ * This optimizer performs delta generation based on (currently) jbdiff.
+ * The optimization can be controlled with the ´width´ and the ´depth´ parameter.
+ * ´width´ defines for how many ´related´ artifact keys a delta should be generated,
+ * starting from the most up-to-date.
+ * ´depth´ defines to how many predecessor a delta should be generated.
+ *
+ * With AK(c-v) : AK - artifact key, c - artifact id, v - artifact version
+ * the ´repository content´ can be viewed a two dimensional array, where the
+ * artifact keys for the same component are in order of their version:
+ * <pre><code>
+ * w=1 w=2
+ * | |
+ * | +------.------------+ d=2
+ * | | +----.---+ d=1 |
+ * | | | | | v
+ * [ v | | v v v
+ * [ AK(x,2.0) AK(x,1.5) AK(x,1.1) ]
+ * [ AK(y,2.0) AK(y,1.9) ]
+ * [ AK(z,2.0) AK(z,1.5) AK(z,1.3) AK(z,1.0) ]
+ * ]
+ * </code></pre>
+ * E.g: with a ´width´ of one and a ´depth´ of two the optimizer would
+ * create two deltas for component ´x´ from 1.5 to 2.0 and from 1.1 to 2.0.
+ *
+ * @param repository
+ * @param width
+ * @param depth
+ */
+ public Optimizer(IArtifactRepository repository, int width, int depth) {
+ this.repository = repository;
+ this.width = width;
+ this.depth = depth;
+ }
+
+ public void run() {
+ System.out.println("Starting delta (jardelta) optimizations (width=" + width + ", depth=" + depth + ")");
+ IArtifactKey[][] keys = getSortedRelatedArtifactKeys(repository.getArtifactKeys());
+ for (int i = 0; i < keys.length; i++) {
+ if (keys[i].length < 2)
+ // Nothing to diff here!
+ continue;
+ int minWidth = Math.min(width, keys[i].length);
+ for (int j = 0; j < minWidth; j++) {
+ IArtifactKey key = keys[i][j];
+ boolean isArchive = key.getClassifier().equals("plugin"); //$NON-NLS-1$
+ optimize(keys[i], key);
+ }
+ }
+ System.out.println("Done.");
+
+ }
+
+ private void optimize(IArtifactKey[] keys, IArtifactKey key) {
+ IArtifactDescriptor[] descriptors = repository.getArtifactDescriptors(key);
+ IArtifactDescriptor canonical = null;
+ for (int k = 0; k < descriptors.length; k++) {
+ IArtifactDescriptor descriptor = descriptors[k];
+ boolean optimized = false;
+ if (isCanonical(descriptor))
+ canonical = descriptor;
+ else
+ optimized |= isOptimized(descriptor);
+ if (!optimized)
+ optimize(canonical, keys);
+ }
+ }
+
+ private IArtifactKey getVersionlessKey(IArtifactKey key) {
+ return new ArtifactKey(key.getNamespace(), key.getClassifier(), key.getId(), Version.emptyVersion);
+ }
+
+ /**
+ * This method retrieves a list of list of IArtifactKeys. The artifact keys in the
+ * list of artifact keys are all ´strongly related´ to each other such that are
+ * equal but not considering the versions. This list is sorted such that the
+ * newer versions are first in the list.<p>
+ * With AK(c-v) : AK - artifact key, c - artifact id, v - artifact version
+ * the result is than, e.g.
+ * <pre><code>
+ * [
+ * [ AK(x,2.0) AK(x,1.5) AK(x,1.1) ]
+ * [ AK(y,2.0) AK(y,1.9) ]
+ * [ AK(z,2.0) AK(z,1.5) AK(z,1.3) AK(z,1.0) ]
+ * ]
+ * </code></pre>
+ * @param artifactKeys
+ * @return the sorted artifact keys
+ */
+ private IArtifactKey[][] getSortedRelatedArtifactKeys(IArtifactKey[] artifactKeys) {
+ Map map = new HashMap();
+ for (int i = 0; i < artifactKeys.length; i++) {
+ IArtifactKey freeKey = getVersionlessKey(artifactKeys[i]);
+ List values = (List) map.get(freeKey);
+ if (values == null) {
+ values = new ArrayList();
+ map.put(freeKey, values);
+ }
+ values.add(artifactKeys[i]);
+ }
+ IArtifactKey[][] lists = new IArtifactKey[map.size()][];
+ int i = 0;
+ for (Iterator iterator = map.values().iterator(); iterator.hasNext();) {
+ List artifactKeyList = (List) iterator.next();
+ IArtifactKey[] relatedArtifactKeys = (IArtifactKey[]) artifactKeyList.toArray(new IArtifactKey[artifactKeyList.size()]);
+ Arrays.sort(relatedArtifactKeys, ARTIFACT_KEY_VERSION_COMPARATOR);
+ lists[i++] = relatedArtifactKeys;
+ }
+ int candidates = 0;
+ for (int ii = 0; ii < lists.length; ii++) {
+ for (int jj = 0; jj < lists[ii].length; jj++) {
+ System.out.println(lists[ii][jj] + ", ");
+ }
+ System.out.println("");
+ if (lists[ii].length > 1)
+ candidates++;
+ }
+ System.out.println("Candidates found: " + candidates);
+ return lists;
+ }
+
+ private void optimize(IArtifactDescriptor canonical, IArtifactKey[] relatedArtifactKeys) {
+ System.out.println("Optimizing " + canonical);
+
+ IArtifactDescriptor[] descriptors = getSortedCompletePredecessors(canonical.getArtifactKey(), relatedArtifactKeys);
+
+ int minDepth = Math.min(depth, descriptors.length);
+ for (int i = 0; i < minDepth; i++) {
+ System.out.println("\t with jar delta against " + descriptors[i].getArtifactKey());
+ String predecessorData = ArtifactKeyDeSerializer.serialize(descriptors[i].getArtifactKey());
+ ArtifactDescriptor newDescriptor = new ArtifactDescriptor(canonical);
+ ProcessingStepDescriptor patchStep = new ProcessingStepDescriptor(JAR_DELTA_PATCH_STEP, predecessorData, true);
+ ProcessingStepDescriptor[] steps = new ProcessingStepDescriptor[] {patchStep};
+ newDescriptor.setProcessingSteps(steps);
+ newDescriptor.setProperty(IArtifactDescriptor.FORMAT, JAR_DELTA_FORMAT);
+ OutputStream repositoryStream = null;
+ try {
+ repositoryStream = repository.getOutputStream(newDescriptor);
+
+ // Add in all the processing steps needed to optimize (e.g., pack200, ...)
+ ProcessingStep optimizerStep = new JarDeltaOptimizerStep(repository);
+ optimizerStep.initialize(patchStep, newDescriptor);
+ ProcessingStepHandler handler = new ProcessingStepHandler();
+ OutputStream destination = handler.link(new ProcessingStep[] {optimizerStep}, repositoryStream, null);
+
+ // Do the actual work by asking the repo to get the artifact and put it in the destination.
+ repository.getArtifact(canonical, destination, new NullProgressMonitor());
+ } finally {
+ if (repositoryStream != null)
+ try {
+ repositoryStream.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ private IArtifactDescriptor[] getSortedCompletePredecessors(IArtifactKey artifactKey, IArtifactKey[] relatedArtifactKeys) {
+ // get all artifact keys
+ List completeDescriptors = new ArrayList(relatedArtifactKeys.length);
+ for (int i = 0; i < relatedArtifactKeys.length; i++) {
+ // if we find ´our self´ skip
+ if (relatedArtifactKeys[i].equals(artifactKey))
+ continue;
+ // look for a complete artifact descriptor of the current key
+ IArtifactDescriptor[] descriptors = repository.getArtifactDescriptors(relatedArtifactKeys[i]);
+ for (int j = 0; j < descriptors.length; j++) {
+ if (isCanonical(descriptors[j])) {
+ completeDescriptors.add(descriptors[j]);
+ break;
+ }
+ }
+ }
+
+ IArtifactDescriptor[] completeSortedDescriptors = (IArtifactDescriptor[]) completeDescriptors.toArray(new IArtifactDescriptor[completeDescriptors.size()]);
+ // Sort, so to allow a depth lookup!
+ Arrays.sort(completeSortedDescriptors, ARTIFACT_DESCRIPTOR_VERSION_COMPARATOR);
+ return completeSortedDescriptors;
+ }
+
+ private boolean isOptimized(IArtifactDescriptor descriptor) {
+ if (descriptor.getProcessingSteps().length != 1)
+ return false;
+ return JAR_DELTA_FORMAT.equals(descriptor.getProperty(IArtifactDescriptor.FORMAT));
+ }
+
+ private boolean isCanonical(IArtifactDescriptor descriptor) {
+ // TODO length != 0 is not necessarily an indicator for not being canonical!
+ return descriptor.getProcessingSteps().length == 0;
+ }
+
+ static final class ArtifactDescriptorVersionComparator implements Comparator {
+ public int compare(Object artifactDescriptor0, Object artifactDescriptor1) {
+ return -1 * ((IArtifactDescriptor) artifactDescriptor0).getArtifactKey().getVersion().compareTo(((IArtifactDescriptor) artifactDescriptor1).getArtifactKey().getVersion());
+ }
+ }
+
+ static final class ArtifactKeyVersionComparator implements Comparator {
+ public int compare(Object artifactKey0, Object artifactKey1) {
+ return -1 * ((IArtifactKey) artifactKey0).getVersion().compareTo(((IArtifactKey) artifactKey1).getVersion());
+ }
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/AbstractDeltaDiffStep.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/AbstractDeltaDiffStep.java
index acf6e24b9..0b53dfe8a 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/AbstractDeltaDiffStep.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/AbstractDeltaDiffStep.java
@@ -12,6 +12,7 @@ package org.eclipse.equinox.internal.p2.artifact.optimizers.jbdiff;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.artifact.optimizers.Activator;
import org.eclipse.equinox.p2.artifact.repository.IArtifactDescriptor;
import org.eclipse.equinox.p2.artifact.repository.IArtifactRepository;
import org.eclipse.equinox.p2.artifact.repository.processing.ProcessingStep;
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Application.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Application.java
index dc657e124..1e328d9a1 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Application.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Application.java
@@ -12,6 +12,7 @@ import java.net.URL;
import java.util.Map;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.equinox.internal.p2.artifact.optimizers.Activator;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.p2.artifact.repository.IArtifactRepository;
import org.eclipse.equinox.p2.artifact.repository.IArtifactRepositoryManager;
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Optimizer.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Optimizer.java
index 698346f37..224cc978c 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Optimizer.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/jbdiff/Optimizer.java
@@ -96,7 +96,7 @@ public class Optimizer {
IArtifactDescriptor complete = null;
for (int k = 0; k < descriptors.length; k++) {
IArtifactDescriptor descriptor = descriptors[k];
- if (isComplete(descriptor))
+ if (isCanonical(descriptor))
complete = descriptor;
else if (isOptimized(descriptor, proposedStrategy)) {
proposedStrategy = null;
@@ -219,7 +219,7 @@ public class Optimizer {
// look for a complete artifact descriptor of the current key
IArtifactDescriptor[] descriptors = repository.getArtifactDescriptors(relatedArtifactKeys[i]);
for (int j = 0; j < descriptors.length; j++) {
- if (isComplete(descriptors[j])) {
+ if (isCanonical(descriptors[j])) {
completeDescriptors.add(descriptors[j]);
break;
}
@@ -238,7 +238,7 @@ public class Optimizer {
return stepId.equals(descriptor.getProcessingSteps()[0].getProcessorId());
}
- private boolean isComplete(IArtifactDescriptor descriptor) {
+ private boolean isCanonical(IArtifactDescriptor descriptor) {
// TODO length != 0 is not necessarily an indicator for not being complete!
return descriptor.getProcessingSteps().length == 0;
}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Activator.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Activator.java
deleted file mode 100644
index 91577f88d..000000000
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Activator.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2007 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.artifact.optimizers.pack200;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-public class Activator implements BundleActivator {
- public static final String ID = "org.eclipse.equinox.p2.artifact.optimizer.pack200"; //$NON-NLS-1$
- private static BundleContext context = null;
-
- public static BundleContext getContext() {
- return context;
- }
-
- public void start(BundleContext context) throws Exception {
- Activator.context = context;
- }
-
- public void stop(BundleContext context) throws Exception {
- }
-
-}
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Application.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Application.java
index ae0e7c37f..ed5194076 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Application.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Application.java
@@ -12,6 +12,7 @@ import java.net.URL;
import java.util.Map;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
+import org.eclipse.equinox.internal.p2.artifact.optimizers.Activator;
import org.eclipse.equinox.internal.p2.core.helpers.ServiceHelper;
import org.eclipse.equinox.p2.artifact.repository.IArtifactRepository;
import org.eclipse.equinox.p2.artifact.repository.IArtifactRepositoryManager;
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Optimizer.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Optimizer.java
index a8ab38c40..15501dcc6 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Optimizer.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Optimizer.java
@@ -31,19 +31,24 @@ public class Optimizer {
if (!key.getClassifier().equals("plugin"))
continue;
IArtifactDescriptor[] descriptors = repository.getArtifactDescriptors(key);
- IArtifactDescriptor complete = null;
+ IArtifactDescriptor canonical = null;
boolean optimized = false;
for (int j = 0; j < descriptors.length; j++) {
IArtifactDescriptor descriptor = descriptors[j];
- if (descriptor.getProcessingSteps().length == 0)
- complete = descriptor;
+ if (isCanonical(descriptor))
+ canonical = descriptor;
optimized |= isOptimized(descriptor);
}
if (!optimized)
- optimize(complete);
+ optimize(canonical);
}
}
+ private boolean isCanonical(IArtifactDescriptor descriptor) {
+ // TODO length != 0 is not necessarily an indicator for not being complete!
+ return descriptor.getProcessingSteps().length == 0;
+ }
+
private void optimize(IArtifactDescriptor descriptor) {
ArtifactDescriptor newDescriptor = new ArtifactDescriptor(descriptor);
ProcessingStepDescriptor[] steps = new ProcessingStepDescriptor[] {new ProcessingStepDescriptor("org.eclipse.equinox.p2.processing.Pack200Unpacker", null, true)};
diff --git a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Pack200Step.java b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Pack200Step.java
index 9800352bc..cf11900c1 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Pack200Step.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.optimizers/src/org/eclipse/equinox/internal/p2/artifact/optimizers/pack200/Pack200Step.java
@@ -14,6 +14,7 @@ package org.eclipse.equinox.internal.p2.artifact.optimizers.pack200;
import java.io.*;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.artifact.optimizers.Activator;
import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
import org.eclipse.equinox.p2.artifact.repository.processing.ProcessingStep;
import org.eclipse.equinox.p2.jarprocessor.JarProcessorExecutor;

Back to the top