Browse Source

Merge "PackWriter: Declare preparePack object sets as @NonNull"

tags/v4.2.0.201601211800-r
Shawn Pearce 8 years ago
parent
commit
95bdc589b8

+ 1
- 1
org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java View File

Set<ObjectId> all = new HashSet<ObjectId>(); Set<ObjectId> all = new HashSet<ObjectId>();
for (Ref r : db.getAllRefs().values()) for (Ref r : db.getAllRefs().values())
all.add(r.getObjectId()); all.add(r.getObjectId());
pw.preparePack(m, all, Collections.<ObjectId> emptySet());
pw.preparePack(m, all, PackWriter.NONE);


final ObjectId name = pw.computeName(); final ObjectId name = pw.computeName();



+ 10
- 13
org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackWriterTest.java View File

import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.eclipse.jgit.internal.storage.pack.PackWriter.NONE;


import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;


public class PackWriterTest extends SampleDataRepositoryTestCase { public class PackWriterTest extends SampleDataRepositoryTestCase {


private static final Set<ObjectId> EMPTY_SET_OBJECT = Collections
.<ObjectId> emptySet();

private static final List<RevObject> EMPTY_LIST_REVS = Collections private static final List<RevObject> EMPTY_LIST_REVS = Collections
.<RevObject> emptyList(); .<RevObject> emptyList();


*/ */
@Test @Test
public void testWriteEmptyPack1() throws IOException { public void testWriteEmptyPack1() throws IOException {
createVerifyOpenPack(EMPTY_SET_OBJECT, EMPTY_SET_OBJECT, false, false);
createVerifyOpenPack(NONE, NONE, false, false);


assertEquals(0, writer.getObjectCount()); assertEquals(0, writer.getObjectCount());
assertEquals(0, pack.getObjectCount()); assertEquals(0, pack.getObjectCount());
final ObjectId nonExisting = ObjectId final ObjectId nonExisting = ObjectId
.fromString("0000000000000000000000000000000000000001"); .fromString("0000000000000000000000000000000000000001");
try { try {
createVerifyOpenPack(EMPTY_SET_OBJECT, Collections.singleton(
nonExisting), false, false);
createVerifyOpenPack(NONE, Collections.singleton(nonExisting),
false, false);
fail("Should have thrown MissingObjectException"); fail("Should have thrown MissingObjectException");
} catch (MissingObjectException x) { } catch (MissingObjectException x) {
// expected // expected
public void testIgnoreNonExistingObjects() throws IOException { public void testIgnoreNonExistingObjects() throws IOException {
final ObjectId nonExisting = ObjectId final ObjectId nonExisting = ObjectId
.fromString("0000000000000000000000000000000000000001"); .fromString("0000000000000000000000000000000000000001");
createVerifyOpenPack(EMPTY_SET_OBJECT, Collections.singleton(
nonExisting), false, true);
createVerifyOpenPack(NONE, Collections.singleton(nonExisting),
false, true);
// shouldn't throw anything // shouldn't throw anything
} }


final ObjectId nonExisting = ObjectId final ObjectId nonExisting = ObjectId
.fromString("0000000000000000000000000000000000000001"); .fromString("0000000000000000000000000000000000000001");
new GC(db).gc(); new GC(db).gc();
createVerifyOpenPack(EMPTY_SET_OBJECT,
Collections.singleton(nonExisting), false, true, true);
createVerifyOpenPack(NONE, Collections.singleton(nonExisting), false,
true, true);
// shouldn't throw anything // shouldn't throw anything
} }


pw.setReuseDeltaCommits(false); pw.setReuseDeltaCommits(false);
for (ObjectIdSet idx : excludeObjects) for (ObjectIdSet idx : excludeObjects)
pw.excludeObjects(idx); pw.excludeObjects(idx);
pw.preparePack(NullProgressMonitor.INSTANCE, want,
Collections.<ObjectId> emptySet());
pw.preparePack(NullProgressMonitor.INSTANCE, want, NONE);
String id = pw.computeName().getName(); String id = pw.computeName().getName();
File packdir = new File(repo.getObjectsDirectory(), "pack"); File packdir = new File(repo.getObjectsDirectory(), "pack");
File packFile = new File(packdir, "pack-" + id + ".pack"); File packFile = new File(packdir, "pack-" + id + ".pack");
final HashSet<ObjectId> interestings = new HashSet<ObjectId>(); final HashSet<ObjectId> interestings = new HashSet<ObjectId>();
interestings.add(ObjectId interestings.add(ObjectId
.fromString("82c6b885ff600be425b4ea96dee75dca255b69e7")); .fromString("82c6b885ff600be425b4ea96dee75dca255b69e7"));
createVerifyOpenPack(interestings, EMPTY_SET_OBJECT, false, false);
createVerifyOpenPack(interestings, NONE, false, false);


final ObjectId expectedOrder[] = new ObjectId[] { final ObjectId expectedOrder[] = new ObjectId[] {
ObjectId.fromString("82c6b885ff600be425b4ea96dee75dca255b69e7"), ObjectId.fromString("82c6b885ff600be425b4ea96dee75dca255b69e7"),

+ 2
- 7
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsGarbageCollector.java View File

import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;


try (PackWriter pw = newPackWriter()) { try (PackWriter pw = newPackWriter()) {
pw.setTagTargets(tagTargets); pw.setTagTargets(tagTargets);
pw.preparePack(pm, allHeads, none());
pw.preparePack(pm, allHeads, PackWriter.NONE);
if (0 < pw.getObjectCount()) if (0 < pw.getObjectCount())
writePack(GC, pw, pm); writePack(GC, pw, pm);
} }
try (PackWriter pw = newPackWriter()) { try (PackWriter pw = newPackWriter()) {
for (ObjectIdSet packedObjs : newPackObj) for (ObjectIdSet packedObjs : newPackObj)
pw.excludeObjects(packedObjs); pw.excludeObjects(packedObjs);
pw.preparePack(pm, txnHeads, none());
pw.preparePack(pm, txnHeads, PackWriter.NONE);
if (0 < pw.getObjectCount()) if (0 < pw.getObjectCount())
writePack(GC_TXN, pw, pm); writePack(GC_TXN, pw, pm);
} }
} }


private static Set<ObjectId> none() {
return Collections.<ObjectId> emptySet();
}

private void packGarbage(ProgressMonitor pm) throws IOException { private void packGarbage(ProgressMonitor pm) throws IOException {
// TODO(sop) This is ugly. The garbage pack needs to be deleted. // TODO(sop) This is ugly. The garbage pack needs to be deleted.
PackConfig cfg = new PackConfig(packConfig); PackConfig cfg = new PackConfig(packConfig);

+ 4
- 3
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/GC.java View File

import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;


import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.IncorrectObjectTypeException;
ret.add(rest); ret.add(rest);
} }
if (!txnHeads.isEmpty()) { if (!txnHeads.isEmpty()) {
PackFile txn = writePack(txnHeads, null, null, excluded);
PackFile txn = writePack(txnHeads, PackWriter.NONE, null, excluded);
if (txn != null) if (txn != null)
ret.add(txn); ret.add(txn);
} }
} }
} }


private PackFile writePack(Set<? extends ObjectId> want,
Set<? extends ObjectId> have, Set<ObjectId> tagTargets,
private PackFile writePack(@NonNull Set<? extends ObjectId> want,
@NonNull Set<? extends ObjectId> have, Set<ObjectId> tagTargets,
List<ObjectIdSet> excludeObjects) throws IOException { List<ObjectIdSet> excludeObjects) throws IOException {
File tmpPack = null; File tmpPack = null;
Map<PackExt, File> tmpExts = new TreeMap<PackExt, File>( Map<PackExt, File> tmpExts = new TreeMap<PackExt, File>(

+ 21
- 18
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/pack/PackWriter.java View File

import java.util.zip.Deflater; import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream; import java.util.zip.DeflaterOutputStream;


import org.eclipse.jgit.annotations.NonNull;
import org.eclipse.jgit.errors.CorruptObjectException; import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.LargeObjectException; import org.eclipse.jgit.errors.LargeObjectException;
public class PackWriter implements AutoCloseable { public class PackWriter implements AutoCloseable {
private static final int PACK_VERSION_GENERATED = 2; private static final int PACK_VERSION_GENERATED = 2;


/** Empty set of objects for {@code preparePack()}. */
public static Set<ObjectId> NONE = Collections.emptySet();

private static final Map<WeakReference<PackWriter>, Boolean> instances = private static final Map<WeakReference<PackWriter>, Boolean> instances =
new ConcurrentHashMap<WeakReference<PackWriter>, Boolean>(); new ConcurrentHashMap<WeakReference<PackWriter>, Boolean>();


* @throws IOException * @throws IOException
* when some I/O problem occur during reading objects. * when some I/O problem occur during reading objects.
*/ */
public void preparePack(final Iterator<RevObject> objectsSource)
public void preparePack(@NonNull Iterator<RevObject> objectsSource)
throws IOException { throws IOException {
while (objectsSource.hasNext()) { while (objectsSource.hasNext()) {
addObject(objectsSource.next()); addObject(objectsSource.next());
* progress during object enumeration. * progress during object enumeration.
* @param want * @param want
* collection of objects to be marked as interesting (start * collection of objects to be marked as interesting (start
* points of graph traversal).
* points of graph traversal). Must not be {@code null}.
* @param have * @param have
* collection of objects to be marked as uninteresting (end * collection of objects to be marked as uninteresting (end
* points of graph traversal).
* points of graph traversal). Pass {@link #NONE} if all objects
* reachable from {@code want} are desired, such as when serving
* a clone.
* @throws IOException * @throws IOException
* when some I/O problem occur during reading objects. * when some I/O problem occur during reading objects.
*/ */
public void preparePack(ProgressMonitor countingMonitor, public void preparePack(ProgressMonitor countingMonitor,
Set<? extends ObjectId> want,
Set<? extends ObjectId> have) throws IOException {
@NonNull Set<? extends ObjectId> want,
@NonNull Set<? extends ObjectId> have) throws IOException {
ObjectWalk ow; ObjectWalk ow;
if (shallowPack) if (shallowPack)
ow = new DepthWalk.ObjectWalk(reader, depth); ow = new DepthWalk.ObjectWalk(reader, depth);
* ObjectWalk to perform enumeration. * ObjectWalk to perform enumeration.
* @param interestingObjects * @param interestingObjects
* collection of objects to be marked as interesting (start * collection of objects to be marked as interesting (start
* points of graph traversal).
* points of graph traversal). Must not be {@code null}.
* @param uninterestingObjects * @param uninterestingObjects
* collection of objects to be marked as uninteresting (end * collection of objects to be marked as uninteresting (end
* points of graph traversal).
* points of graph traversal). Pass {@link #NONE} if all objects
* reachable from {@code want} are desired, such as when serving
* a clone.
* @throws IOException * @throws IOException
* when some I/O problem occur during reading objects. * when some I/O problem occur during reading objects.
*/ */
public void preparePack(ProgressMonitor countingMonitor, public void preparePack(ProgressMonitor countingMonitor,
ObjectWalk walk,
final Set<? extends ObjectId> interestingObjects,
final Set<? extends ObjectId> uninterestingObjects)
@NonNull ObjectWalk walk,
@NonNull Set<? extends ObjectId> interestingObjects,
@NonNull Set<? extends ObjectId> uninterestingObjects)
throws IOException { throws IOException {
if (countingMonitor == null) if (countingMonitor == null)
countingMonitor = NullProgressMonitor.INSTANCE; countingMonitor = NullProgressMonitor.INSTANCE;
out.write(packcsum); out.write(packcsum);
} }


private void findObjectsToPack(final ProgressMonitor countingMonitor,
final ObjectWalk walker, final Set<? extends ObjectId> want,
Set<? extends ObjectId> have)
throws MissingObjectException, IOException,
IncorrectObjectTypeException {
private void findObjectsToPack(@NonNull ProgressMonitor countingMonitor,
@NonNull ObjectWalk walker, @NonNull Set<? extends ObjectId> want,
@NonNull Set<? extends ObjectId> have) throws IOException {
final long countingStart = System.currentTimeMillis(); final long countingStart = System.currentTimeMillis();
beginPhase(PackingPhase.COUNTING, countingMonitor, ProgressMonitor.UNKNOWN); beginPhase(PackingPhase.COUNTING, countingMonitor, ProgressMonitor.UNKNOWN);


if (have == null)
have = Collections.emptySet();

stats.interestingObjects = Collections.unmodifiableSet(new HashSet<ObjectId>(want)); stats.interestingObjects = Collections.unmodifiableSet(new HashSet<ObjectId>(want));
stats.uninterestingObjects = Collections.unmodifiableSet(new HashSet<ObjectId>(have)); stats.uninterestingObjects = Collections.unmodifiableSet(new HashSet<ObjectId>(have));



Loading…
Cancel
Save