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: I665cd2456e9316640215b6a08bc728d1356f36d8changes/15/64415/1
assertTrue("no references", refdb.getRefs(ALL).isEmpty()); | assertTrue("no references", refdb.getRefs(ALL).isEmpty()); | ||||
assertTrue("no references", refdb.getRefs(R_HEADS).isEmpty()); | assertTrue("no references", refdb.getRefs(R_HEADS).isEmpty()); | ||||
assertTrue("no references", refdb.getRefs(R_TAGS).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<Ref> addl = refdb.getAdditionalRefs(); | |||||
assertEquals(1, addl.size()); | |||||
assertEquals("refs/txn/committed", addl.get(0).getName()); | |||||
assertEquals(getTxnCommitted(), addl.get(0).getObjectId()); | |||||
} | } | ||||
@Test | @Test |
refdb.refresh(); | refdb.refresh(); | ||||
objdb.clearCache(); | objdb.clearCache(); | ||||
Collection<Ref> refsBefore = RefTreeNames.allRefs(refdb); | |||||
Collection<Ref> refsBefore = getAllRefs(); | |||||
packsBefore = packsToRebuild(); | packsBefore = packsToRebuild(); | ||||
if (packsBefore.isEmpty()) | if (packsBefore.isEmpty()) | ||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
private Collection<Ref> getAllRefs() throws IOException { | |||||
Collection<Ref> refs = refdb.getRefs(RefDatabase.ALL).values(); | |||||
List<Ref> addl = refdb.getAdditionalRefs(); | |||||
if (!addl.isEmpty()) { | |||||
List<Ref> all = new ArrayList<>(refs.size() + addl.size()); | |||||
all.addAll(refs); | |||||
all.addAll(addl); | |||||
return all; | |||||
} | |||||
return refs; | |||||
} | |||||
private List<DfsPackFile> packsToRebuild() throws IOException { | private List<DfsPackFile> packsToRebuild() throws IOException { | ||||
DfsPackFile[] packs = objdb.getPacks(); | DfsPackFile[] packs = objdb.getPacks(); | ||||
List<DfsPackFile> out = new ArrayList<DfsPackFile>(packs.length); | List<DfsPackFile> out = new ArrayList<DfsPackFile>(packs.length); |
} | } | ||||
/** | /** | ||||
* 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, ...) | * MERGE_HEAD, ...) | ||||
* | * | ||||
* @return a map where names of refs point to ref objects | |||||
* @return a collection of refs pointing to live objects. | |||||
* @throws IOException | * @throws IOException | ||||
*/ | */ | ||||
private Collection<Ref> getAllRefs() throws IOException { | private Collection<Ref> getAllRefs() throws IOException { | ||||
Collection<Ref> refs = RefTreeNames.allRefs(repo.getRefDatabase()); | |||||
List<Ref> addl = repo.getRefDatabase().getAdditionalRefs(); | |||||
RefDatabase refdb = repo.getRefDatabase(); | |||||
Collection<Ref> refs = refdb.getRefs(RefDatabase.ALL).values(); | |||||
List<Ref> addl = refdb.getAdditionalRefs(); | |||||
if (!addl.isEmpty()) { | if (!addl.isEmpty()) { | ||||
List<Ref> all = new ArrayList<>(refs.size() + addl.size()); | List<Ref> all = new ArrayList<>(refs.size() + addl.size()); | ||||
all.addAll(refs); | all.addAll(refs); |
import static org.eclipse.jgit.lib.Ref.Storage.PACKED; | import static org.eclipse.jgit.lib.Ref.Storage.PACKED; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.ArrayList; | |||||
import java.util.Collection; | |||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.HashMap; | import java.util.HashMap; | ||||
import java.util.List; | import java.util.List; | ||||
@Override | @Override | ||||
public List<Ref> getAdditionalRefs() throws IOException { | public List<Ref> getAdditionalRefs() throws IOException { | ||||
return Collections.emptyList(); | |||||
Collection<Ref> 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<Ref> otherRefs = bootstrap.getAdditionalRefs(); | |||||
List<Ref> all = new ArrayList<>(txnRefs.size() + otherRefs.size()); | |||||
all.addAll(txnRefs); | |||||
all.addAll(otherRefs); | |||||
return all; | |||||
} | } | ||||
@Override | @Override |
package org.eclipse.jgit.internal.storage.reftree; | 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; | import org.eclipse.jgit.lib.RefDatabase; | ||||
/** Magic reference name logic for RefTrees. */ | /** Magic reference name logic for RefTrees. */ | ||||
return false; | return false; | ||||
} | } | ||||
/** | |||||
* Snapshot all references from a RefTreeDatabase and its bootstrap. | |||||
* <p> | |||||
* 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<Ref> allRefs(RefDatabase refdb) | |||||
throws IOException { | |||||
Collection<Ref> refs = refdb.getRefs(ALL).values(); | |||||
if (!(refdb instanceof RefTreeDatabase)) { | |||||
return refs; | |||||
} | |||||
RefDatabase bootstrap = ((RefTreeDatabase) refdb).getBootstrap(); | |||||
Collection<Ref> br = bootstrap.getRefs(ALL).values(); | |||||
List<Ref> all = new ArrayList<>(refs.size() + br.size()); | |||||
all.addAll(refs); | |||||
all.addAll(br); | |||||
return all; | |||||
} | |||||
private RefTreeNames() { | private RefTreeNames() { | ||||
} | } | ||||
} | } |