[EGIT PATCH 26/26] Rewrite AssumeUnchangedOperation to use DirCache

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux