Update CachedObjectDirectory when inserting objects

If an ObjectInserter is created from a CachedObjectDirectory, we need
to ensure the cache is updated whenever a new loose object is actually
added to the loose objects directory, otherwise a future read from an
ObjectReader on the CachedObjectDirectory might not be able to open
the newly created object.

We mostly had the infrastructure in place to implement this due to the
injection of unpacked large deltas, but we didn't have a way to pass
the ObjectId from ObjectDirectoryInserter to CachedObjectDirectory,
because the inserter was using the underlying ObjectDirectory and not
the CachedObjectDirectory.  Redirecting to CachedObjectDirectory
ensures the cache is updated.

Change-Id: I1f7bdfacc7ad77ebdb885f655e549cc570652225
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java
index 9bad71d..9e137be 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/CachedObjectDirectory.java
@@ -50,6 +50,7 @@
 
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectDatabase;
 import org.eclipse.jgit.lib.ObjectId;
@@ -112,11 +113,6 @@ public void close() {
 	}
 
 	@Override
-	public ObjectDirectoryInserter newInserter() {
-		return wrapped.newInserter();
-	}
-
-	@Override
 	public ObjectDatabase newCachedDatabase() {
 		return this;
 	}
@@ -132,6 +128,11 @@ File getDirectory() {
 	}
 
 	@Override
+	Config getConfig() {
+		return wrapped.getConfig();
+	}
+
+	@Override
 	AlternateHandle[] myAlternates() {
 		if (alts == null) {
 			AlternateHandle[] src = wrapped.myAlternates();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java
index 8bd3751..4e9f5e9 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/FileObjectDatabase.java
@@ -49,6 +49,7 @@
 
 import org.eclipse.jgit.lib.AbbreviatedObjectId;
 import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.ObjectDatabase;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectLoader;
@@ -67,7 +68,9 @@ public ObjectReader newReader() {
 	}
 
 	@Override
-	public abstract ObjectDirectoryInserter newInserter();
+	public ObjectDirectoryInserter newInserter() {
+		return new ObjectDirectoryInserter(this, getConfig());
+	}
 
 	/**
 	 * Does the requested object exist in this database?
@@ -83,6 +86,23 @@ public boolean has(final AnyObjectId objectId) {
 		return hasObjectImpl1(objectId) || hasObjectImpl2(objectId.name());
 	}
 
+	/**
+	 * Compute the location of a loose object file.
+	 *
+	 * @param objectId
+	 *            identity of the loose object to map to the directory.
+	 * @return location of the object, if it were to exist as a loose object.
+	 */
+	File fileFor(final AnyObjectId objectId) {
+		return fileFor(objectId.name());
+	}
+
+	File fileFor(final String objectName) {
+		final String d = objectName.substring(0, 2);
+		final String f = objectName.substring(2);
+		return new File(new File(getDirectory(), d), f);
+	}
+
 	final boolean hasObjectImpl1(final AnyObjectId objectId) {
 		if (hasObject1(objectId))
 			return true;
@@ -110,6 +130,8 @@ final boolean hasObjectImpl2(final String objectId) {
 	abstract void resolve(Set<ObjectId> matches, AbbreviatedObjectId id)
 			throws IOException;
 
+	abstract Config getConfig();
+
 	/**
 	 * Open an object from this database.
 	 * <p>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
index e7ccba0..86e19f4 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectory.java
@@ -204,14 +204,9 @@ public void close() {
 	 *            identity of the loose object to map to the directory.
 	 * @return location of the object, if it were to exist as a loose object.
 	 */
+	@Override
 	public File fileFor(final AnyObjectId objectId) {
-		return fileFor(objectId.name());
-	}
-
-	private File fileFor(final String objectName) {
-		final String d = objectName.substring(0, 2);
-		final String f = objectName.substring(2);
-		return new File(new File(objects, d), f);
+		return super.fileFor(objectId);
 	}
 
 	/**
@@ -515,6 +510,10 @@ boolean tryAgain1() {
 		return false;
 	}
 
+	Config getConfig() {
+		return config;
+	}
+
 	private void insertPack(final PackFile pf) {
 		PackList o, n;
 		do {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java
index 074ebb9..16cb8aa 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/ObjectDirectoryInserter.java
@@ -66,13 +66,13 @@
 
 /** Creates loose objects in a {@link ObjectDirectory}. */
 class ObjectDirectoryInserter extends ObjectInserter {
-	private final ObjectDirectory db;
+	private final FileObjectDatabase db;
 
 	private final Config config;
 
 	private Deflater deflate;
 
-	ObjectDirectoryInserter(final ObjectDirectory dest, final Config cfg) {
+	ObjectDirectoryInserter(final FileObjectDatabase dest, final Config cfg) {
 		db = dest;
 		config = cfg;
 	}