Merge "DfsInserter: Reuse ObjectReader when checking for existing objects"
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
index efa98de..4590e4a 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/dfs/DfsInserterTest.java
@@ -313,6 +313,44 @@ public void testObjectSizeIndexOnInsert() throws IOException {
 				insertPack.findIdxPosition(reader, fooId)));
 	}
 
+	@Test
+	public void testInserterReusesReader() throws IOException {
+		int[] newReaderCalls = new int[1];
+		int[] closeReaderCalls = new int[1];
+		try (InMemoryRepository repo = new InMemoryRepository(
+				new DfsRepositoryDescription("test")) {
+			private final MemObjDatabase odb = new MemObjDatabase(this) {
+				@Override
+				public DfsReader newReader() {
+					newReaderCalls[0]++;
+					return new DfsReader(this) {
+						@Override
+						public void close() {
+							closeReaderCalls[0]++;
+							super.close();
+						}
+					};
+				}
+			};
+
+			@Override
+			public MemObjDatabase getObjectDatabase() {
+				return odb;
+			}
+		}) {
+			try (ObjectInserter ins = repo.newObjectInserter()) {
+				ins.insert(Constants.OBJ_BLOB, Constants.encode("foo"));
+				ins.insert(Constants.OBJ_BLOB, Constants.encode("bar"));
+				ins.insert(Constants.OBJ_BLOB, Constants.encode("baz"));
+				ins.flush();
+				assertEquals(1, newReaderCalls[0]);
+				assertEquals(0, closeReaderCalls[0]);
+			}
+			assertEquals(1, newReaderCalls[0]);
+			assertEquals(1, closeReaderCalls[0]);
+		}
+	}
+
 	private static String readString(ObjectLoader loader) throws IOException {
 		return RawParseUtils.decode(readStream(loader));
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
index dd9e4b9..e929115 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsInserter.java
@@ -84,6 +84,8 @@ public class DfsInserter extends ObjectInserter {
 	PackStream packOut;
 	private boolean rollback;
 
+	private ObjectReader reader;
+
 	/**
 	 * Initialize a new inserter.
 	 *
@@ -117,7 +119,7 @@ public ObjectId insert(int type, byte[] data, int off, int len)
 		if (objectMap != null && objectMap.contains(id))
 			return id;
 		// Ignore unreachable (garbage) objects here.
-		if (db.has(id, true)) {
+		if (has(id)) {
 			return id;
 		}
 
@@ -127,6 +129,14 @@ public ObjectId insert(int type, byte[] data, int off, int len)
 		return endObject(id, offset, len, type);
 	}
 
+	private boolean has(AnyObjectId id) throws IOException {
+		if (reader == null) {
+			reader = db.newReader();
+			reader.setAvoidUnreachableObjects(true);
+		}
+		return reader.has(id);
+	}
+
 	@Override
 	public ObjectId insert(int type, long len, InputStream in)
 			throws IOException {
@@ -217,6 +227,13 @@ public void close() {
 				rollback = false;
 			}
 		}
+		if (reader != null) {
+			try {
+				reader.close();
+			} finally {
+				reader = null;
+			}
+		}
 		clear();
 	}