From 0d6ba84065b3281d2e3c3cf8251b7679cbc83488 Mon Sep 17 00:00:00 2001 From: Dave Borowitz Date: Wed, 1 Jun 2016 17:07:19 -0400 Subject: [PATCH] DfsInserter: Optionally disable existing object check When using a DfsInserter for high-throughput insertion of many objects (analogous to git-fast-import), we don't necessarily want to do a random object lookup for each. It'll be faster from the inserter's perspective to insert the duplicate objects and let a later GC handle the deduplication. Change-Id: Ic97f5f01657b4525f157e6df66023f1f07fc1851 --- .../internal/storage/dfs/DfsInserterTest.java | 31 +++++++++++++++++++ .../internal/storage/dfs/DfsInserter.java | 12 ++++++- 2 files changed, 42 insertions(+), 1 deletion(-) 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 74790f72c5..b738f7ea74 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 @@ -219,6 +219,37 @@ public class DfsInserterTest { assertTrue(pack_sources.contains(PackSource.INSERT)); } + @Test + public void testNoCheckExisting() throws IOException { + byte[] contents = Constants.encode("foo"); + ObjectId fooId; + try (ObjectInserter ins = db.newObjectInserter()) { + fooId = ins.insert(Constants.OBJ_BLOB, contents); + ins.flush(); + } + assertEquals(1, db.getObjectDatabase().listPacks().size()); + + try (ObjectInserter ins = db.newObjectInserter()) { + ((DfsInserter) ins).checkExisting(false); + assertEquals(fooId, ins.insert(Constants.OBJ_BLOB, contents)); + ins.flush(); + } + assertEquals(2, db.getObjectDatabase().listPacks().size()); + + // Verify that we have a foo in both INSERT packs. + DfsReader reader = new DfsReader(db.getObjectDatabase()); + DfsPackFile packs[] = db.getObjectDatabase().getPacks(); + + assertEquals(2, packs.length); + DfsPackFile p1 = packs[0]; + assertEquals(PackSource.INSERT, p1.getPackDescription().getPackSource()); + assertTrue(p1.hasObject(reader, fooId)); + + DfsPackFile p2 = packs[1]; + assertEquals(PackSource.INSERT, p2.getPackDescription().getPackSource()); + assertTrue(p2.hasObject(reader, fooId)); + } + 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 f5673e83d1..3e8deac0f0 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 @@ -106,6 +106,7 @@ public class DfsInserter extends ObjectInserter { DfsPackDescription packDsc; PackStream packOut; private boolean rollback; + private boolean checkExisting = true; /** * Initialize a new inserter. @@ -117,6 +118,15 @@ public class DfsInserter extends ObjectInserter { this.db = db; } + /** + * @param check + * if false, will write out possibly-duplicate objects without + * first checking whether they exist in the repo; default is true. + */ + public void checkExisting(boolean check) { + checkExisting = check; + } + void setCompressionLevel(int compression) { this.compression = compression; } @@ -138,7 +148,7 @@ public class DfsInserter extends ObjectInserter { if (objectMap != null && objectMap.contains(id)) return id; // Ignore unreachable (garbage) objects here. - if (db.has(id, true)) + if (checkExisting && db.has(id, true)) return id; long offset = beginObject(type, len); -- 2.39.5