Mercurial > jhg
diff src/org/tmatesoft/hg/repo/HgManifest.java @ 574:88afffd39899
Improve memory consumption of HgManifest#getFileRevision(): avoid extra byte[] instances
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 16 Apr 2013 14:44:57 +0200 |
parents | e4ee4bf4c7d0 |
children | 47dfa0ec7e35 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/repo/HgManifest.java Fri Apr 12 19:50:21 2013 +0200 +++ b/src/org/tmatesoft/hg/repo/HgManifest.java Tue Apr 16 14:44:57 2013 +0200 @@ -20,26 +20,26 @@ import static org.tmatesoft.hg.repo.HgRepository.*; import static org.tmatesoft.hg.util.LogFacility.Severity.Info; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import org.tmatesoft.hg.core.HgChangesetFileSneaker; import org.tmatesoft.hg.core.Nodeid; +import org.tmatesoft.hg.internal.ByteVector; import org.tmatesoft.hg.internal.Callback; import org.tmatesoft.hg.internal.DataAccess; import org.tmatesoft.hg.internal.DigestHelper; import org.tmatesoft.hg.internal.EncodingHelper; +import org.tmatesoft.hg.internal.IdentityPool; import org.tmatesoft.hg.internal.IntMap; import org.tmatesoft.hg.internal.IterateControlMediator; import org.tmatesoft.hg.internal.Lifecycle; -import org.tmatesoft.hg.internal.IdentityPool; import org.tmatesoft.hg.internal.RevlogStream; import org.tmatesoft.hg.util.CancelSupport; +import org.tmatesoft.hg.util.LogFacility.Severity; import org.tmatesoft.hg.util.Path; import org.tmatesoft.hg.util.ProgressSupport; -import org.tmatesoft.hg.util.LogFacility.Severity; /** @@ -51,7 +51,8 @@ */ public final class HgManifest extends Revlog { private RevisionMapper revisionMap; - private EncodingHelper encodingHelper; + private final EncodingHelper encodingHelper; + private final Path.Source pathFactory; /** * File flags recorded in manifest @@ -111,11 +112,19 @@ } throw new IllegalStateException(toString()); } + + public int fsMode() { + if (this == Exec) { + return 0755; + } + return 0644; + } } /*package-local*/ HgManifest(HgRepository hgRepo, RevlogStream content, EncodingHelper eh) { super(hgRepo, content); encodingHelper = eh; + pathFactory = hgRepo.getSessionContext().getPathFactory(); } /** @@ -446,8 +455,8 @@ public Path freeze() { if (result == null) { - Path.Source pathFactory = HgManifest.this.getRepo().getSessionContext().getPathFactory(); - result = pathFactory.path(HgManifest.this.encodingHelper.fromManifest(data, start, length)); + Path.Source pf = HgManifest.this.pathFactory; + result = pf.path(HgManifest.this.encodingHelper.fromManifest(data, start, length)); // release reference to bigger data array, make a copy of relevant part only // use original bytes, not those from String above to avoid cache misses due to different encodings byte[] d = new byte[length]; @@ -689,16 +698,14 @@ } public void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[] nodeid, DataAccess data) { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ByteVector byteVector = new ByteVector(256, 128); // allocate for long paths right away try { byte b; while (!data.isEmpty() && (b = data.readByte()) != '\n') { if (b != 0) { - bos.write(b); + byteVector.add(b); } else { - byte[] byteArray = bos.toByteArray(); - bos.reset(); - if (Arrays.equals(filenameAsBytes, byteArray)) { + if (byteVector.equalsTo(filenameAsBytes)) { Nodeid fileRev = null; Flags flags = null; if (csetIndex2FileRev != null || delegate != null) { @@ -709,15 +716,15 @@ data.skip(40); } if (csetIndex2Flags != null || delegate != null) { + byteVector.clear(); while (!data.isEmpty() && (b = data.readByte()) != '\n') { - bos.write(b); + byteVector.add(b); } - if (bos.size() == 0) { + if (byteVector.size() == 0) { flags = Flags.RegularFile; } else { - flags = Flags.parse(bos.toByteArray(), 0, bos.size()); + flags = Flags.parse(byteVector.toByteArray(), 0, byteVector.size()); } - } if (delegate != null) { assert flags != null; @@ -741,6 +748,8 @@ // else skip to the end of line while (!data.isEmpty() && (b = data.readByte()) != '\n') ; + + byteVector.clear(); } } } catch (IOException ex) {