From ccb43b891eaca9bc07e118a2112abf18626531b5 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Mon, 11 Aug 2008 18:08:12 -0700 Subject: [PATCH] Rewrite UntrackOperation to use DirCacheBuilder We can more efficiently untrack single files and entire directories using the DirCacheBuilder API as that API is able to perform range edits on the index data structure. Its also able to perform faster disk IO, due to less conversion overheads. Although performance of untrack is not a critical feature it is a good idea to move it over to the newer API, as we will eventually get rid of the GitIndex class entirely. Signed-off-by: Shawn O. Pearce Signed-off-by: Robin Rosenberg --- .../org/spearce/egit/core/op/UntrackOperation.java | 98 ++++++++++++---------- 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/op/UntrackOperation.java b/org.spearce.egit.core/src/org/spearce/egit/core/op/UntrackOperation.java index b491e6d8..46565523 100644 --- a/org.spearce.egit.core/src/org/spearce/egit/core/op/UntrackOperation.java +++ b/org.spearce.egit.core/src/org/spearce/egit/core/op/UntrackOperation.java @@ -1,6 +1,7 @@ /******************************************************************************* * Copyright (C) 2007, Robin Rosenberg * Copyright (C) 2008, Shawn O. Pearce + * 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 @@ -8,15 +9,14 @@ *******************************************************************************/ package org.spearce.egit.core.op; -import java.io.File; 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; @@ -26,7 +26,9 @@ 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.dircache.DirCache; +import org.spearce.jgit.dircache.DirCacheEditor; +import org.spearce.jgit.lib.Repository; /** * Remove one or more existing files/folders from the Git repository. @@ -43,6 +45,10 @@ import org.spearce.jgit.lib.GitIndex; public class UntrackOperation implements IWorkspaceRunnable { private final Collection rsrcList; + private final IdentityHashMap edits; + + private final IdentityHashMap mappings; + /** * Create a new operation to stop tracking existing files/folders. * @@ -52,63 +58,69 @@ public class UntrackOperation implements IWorkspaceRunnable { */ public UntrackOperation(final Collection rsrcs) { rsrcList = rsrcs; + edits = new IdentityHashMap(); + mappings = new IdentityHashMap(); } public void run(IProgressMonitor m) throws CoreException { - if (m == null) { + if (m == null) m = new NullProgressMonitor(); - } - final IdentityHashMap tomerge = new IdentityHashMap(); + edits.clear(); + mappings.clear(); + m.beginTask(CoreText.AddOperation_adding, rsrcList.size() * 200); try { for (Object obj : rsrcList) { - obj = ((IAdaptable)obj).getAdapter(IResource.class); - if (obj instanceof IResource) { - final IResource toRemove = (IResource)obj; - final GitProjectData pd = GitProjectData.get(toRemove.getProject()); - final RepositoryMapping rm = pd.getRepositoryMapping(toRemove); - final GitIndex index = rm.getRepository().getIndex(); - tomerge.put(rm, Boolean.TRUE); - if (toRemove instanceof IContainer) { - ((IContainer)toRemove).accept(new IResourceVisitor() { - public boolean visit(IResource resource) throws CoreException { - if (resource.getType() == IResource.FILE) { - index.remove(rm.getWorkDir(), new File(rm.getWorkDir(),rm.getRepoRelativePath(resource))); - } - return true; - } - },IResource.DEPTH_INFINITE, IContainer.EXCLUDE_DERIVED); - } else { - index.remove(rm.getWorkDir(), new File(rm.getWorkDir(),rm.getRepoRelativePath(toRemove))); - } - } + obj = ((IAdaptable) obj).getAdapter(IResource.class); + if (obj instanceof IResource) + remove((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 e : edits.entrySet()) { + final Repository db = e.getKey(); + final DirCacheEditor editor = e.getValue(); + m.setTaskName("Writing index for " + db.getDirectory()); + editor.commit(); } } catch (RuntimeException e) { - e.printStackTrace(); throw Activator.error(CoreText.UntrackOperation_failed, e); } catch (IOException e) { - e.printStackTrace(); throw Activator.error(CoreText.UntrackOperation_failed, e); } finally { + for (final RepositoryMapping rm : mappings.keySet()) + rm.fireRepositoryChanged(); + edits.clear(); + mappings.clear(); + m.done(); + } + } + + private void remove(final IResource path) throws CoreException { + final IProject proj = path.getProject(); + final GitProjectData pd = GitProjectData.get(proj); + if (pd == null) + return; + final RepositoryMapping rm = pd.getRepositoryMapping(path); + if (rm == null) + return; + final Repository db = rm.getRepository(); + + DirCacheEditor e = edits.get(db); + if (e == 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(); + e = DirCache.lock(db).editor(); + } catch (IOException err) { + throw Activator.error(CoreText.UntrackOperation_failed, err); } + edits.put(db, e); + mappings.put(rm, rm); } - } + if (path instanceof IContainer) + e.add(new DirCacheEditor.DeleteTree(rm.getRepoRelativePath(path))); + else + e.add(new DirCacheEditor.DeletePath(rm.getRepoRelativePath(path))); + } } -- 2.11.4.GIT