Its faster to use the DirCache and run over the range of entries than to use GitIndex and probe the hash many times as we are in a loop over the resources in the workspace. Signed-off-by: Shawn O. Pearce <spearce@xxxxxxxxxxx> --- .../egit/core/op/AssumeUnchangedOperation.java | 133 ++++++++++---------- 1 files changed, 69 insertions(+), 64 deletions(-) diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/op/AssumeUnchangedOperation.java b/org.spearce.egit.core/src/org/spearce/egit/core/op/AssumeUnchangedOperation.java index 78a84bb..fa70b6c 100644 --- a/org.spearce.egit.core/src/org/spearce/egit/core/op/AssumeUnchangedOperation.java +++ b/org.spearce.egit.core/src/org/spearce/egit/core/op/AssumeUnchangedOperation.java @@ -1,6 +1,7 @@ /******************************************************************************* * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@xxxxxxxxxx> * Copyright (C) 2008, Shawn O. Pearce <spearce@xxxxxxxxxxx> + * Copyright (C) 2008, Google Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -11,11 +12,11 @@ package org.spearce.egit.core.op; import java.io.IOException; import java.util.Collection; import java.util.IdentityHashMap; -import java.util.Iterator; +import java.util.Map; import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; @@ -23,9 +24,11 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.spearce.egit.core.Activator; import org.spearce.egit.core.CoreText; +import org.spearce.egit.core.project.GitProjectData; import org.spearce.egit.core.project.RepositoryMapping; -import org.spearce.jgit.lib.GitIndex; -import org.spearce.jgit.lib.GitIndex.Entry; +import org.spearce.jgit.dircache.DirCache; +import org.spearce.jgit.dircache.DirCacheEntry; +import org.spearce.jgit.lib.Repository; /** * Tell JGit to ignore changes in selected files @@ -33,87 +36,89 @@ import org.spearce.jgit.lib.GitIndex.Entry; public class AssumeUnchangedOperation implements IWorkspaceRunnable { private final Collection rsrcList; + private final IdentityHashMap<Repository, DirCache> caches; + + private final IdentityHashMap<RepositoryMapping, Object> mappings; + /** * Create a new operation to ignore changes in tracked files - * + * * @param rsrcs - * collection of {@link IResource}s which should be - * ignored when looking for changes or committing. + * collection of {@link IResource}s which should be ignored when + * looking for changes or committing. */ public AssumeUnchangedOperation(final Collection rsrcs) { rsrcList = rsrcs; + caches = new IdentityHashMap<Repository, DirCache>(); + mappings = new IdentityHashMap<RepositoryMapping, Object>(); } public void run(IProgressMonitor m) throws CoreException { - if (m == null) { + if (m == null) m = new NullProgressMonitor(); - } - final IdentityHashMap<RepositoryMapping, Boolean> tomerge = new IdentityHashMap<RepositoryMapping, Boolean>(); - m.beginTask(CoreText.AssumeUnchangedOperation_adding, rsrcList.size() * 200); + caches.clear(); + mappings.clear(); + + m.beginTask(CoreText.AssumeUnchangedOperation_adding, + rsrcList.size() * 200); try { for (Object obj : rsrcList) { - obj = ((IAdaptable)obj).getAdapter(IResource.class); - if (obj instanceof IResource) { - final IResource toAssumeValid = (IResource)obj; - final RepositoryMapping rm = RepositoryMapping.getMapping(toAssumeValid); - final GitIndex index = rm.getRepository().getIndex(); - - if (toAssumeValid instanceof IContainer) { - ((IContainer)toAssumeValid).accept(new IResourceVisitor() { - public boolean visit(IResource resource) throws CoreException { - try { - String repoPath = rm.getRepoRelativePath(resource); - Entry entry = index.getEntry(repoPath); - if (entry != null) { - if (!entry.isAssumedValid()) { - entry.setAssumeValid(true); - tomerge.put(rm, Boolean.TRUE); - } - } - } catch (IOException e) { - e.printStackTrace(); - throw Activator.error(CoreText.AssumeUnchangedOperation_failed, e); - } - return true; - } - },IResource.DEPTH_INFINITE, IContainer.EXCLUDE_DERIVED); - } else { - String repoPath = rm.getRepoRelativePath((IResource) obj); - Entry entry = index.getEntry(repoPath); - if (entry != null) { - if (!entry.isAssumedValid()) { - entry.setAssumeValid(true); - tomerge.put(rm, Boolean.TRUE); - } - } - } - } + obj = ((IAdaptable) obj).getAdapter(IResource.class); + if (obj instanceof IResource) + assumeValid((IResource) obj); m.worked(200); } - for (RepositoryMapping rm : tomerge.keySet()) { - m.setTaskName("Writing index for "+rm.getRepository().getDirectory()); - rm.getRepository().getIndex().write(); + + for (Map.Entry<Repository, DirCache> e : caches.entrySet()) { + final Repository db = e.getKey(); + final DirCache editor = e.getValue(); + m.setTaskName("Writing index for " + db.getDirectory()); + editor.write(); + editor.commit(); } } catch (RuntimeException e) { - e.printStackTrace(); - throw Activator.error(CoreText.AssumeUnchangedOperation_failed, e); + throw Activator.error(CoreText.UntrackOperation_failed, e); } catch (IOException e) { - e.printStackTrace(); - throw Activator.error(CoreText.AssumeUnchangedOperation_failed, e); + throw Activator.error(CoreText.UntrackOperation_failed, e); } finally { + for (final RepositoryMapping rm : mappings.keySet()) + rm.fireRepositoryChanged(); + caches.clear(); + mappings.clear(); + m.done(); + } + } + + private void assumeValid(final IResource resource) throws CoreException { + final IProject proj = resource.getProject(); + final GitProjectData pd = GitProjectData.get(proj); + if (pd == null) + return; + final RepositoryMapping rm = pd.getRepositoryMapping(resource); + if (rm == null) + return; + final Repository db = rm.getRepository(); + + DirCache cache = caches.get(db); + if (cache == null) { try { - final Iterator i = tomerge.keySet().iterator(); - while (i.hasNext()) { - final RepositoryMapping r = (RepositoryMapping) i.next(); - r.getRepository().getIndex().read(); - r.fireRepositoryChanged(); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - m.done(); + cache = DirCache.lock(db); + } catch (IOException err) { + throw Activator.error(CoreText.UntrackOperation_failed, err); } + caches.put(db, cache); + mappings.put(rm, rm); + } + + final String path = rm.getRepoRelativePath(resource); + if (resource instanceof IContainer) { + for (final DirCacheEntry ent : cache.getEntriesWithin(path)) + ent.setAssumeValid(true); + } else { + final DirCacheEntry ent = cache.getEntry(path); + if (ent != null) + ent.setAssumeValid(true); } } } -- 1.6.0.rc2.22.g71b99 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html