Browse Source

Ensure ObjectReader used by PackWriter is released

The ObjectReader API demands that we release the reader when we are
done with it.  PackWriter contains a reader, which it uses for the
entire packing session.  Expose the release of the reader through
a release method on the writer.

This still doesn't address the RevWalk and TreeWalk users, who
don't correctly release their reader.  But its a small step in the
right direction.

Change-Id: I5cb0b5c1b432434a799fceb21b86479e09b84a0a
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
stable-0.9
Shawn O. Pearce 15 years ago
parent
commit
a45728d7a4
  1. 11
      org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java
  2. 2
      org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/ConcurrentRepackTest.java
  3. 2
      org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/PackWriterTest.java
  4. 14
      org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java
  5. 15
      org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java
  6. 4
      org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java
  7. 4
      org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java
  8. 4
      org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java

11
org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/TestRepository.java

@ -600,8 +600,10 @@ public class TestRepository<R extends Repository> {
public void packAndPrune() throws Exception { public void packAndPrune() throws Exception {
if (db.getObjectDatabase() instanceof ObjectDirectory) { if (db.getObjectDatabase() instanceof ObjectDirectory) {
ObjectDirectory odb = (ObjectDirectory) db.getObjectDatabase(); ObjectDirectory odb = (ObjectDirectory) db.getObjectDatabase();
PackWriter pw = new PackWriter(db, NullProgressMonitor.INSTANCE);
final File pack, idx;
PackWriter pw = new PackWriter(db, NullProgressMonitor.INSTANCE);
try {
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());
@ -610,7 +612,7 @@ public class TestRepository<R extends Repository> {
final ObjectId name = pw.computeName(); final ObjectId name = pw.computeName();
OutputStream out; OutputStream out;
final File pack = nameFor(odb, name, ".pack"); pack = nameFor(odb, name, ".pack");
out = new BufferedOutputStream(new FileOutputStream(pack)); out = new BufferedOutputStream(new FileOutputStream(pack));
try { try {
pw.writePack(out); pw.writePack(out);
@ -619,7 +621,7 @@ public class TestRepository<R extends Repository> {
} }
pack.setReadOnly(); pack.setReadOnly();
final File idx = nameFor(odb, name, ".idx"); idx = nameFor(odb, name, ".idx");
out = new BufferedOutputStream(new FileOutputStream(idx)); out = new BufferedOutputStream(new FileOutputStream(idx));
try { try {
pw.writeIndex(out); pw.writeIndex(out);
@ -627,6 +629,9 @@ public class TestRepository<R extends Repository> {
out.close(); out.close();
} }
idx.setReadOnly(); idx.setReadOnly();
} finally {
pw.release();
}
odb.openPack(pack, idx); odb.openPack(pack, idx);
updateServerInfo(); updateServerInfo();

2
org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/ConcurrentRepackTest.java

@ -138,6 +138,7 @@ public class ConcurrentRepackTest extends RepositoryTestCase {
pw.addObject(o2); pw.addObject(o2);
pw.addObject(o1); pw.addObject(o1);
write(out1, pw); write(out1, pw);
pw.release();
// Try the old name, then the new name. The old name should cause the // Try the old name, then the new name. The old name should cause the
// pack to reload when it opens and the index and pack mismatch. // pack to reload when it opens and the index and pack mismatch.
@ -208,6 +209,7 @@ public class ConcurrentRepackTest extends RepositoryTestCase {
final File idxFile = fullPackFileName(name, ".idx"); final File idxFile = fullPackFileName(name, ".idx");
final File[] files = new File[] { packFile, idxFile }; final File[] files = new File[] { packFile, idxFile };
write(files, pw); write(files, pw);
pw.release();
return files; return files;
} }

2
org.eclipse.jgit.test/tst/org/eclipse/jgit/storage/file/PackWriterTest.java

@ -484,6 +484,7 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
writer.setIgnoreMissingUninteresting(ignoreMissingUninteresting); writer.setIgnoreMissingUninteresting(ignoreMissingUninteresting);
writer.preparePack(interestings, uninterestings); writer.preparePack(interestings, uninterestings);
writer.writePack(os); writer.writePack(os);
writer.release();
verifyOpenPack(thin); verifyOpenPack(thin);
} }
@ -491,6 +492,7 @@ public class PackWriterTest extends SampleDataRepositoryTestCase {
throws MissingObjectException, IOException { throws MissingObjectException, IOException {
writer.preparePack(objectSource); writer.preparePack(objectSource);
writer.writePack(os); writer.writePack(os);
writer.release();
verifyOpenPack(false); verifyOpenPack(false);
} }

14
org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackWriter.java

@ -610,22 +610,24 @@ public class PackWriter {
* stream. * stream.
*/ */
public void writePack(OutputStream packStream) throws IOException { public void writePack(OutputStream packStream) throws IOException {
try {
if ((reuseDeltas || reuseObjects) && reuseSupport != null) if ((reuseDeltas || reuseObjects) && reuseSupport != null)
searchForReuse(); searchForReuse();
out = new PackOutputStream(packStream, isDeltaBaseAsOffset()); out = new PackOutputStream(packStream, isDeltaBaseAsOffset());
int cnt = getObjectsNumber(); writeMonitor.beginTask(WRITING_OBJECTS_PROGRESS, getObjectsNumber());
writeMonitor.beginTask(WRITING_OBJECTS_PROGRESS, cnt); out.writeFileHeader(PACK_VERSION_GENERATED, getObjectsNumber());
out.writeFileHeader(PACK_VERSION_GENERATED, cnt);
writeObjects(); writeObjects();
writeChecksum(); writeChecksum();
writeMonitor.endTask();
} finally {
out = null; out = null;
reader.release(); reader.release();
writeMonitor.endTask();
} }
/** Release all resources used by this writer. */
public void release() {
reader.release();
} }
private void searchForReuse() throws IOException { private void searchForReuse() throws IOException {

15
org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackPushConnection.java

@ -48,6 +48,7 @@ import java.io.IOException;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.jgit.JGitText; import org.eclipse.jgit.JGitText;
@ -226,11 +227,12 @@ class BasePackPushConnection extends BasePackConnection implements
private void writePack(final Map<String, RemoteRefUpdate> refUpdates, private void writePack(final Map<String, RemoteRefUpdate> refUpdates,
final ProgressMonitor monitor) throws IOException { final ProgressMonitor monitor) throws IOException {
List<ObjectId> remoteObjects = new ArrayList<ObjectId>(getRefs().size());
List<ObjectId> newObjects = new ArrayList<ObjectId>(refUpdates.size());
final long start;
final PackWriter writer = new PackWriter(local, monitor); final PackWriter writer = new PackWriter(local, monitor);
final ArrayList<ObjectId> remoteObjects = new ArrayList<ObjectId>( try {
getRefs().size());
final ArrayList<ObjectId> newObjects = new ArrayList<ObjectId>(
refUpdates.size());
for (final Ref r : getRefs()) for (final Ref r : getRefs())
remoteObjects.add(r.getObjectId()); remoteObjects.add(r.getObjectId());
@ -243,8 +245,11 @@ class BasePackPushConnection extends BasePackConnection implements
writer.setThin(thinPack); writer.setThin(thinPack);
writer.setDeltaBaseAsOffset(capableOfsDelta); writer.setDeltaBaseAsOffset(capableOfsDelta);
writer.preparePack(newObjects, remoteObjects); writer.preparePack(newObjects, remoteObjects);
final long start = System.currentTimeMillis(); start = System.currentTimeMillis();
writer.writePack(out); writer.writePack(out);
} finally {
writer.release();
}
out.flush(); out.flush();
packTransferTime = System.currentTimeMillis() - start; packTransferTime = System.currentTimeMillis() - start;
} }

4
org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleWriter.java

@ -165,6 +165,7 @@ public class BundleWriter {
* stream. * stream.
*/ */
public void writeBundle(OutputStream os) throws IOException { public void writeBundle(OutputStream os) throws IOException {
try {
final HashSet<ObjectId> inc = new HashSet<ObjectId>(); final HashSet<ObjectId> inc = new HashSet<ObjectId>();
final HashSet<ObjectId> exc = new HashSet<ObjectId>(); final HashSet<ObjectId> exc = new HashSet<ObjectId>();
inc.addAll(include.values()); inc.addAll(include.values());
@ -197,5 +198,8 @@ public class BundleWriter {
w.write('\n'); w.write('\n');
w.flush(); w.flush();
packWriter.writePack(os); packWriter.writePack(os);
} finally {
packWriter.release();
}
} }
} }

4
org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

@ -569,6 +569,7 @@ public class UploadPack {
final PackWriter pw; final PackWriter pw;
pw = new PackWriter(db, pm, NullProgressMonitor.INSTANCE); pw = new PackWriter(db, pm, NullProgressMonitor.INSTANCE);
try {
pw.setDeltaBaseAsOffset(options.contains(OPTION_OFS_DELTA)); pw.setDeltaBaseAsOffset(options.contains(OPTION_OFS_DELTA));
pw.setThin(thin); pw.setThin(thin);
pw.preparePack(wantAll, commonBase); pw.preparePack(wantAll, commonBase);
@ -588,6 +589,9 @@ public class UploadPack {
} }
} }
pw.writePack(packOut); pw.writePack(packOut);
} finally {
pw.release();
}
packOut.flush(); packOut.flush();
if (sideband) if (sideband)

4
org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkPushConnection.java

@ -209,8 +209,8 @@ class WalkPushConnection extends BaseConnection implements PushConnection {
String pathPack = null; String pathPack = null;
String pathIdx = null; String pathIdx = null;
try {
final PackWriter pw = new PackWriter(local, monitor); final PackWriter pw = new PackWriter(local, monitor);
try {
final List<ObjectId> need = new ArrayList<ObjectId>(); final List<ObjectId> need = new ArrayList<ObjectId>();
final List<ObjectId> have = new ArrayList<ObjectId>(); final List<ObjectId> have = new ArrayList<ObjectId>();
for (final RemoteRefUpdate r : updates) for (final RemoteRefUpdate r : updates)
@ -281,6 +281,8 @@ class WalkPushConnection extends BaseConnection implements PushConnection {
safeDelete(pathPack); safeDelete(pathPack);
throw new TransportException(uri, JGitText.get().cannotStoreObjects, err); throw new TransportException(uri, JGitText.get().cannotStoreObjects, err);
} finally {
pw.release();
} }
} }

Loading…
Cancel
Save