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(); }