# HG changeset patch # User Artem Tikhomirov # Date 1367928995 -7200 # Node ID 5daa42067e7c9992869f15bc926fd831f2077583 # Parent c56edf42be645e6595d2c1ef0115d5c5c05f6260 Avoid mmap files when only few bytes are to be read diff -r c56edf42be64 -r 5daa42067e7c src/org/tmatesoft/hg/internal/DataAccessProvider.java --- a/src/org/tmatesoft/hg/internal/DataAccessProvider.java Mon May 06 20:28:21 2013 +0200 +++ b/src/org/tmatesoft/hg/internal/DataAccessProvider.java Tue May 07 14:16:35 2013 +0200 @@ -84,14 +84,14 @@ return mapioBoundary == 0 ? Integer.MAX_VALUE : mapioBoundary; } - public DataAccess createReader(File f) { + public DataAccess createReader(File f, boolean shortRead) { if (!f.exists()) { return new DataAccess(); } try { FileChannel fc = new FileInputStream(f).getChannel(); long flen = fc.size(); - if (flen > mapioMagicBoundary) { + if (!shortRead && flen > mapioMagicBoundary) { // TESTS: bufLen of 1024 was used to test MemMapFileAccess return new MemoryMapFileAccess(fc, flen, mapioBufSize, context.getLog()); } else { diff -r c56edf42be64 -r 5daa42067e7c src/org/tmatesoft/hg/internal/DirstateReader.java --- a/src/org/tmatesoft/hg/internal/DirstateReader.java Mon May 06 20:28:21 2013 +0200 +++ b/src/org/tmatesoft/hg/internal/DirstateReader.java Tue May 07 14:16:35 2013 +0200 @@ -66,7 +66,7 @@ if (dirstateFile == null || !dirstateFile.exists()) { return; } - DataAccess da = repo.getDataAccess().createReader(dirstateFile); + DataAccess da = repo.getDataAccess().createReader(dirstateFile, false); try { if (da.isEmpty()) { return; @@ -142,7 +142,7 @@ if (dirstateFile == null || !dirstateFile.exists()) { return new Pair(NULL, NULL); } - DataAccess da = internalRepo.getDataAccess().createReader(dirstateFile); + DataAccess da = internalRepo.getDataAccess().createReader(dirstateFile, false); try { if (da.isEmpty()) { return new Pair(NULL, NULL); diff -r c56edf42be64 -r 5daa42067e7c src/org/tmatesoft/hg/internal/RevlogStream.java --- a/src/org/tmatesoft/hg/internal/RevlogStream.java Mon May 06 20:28:21 2013 +0200 +++ b/src/org/tmatesoft/hg/internal/RevlogStream.java Tue May 07 14:16:35 2013 +0200 @@ -77,14 +77,18 @@ this.indexFile = indexFile; } - /*package*/ DataAccess getIndexStream() { - // FIXME [1.1] must supply a hint that I'll need really few bytes of data (perhaps, at some offset) - // to avoid mmap files when only few bytes are to be read (i.e. #dataLength()) - return dataAccess.createReader(indexFile); + /** + * @param shortRead pass true to indicate intention to read few revisions only (as opposed to reading most of/complete revlog) + * @return never null, empty {@link DataAccess} if no stream is available + */ + /*package*/ DataAccess getIndexStream(boolean shortRead) { + // shortRead hint helps to avoid mmap files when only + // few bytes are to be read (i.e. #dataLength()) + return dataAccess.createReader(indexFile, shortRead); } /*package*/ DataAccess getDataStream() { - return dataAccess.createReader(getDataFile()); + return dataAccess.createReader(getDataFile(), false); } /*package*/ DataSerializer getIndexStreamWriter() { @@ -147,7 +151,7 @@ // XXX in fact, use of iterate() instead of this implementation may be quite reasonable. // revisionIndex = checkRevisionIndex(revisionIndex); - DataAccess daIndex = getIndexStream(); + DataAccess daIndex = getIndexStream(true); try { int recordOffset = getIndexOffsetInt(revisionIndex); daIndex.seek(recordOffset + 12); // 6+2+4 @@ -168,7 +172,7 @@ */ public byte[] nodeid(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException { revisionIndex = checkRevisionIndex(revisionIndex); - DataAccess daIndex = getIndexStream(); + DataAccess daIndex = getIndexStream(true); try { int recordOffset = getIndexOffsetInt(revisionIndex); daIndex.seek(recordOffset + 32); @@ -190,7 +194,7 @@ */ public int linkRevision(int revisionIndex) throws HgInvalidControlFileException, HgInvalidRevisionException { revisionIndex = checkRevisionIndex(revisionIndex); - DataAccess daIndex = getIndexStream(); + DataAccess daIndex = getIndexStream(true); try { int recordOffset = getIndexOffsetInt(revisionIndex); daIndex.seek(recordOffset + 20); @@ -226,7 +230,7 @@ public int findRevisionIndex(Nodeid nodeid) throws HgInvalidControlFileException { // XXX this one may be implemented with iterate() once there's mechanism to stop iterations final int indexSize = revisionCount(); - DataAccess daIndex = getIndexStream(); + DataAccess daIndex = getIndexStream(false); try { byte[] nodeidBuf = new byte[20]; for (int i = 0; i < indexSize; i++) { @@ -255,7 +259,7 @@ if (revisionCount() == 0) { return 0; } - DataAccess daIndex = getIndexStream(); + DataAccess daIndex = getIndexStream(true); int lastRev = revisionCount() - 1; try { int recordOffset = getIndexOffsetInt(lastRev); @@ -421,7 +425,7 @@ if (outlineCached()) { return; } - DataAccess da = getIndexStream(); + DataAccess da = getIndexStream(false); try { if (da.isEmpty()) { // do not fail with exception if stream is empty, it's likely intentional @@ -551,7 +555,7 @@ } public void start(int totalWork, CachedRevision cachedRevision) { - daIndex = getIndexStream(); + daIndex = getIndexStream(totalWork <= 10); if (needData && !inline) { daData = getDataStream(); } diff -r c56edf42be64 -r 5daa42067e7c src/org/tmatesoft/hg/repo/HgBundle.java --- a/src/org/tmatesoft/hg/repo/HgBundle.java Mon May 06 20:28:21 2013 +0200 +++ b/src/org/tmatesoft/hg/repo/HgBundle.java Tue May 07 14:16:35 2013 +0200 @@ -60,7 +60,7 @@ } private DataAccess getDataStream() throws IOException { - DataAccess da = accessProvider.createReader(bundleFile); + DataAccess da = accessProvider.createReader(bundleFile, false); byte[] signature = new byte[6]; if (da.length() > 6) { da.readBytes(signature, 0, 6);