From a290b822ab4f0ec9c1e5121235564fadf594a74e Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Thu, 14 Jan 2016 16:11:15 -0800 Subject: [PATCH] RefTreeDatabase: Expose bootstrap refs in getAdditionalRefs By showing the bootstrap layer in getAdditionalRefs() garbage collector code can be more RefDatabase agnostic and not care about the special case of RefTree and RefTreeNames for the purposes of building up the roots to GC. Instead they can combine getRefs(ALL) and getAdditionalRefs() and have a clean set of roots. Change-Id: I665cd2456e9316640215b6a08bc728d1356f36d8 --- .../storage/reftree/RefTreeDatabaseTest.java | 11 ++++++ .../storage/dfs/DfsGarbageCollector.java | 14 +++++++- .../jgit/internal/storage/file/GC.java | 9 ++--- .../storage/reftree/RefTreeDatabase.java | 20 ++++++++++- .../storage/reftree/RefTreeNames.java | 35 ------------------- 5 files changed, 48 insertions(+), 41 deletions(-) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java index 020d1b1b5..1bacfe46f 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabaseTest.java @@ -124,6 +124,17 @@ public class RefTreeDatabaseTest { assertTrue("no references", refdb.getRefs(ALL).isEmpty()); assertTrue("no references", refdb.getRefs(R_HEADS).isEmpty()); assertTrue("no references", refdb.getRefs(R_TAGS).isEmpty()); + assertTrue("no references", refdb.getAdditionalRefs().isEmpty()); + } + + @Test + public void testGetAdditionalRefs() throws IOException { + update("refs/heads/master", A); + + List addl = refdb.getAdditionalRefs(); + assertEquals(1, addl.size()); + assertEquals("refs/txn/committed", addl.get(0).getName()); + assertEquals(getTxnCommitted(), addl.get(0).getObjectId()); } @Test diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java index 784507d88..33be3b15a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java @@ -194,7 +194,7 @@ public class DfsGarbageCollector { refdb.refresh(); objdb.clearCache(); - Collection refsBefore = RefTreeNames.allRefs(refdb); + Collection refsBefore = getAllRefs(); packsBefore = packsToRebuild(); if (packsBefore.isEmpty()) return true; @@ -235,6 +235,18 @@ public class DfsGarbageCollector { } } + private Collection getAllRefs() throws IOException { + Collection refs = refdb.getRefs(RefDatabase.ALL).values(); + List addl = refdb.getAdditionalRefs(); + if (!addl.isEmpty()) { + List all = new ArrayList<>(refs.size() + addl.size()); + all.addAll(refs); + all.addAll(addl); + return all; + } + return refs; + } + private List packsToRebuild() throws IOException { DfsPackFile[] packs = objdb.getPacks(); List out = new ArrayList(packs.length); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java index 2ce0d4734..49f9335ae 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java @@ -629,15 +629,16 @@ public class GC { } /** - * Returns a map of all refs and additional refs (e.g. FETCH_HEAD, + * Returns a collection of all refs and additional refs (e.g. FETCH_HEAD, * MERGE_HEAD, ...) * - * @return a map where names of refs point to ref objects + * @return a collection of refs pointing to live objects. * @throws IOException */ private Collection getAllRefs() throws IOException { - Collection refs = RefTreeNames.allRefs(repo.getRefDatabase()); - List addl = repo.getRefDatabase().getAdditionalRefs(); + RefDatabase refdb = repo.getRefDatabase(); + Collection refs = refdb.getRefs(RefDatabase.ALL).values(); + List addl = refdb.getAdditionalRefs(); if (!addl.isEmpty()) { List all = new ArrayList<>(refs.size() + addl.size()); all.addAll(refs); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabase.java index dc6031110..f6fdef1fa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabase.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeDatabase.java @@ -47,6 +47,8 @@ import static org.eclipse.jgit.lib.Ref.Storage.LOOSE; import static org.eclipse.jgit.lib.Ref.Storage.PACKED; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -250,7 +252,23 @@ public class RefTreeDatabase extends RefDatabase { @Override public List getAdditionalRefs() throws IOException { - return Collections.emptyList(); + Collection txnRefs; + if (txnNamespace != null) { + txnRefs = bootstrap.getRefs(txnNamespace).values(); + } else { + Ref r = bootstrap.exactRef(txnCommitted); + if (r != null && r.getObjectId() != null) { + txnRefs = Collections.singleton(r); + } else { + txnRefs = Collections.emptyList(); + } + } + + List otherRefs = bootstrap.getAdditionalRefs(); + List all = new ArrayList<>(txnRefs.size() + otherRefs.size()); + all.addAll(txnRefs); + all.addAll(otherRefs); + return all; } @Override diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeNames.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeNames.java index 239a74527..c53d6deb2 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeNames.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/reftree/RefTreeNames.java @@ -43,14 +43,6 @@ package org.eclipse.jgit.internal.storage.reftree; -import static org.eclipse.jgit.lib.RefDatabase.ALL; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.RefDatabase; /** Magic reference name logic for RefTrees. */ @@ -92,33 +84,6 @@ public class RefTreeNames { return false; } - /** - * Snapshot all references from a RefTreeDatabase and its bootstrap. - *

- * There may be name conflicts with multiple {@link Ref} objects containing - * the same name in the returned collection. - * - * @param refdb - * database instance. - * @return all known references. - * @throws IOException - * references cannot be enumerated. - */ - public static Collection allRefs(RefDatabase refdb) - throws IOException { - Collection refs = refdb.getRefs(ALL).values(); - if (!(refdb instanceof RefTreeDatabase)) { - return refs; - } - - RefDatabase bootstrap = ((RefTreeDatabase) refdb).getBootstrap(); - Collection br = bootstrap.getRefs(ALL).values(); - List all = new ArrayList<>(refs.size() + br.size()); - all.addAll(refs); - all.addAll(br); - return all; - } - private RefTreeNames() { } }