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>
This commit is contained in:
parent
b5aa52e98a
commit
a45728d7a4
|
@ -600,33 +600,38 @@ private static void assertHash(RevObject id, byte[] bin) {
|
|||
public void packAndPrune() throws Exception {
|
||||
if (db.getObjectDatabase() instanceof ObjectDirectory) {
|
||||
ObjectDirectory odb = (ObjectDirectory) db.getObjectDatabase();
|
||||
|
||||
final File pack, idx;
|
||||
PackWriter pw = new PackWriter(db, NullProgressMonitor.INSTANCE);
|
||||
|
||||
Set<ObjectId> all = new HashSet<ObjectId>();
|
||||
for (Ref r : db.getAllRefs().values())
|
||||
all.add(r.getObjectId());
|
||||
pw.preparePack(all, Collections.<ObjectId> emptySet());
|
||||
|
||||
final ObjectId name = pw.computeName();
|
||||
OutputStream out;
|
||||
|
||||
final File pack = nameFor(odb, name, ".pack");
|
||||
out = new BufferedOutputStream(new FileOutputStream(pack));
|
||||
try {
|
||||
pw.writePack(out);
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
pack.setReadOnly();
|
||||
Set<ObjectId> all = new HashSet<ObjectId>();
|
||||
for (Ref r : db.getAllRefs().values())
|
||||
all.add(r.getObjectId());
|
||||
pw.preparePack(all, Collections.<ObjectId> emptySet());
|
||||
|
||||
final File idx = nameFor(odb, name, ".idx");
|
||||
out = new BufferedOutputStream(new FileOutputStream(idx));
|
||||
try {
|
||||
pw.writeIndex(out);
|
||||
final ObjectId name = pw.computeName();
|
||||
OutputStream out;
|
||||
|
||||
pack = nameFor(odb, name, ".pack");
|
||||
out = new BufferedOutputStream(new FileOutputStream(pack));
|
||||
try {
|
||||
pw.writePack(out);
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
pack.setReadOnly();
|
||||
|
||||
idx = nameFor(odb, name, ".idx");
|
||||
out = new BufferedOutputStream(new FileOutputStream(idx));
|
||||
try {
|
||||
pw.writeIndex(out);
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
idx.setReadOnly();
|
||||
} finally {
|
||||
out.close();
|
||||
pw.release();
|
||||
}
|
||||
idx.setReadOnly();
|
||||
|
||||
odb.openPack(pack, idx);
|
||||
updateServerInfo();
|
||||
|
|
|
@ -138,6 +138,7 @@ public void testObjectMovedWithinPack()
|
|||
pw.addObject(o2);
|
||||
pw.addObject(o1);
|
||||
write(out1, pw);
|
||||
pw.release();
|
||||
|
||||
// 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.
|
||||
|
@ -208,6 +209,7 @@ private File[] pack(final Repository src, final RevObject... list)
|
|||
final File idxFile = fullPackFileName(name, ".idx");
|
||||
final File[] files = new File[] { packFile, idxFile };
|
||||
write(files, pw);
|
||||
pw.release();
|
||||
return files;
|
||||
}
|
||||
|
||||
|
|
|
@ -484,6 +484,7 @@ private void createVerifyOpenPack(final Collection<ObjectId> interestings,
|
|||
writer.setIgnoreMissingUninteresting(ignoreMissingUninteresting);
|
||||
writer.preparePack(interestings, uninterestings);
|
||||
writer.writePack(os);
|
||||
writer.release();
|
||||
verifyOpenPack(thin);
|
||||
}
|
||||
|
||||
|
@ -491,6 +492,7 @@ private void createVerifyOpenPack(final Iterator<RevObject> objectSource)
|
|||
throws MissingObjectException, IOException {
|
||||
writer.preparePack(objectSource);
|
||||
writer.writePack(os);
|
||||
writer.release();
|
||||
verifyOpenPack(false);
|
||||
}
|
||||
|
||||
|
|
|
@ -610,22 +610,24 @@ private List<ObjectToPack> sortByName() {
|
|||
* stream.
|
||||
*/
|
||||
public void writePack(OutputStream packStream) throws IOException {
|
||||
try {
|
||||
if ((reuseDeltas || reuseObjects) && reuseSupport != null)
|
||||
searchForReuse();
|
||||
if ((reuseDeltas || reuseObjects) && reuseSupport != null)
|
||||
searchForReuse();
|
||||
|
||||
out = new PackOutputStream(packStream, isDeltaBaseAsOffset());
|
||||
out = new PackOutputStream(packStream, isDeltaBaseAsOffset());
|
||||
|
||||
int cnt = getObjectsNumber();
|
||||
writeMonitor.beginTask(WRITING_OBJECTS_PROGRESS, cnt);
|
||||
out.writeFileHeader(PACK_VERSION_GENERATED, cnt);
|
||||
writeObjects();
|
||||
writeChecksum();
|
||||
writeMonitor.endTask();
|
||||
} finally {
|
||||
out = null;
|
||||
reader.release();
|
||||
}
|
||||
writeMonitor.beginTask(WRITING_OBJECTS_PROGRESS, getObjectsNumber());
|
||||
out.writeFileHeader(PACK_VERSION_GENERATED, getObjectsNumber());
|
||||
writeObjects();
|
||||
writeChecksum();
|
||||
|
||||
out = null;
|
||||
reader.release();
|
||||
writeMonitor.endTask();
|
||||
}
|
||||
|
||||
/** Release all resources used by this writer. */
|
||||
public void release() {
|
||||
reader.release();
|
||||
}
|
||||
|
||||
private void searchForReuse() throws IOException {
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jgit.JGitText;
|
||||
|
@ -226,25 +227,29 @@ private String enableCapabilities(final ProgressMonitor monitor) {
|
|||
|
||||
private void writePack(final Map<String, RemoteRefUpdate> refUpdates,
|
||||
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 ArrayList<ObjectId> remoteObjects = new ArrayList<ObjectId>(
|
||||
getRefs().size());
|
||||
final ArrayList<ObjectId> newObjects = new ArrayList<ObjectId>(
|
||||
refUpdates.size());
|
||||
try {
|
||||
|
||||
for (final Ref r : getRefs())
|
||||
remoteObjects.add(r.getObjectId());
|
||||
remoteObjects.addAll(additionalHaves);
|
||||
for (final RemoteRefUpdate r : refUpdates.values()) {
|
||||
if (!ObjectId.zeroId().equals(r.getNewObjectId()))
|
||||
newObjects.add(r.getNewObjectId());
|
||||
for (final Ref r : getRefs())
|
||||
remoteObjects.add(r.getObjectId());
|
||||
remoteObjects.addAll(additionalHaves);
|
||||
for (final RemoteRefUpdate r : refUpdates.values()) {
|
||||
if (!ObjectId.zeroId().equals(r.getNewObjectId()))
|
||||
newObjects.add(r.getNewObjectId());
|
||||
}
|
||||
|
||||
writer.setThin(thinPack);
|
||||
writer.setDeltaBaseAsOffset(capableOfsDelta);
|
||||
writer.preparePack(newObjects, remoteObjects);
|
||||
start = System.currentTimeMillis();
|
||||
writer.writePack(out);
|
||||
} finally {
|
||||
writer.release();
|
||||
}
|
||||
|
||||
writer.setThin(thinPack);
|
||||
writer.setDeltaBaseAsOffset(capableOfsDelta);
|
||||
writer.preparePack(newObjects, remoteObjects);
|
||||
final long start = System.currentTimeMillis();
|
||||
writer.writePack(out);
|
||||
out.flush();
|
||||
packTransferTime = System.currentTimeMillis() - start;
|
||||
}
|
||||
|
|
|
@ -165,37 +165,41 @@ public void assume(final RevCommit c) {
|
|||
* stream.
|
||||
*/
|
||||
public void writeBundle(OutputStream os) throws IOException {
|
||||
final HashSet<ObjectId> inc = new HashSet<ObjectId>();
|
||||
final HashSet<ObjectId> exc = new HashSet<ObjectId>();
|
||||
inc.addAll(include.values());
|
||||
for (final RevCommit r : assume)
|
||||
exc.add(r.getId());
|
||||
packWriter.setThin(exc.size() > 0);
|
||||
packWriter.preparePack(inc, exc);
|
||||
try {
|
||||
final HashSet<ObjectId> inc = new HashSet<ObjectId>();
|
||||
final HashSet<ObjectId> exc = new HashSet<ObjectId>();
|
||||
inc.addAll(include.values());
|
||||
for (final RevCommit r : assume)
|
||||
exc.add(r.getId());
|
||||
packWriter.setThin(exc.size() > 0);
|
||||
packWriter.preparePack(inc, exc);
|
||||
|
||||
final Writer w = new OutputStreamWriter(os, Constants.CHARSET);
|
||||
w.write(TransportBundle.V2_BUNDLE_SIGNATURE);
|
||||
w.write('\n');
|
||||
final Writer w = new OutputStreamWriter(os, Constants.CHARSET);
|
||||
w.write(TransportBundle.V2_BUNDLE_SIGNATURE);
|
||||
w.write('\n');
|
||||
|
||||
final char[] tmp = new char[Constants.OBJECT_ID_STRING_LENGTH];
|
||||
for (final RevCommit a : assume) {
|
||||
w.write('-');
|
||||
a.copyTo(tmp, w);
|
||||
if (a.getRawBuffer() != null) {
|
||||
w.write(' ');
|
||||
w.write(a.getShortMessage());
|
||||
final char[] tmp = new char[Constants.OBJECT_ID_STRING_LENGTH];
|
||||
for (final RevCommit a : assume) {
|
||||
w.write('-');
|
||||
a.copyTo(tmp, w);
|
||||
if (a.getRawBuffer() != null) {
|
||||
w.write(' ');
|
||||
w.write(a.getShortMessage());
|
||||
}
|
||||
w.write('\n');
|
||||
}
|
||||
for (final Map.Entry<String, ObjectId> e : include.entrySet()) {
|
||||
e.getValue().copyTo(tmp, w);
|
||||
w.write(' ');
|
||||
w.write(e.getKey());
|
||||
w.write('\n');
|
||||
}
|
||||
w.write('\n');
|
||||
}
|
||||
for (final Map.Entry<String, ObjectId> e : include.entrySet()) {
|
||||
e.getValue().copyTo(tmp, w);
|
||||
w.write(' ');
|
||||
w.write(e.getKey());
|
||||
w.write('\n');
|
||||
}
|
||||
|
||||
w.write('\n');
|
||||
w.flush();
|
||||
packWriter.writePack(os);
|
||||
w.write('\n');
|
||||
w.flush();
|
||||
packWriter.writePack(os);
|
||||
} finally {
|
||||
packWriter.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -569,25 +569,29 @@ private void sendPack() throws IOException {
|
|||
|
||||
final PackWriter pw;
|
||||
pw = new PackWriter(db, pm, NullProgressMonitor.INSTANCE);
|
||||
pw.setDeltaBaseAsOffset(options.contains(OPTION_OFS_DELTA));
|
||||
pw.setThin(thin);
|
||||
pw.preparePack(wantAll, commonBase);
|
||||
if (options.contains(OPTION_INCLUDE_TAG)) {
|
||||
for (final Ref r : refs.values()) {
|
||||
final RevObject o;
|
||||
try {
|
||||
o = walk.parseAny(r.getObjectId());
|
||||
} catch (IOException e) {
|
||||
continue;
|
||||
try {
|
||||
pw.setDeltaBaseAsOffset(options.contains(OPTION_OFS_DELTA));
|
||||
pw.setThin(thin);
|
||||
pw.preparePack(wantAll, commonBase);
|
||||
if (options.contains(OPTION_INCLUDE_TAG)) {
|
||||
for (final Ref r : refs.values()) {
|
||||
final RevObject o;
|
||||
try {
|
||||
o = walk.parseAny(r.getObjectId());
|
||||
} catch (IOException e) {
|
||||
continue;
|
||||
}
|
||||
if (o.has(WANT) || !(o instanceof RevTag))
|
||||
continue;
|
||||
final RevTag t = (RevTag) o;
|
||||
if (!pw.willInclude(t) && pw.willInclude(t.getObject()))
|
||||
pw.addObject(t);
|
||||
}
|
||||
if (o.has(WANT) || !(o instanceof RevTag))
|
||||
continue;
|
||||
final RevTag t = (RevTag) o;
|
||||
if (!pw.willInclude(t) && pw.willInclude(t.getObject()))
|
||||
pw.addObject(t);
|
||||
}
|
||||
pw.writePack(packOut);
|
||||
} finally {
|
||||
pw.release();
|
||||
}
|
||||
pw.writePack(packOut);
|
||||
packOut.flush();
|
||||
|
||||
if (sideband)
|
||||
|
|
|
@ -209,8 +209,8 @@ private void sendpack(final List<RemoteRefUpdate> updates,
|
|||
String pathPack = null;
|
||||
String pathIdx = null;
|
||||
|
||||
final PackWriter pw = new PackWriter(local, monitor);
|
||||
try {
|
||||
final PackWriter pw = new PackWriter(local, monitor);
|
||||
final List<ObjectId> need = new ArrayList<ObjectId>();
|
||||
final List<ObjectId> have = new ArrayList<ObjectId>();
|
||||
for (final RemoteRefUpdate r : updates)
|
||||
|
@ -281,6 +281,8 @@ private void sendpack(final List<RemoteRefUpdate> updates,
|
|||
safeDelete(pathPack);
|
||||
|
||||
throw new TransportException(uri, JGitText.get().cannotStoreObjects, err);
|
||||
} finally {
|
||||
pw.release();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue