### Eclipse Workspace Patch 1.0 #P org.eclipse.equinox.p2.garbagecollector Index: META-INF/MANIFEST.MF =================================================================== RCS file: /cvsroot/rt/org.eclipse.equinox/p2/bundles/org.eclipse.equinox.p2.garbagecollector/META-INF/MANIFEST.MF,v retrieving revision 1.11 diff -u -r1.11 MANIFEST.MF --- META-INF/MANIFEST.MF 17 Jul 2008 19:39:39 -0000 1.11 +++ META-INF/MANIFEST.MF 16 Apr 2009 19:50:49 -0000 @@ -12,7 +12,9 @@ org.eclipse.equinox.internal.provisional.p2.core, org.eclipse.equinox.internal.provisional.p2.core.eventbus, org.eclipse.equinox.internal.provisional.p2.metadata, + org.eclipse.equinox.internal.provisional.p2.metadata.query, org.eclipse.equinox.internal.provisional.p2.metadata.repository, + org.eclipse.equinox.internal.provisional.p2.query, org.eclipse.osgi.util;version="1.1.0", org.osgi.framework;version="1.4.0", org.osgi.service.prefs;version="1.1.0", Index: src/org/eclipse/equinox/internal/p2/garbagecollector/GCActivator.java =================================================================== RCS file: /cvsroot/rt/org.eclipse.equinox/p2/bundles/org.eclipse.equinox.p2.garbagecollector/src/org/eclipse/equinox/internal/p2/garbagecollector/GCActivator.java,v retrieving revision 1.8 diff -u -r1.8 GCActivator.java --- src/org/eclipse/equinox/internal/p2/garbagecollector/GCActivator.java 10 Mar 2009 19:03:35 -0000 1.8 +++ src/org/eclipse/equinox/internal/p2/garbagecollector/GCActivator.java 16 Apr 2009 19:50:49 -0000 @@ -18,6 +18,8 @@ import org.eclipse.equinox.internal.provisional.p2.core.eventbus.IProvisioningEventBus; import org.eclipse.equinox.internal.provisional.p2.core.eventbus.SynchronousProvisioningListener; import org.eclipse.equinox.internal.provisional.p2.engine.*; +import org.eclipse.equinox.internal.provisional.p2.metadata.query.InstallableUnitQuery; +import org.eclipse.equinox.internal.provisional.p2.query.Collector; import org.eclipse.osgi.service.debug.DebugOptions; import org.osgi.framework.*; import org.osgi.service.prefs.Preferences; @@ -58,25 +60,37 @@ return; } eventBus.addListener(busListener = new SynchronousProvisioningListener() { - //The GC is triggered when an uninstall event occurred during a "transaction" and the transaction is committed. - private boolean uninstallEventOccurred = false; + + private Map activeProfiles = Collections.synchronizedMap(new HashMap()); public void notify(EventObject o) { - if (o instanceof InstallableUnitEvent) { - InstallableUnitEvent event = (InstallableUnitEvent) o; - if (event.isUninstall() && event.isPost()) { - uninstallEventOccurred = true; - } - } else if (o instanceof CommitOperationEvent) { - if (uninstallEventOccurred == true) { - CommitOperationEvent event = (CommitOperationEvent) o; - if (getBooleanPreference(GC_ENABLED, true)) { - new GarbageCollector().runGC(event.getProfile()); - } - uninstallEventOccurred = false; - } - } else if (o instanceof RollbackOperationEvent) { - uninstallEventOccurred = false; + // Return if the event isn't a TransactionEvent + if (!(o instanceof TransactionEvent)) + return; + // Return if garbage collection is disabled + if (!getBooleanPreference(GC_ENABLED, true)) + return; + + TransactionEvent event = (TransactionEvent) o; + IProfile profile = event.getProfile(); + + if (profile == null) + return; + + if (event instanceof RollbackOperationEvent) + // Transaction rolled back, profile data can be removed + activeProfiles.remove(profile.getProfileId()); + else if (event instanceof BeginOperationEvent) { + // Store a collection of IUs present in the profile at the start of the Transaction + Collection profileIUs = profile.query(InstallableUnitQuery.ANY, new Collector(), null).toCollection(); + activeProfiles.put(profile.getProfileId(), profileIUs); + } else if (event instanceof CommitOperationEvent) { + // Retrieve collection of IUs present in the profile at the end of the Transaction + Collection profileIUs = profile.query(InstallableUnitQuery.ANY, new Collector(), null).toCollection(); + Collection previousIUs = (Collection) activeProfiles.remove(profile.getProfileId()); + // Run GC if IUs were present in the profile before, but are now missing from the profile + if (previousIUs != null && !profileIUs.containsAll(previousIUs)) + new GarbageCollector().runGC(event.getProfile()); } } });