diff src/org/tmatesoft/hg/internal/RevlogStream.java @ 606:5daa42067e7c

Avoid mmap files when only few bytes are to be read
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 07 May 2013 14:16:35 +0200
parents cc7b0c4dc993
children 66f1cc23b906
line wrap: on
line diff
--- 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 <code>true</code> to indicate intention to read few revisions only (as opposed to reading most of/complete revlog)
+	 * @return never <code>null</code>, 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();
 			}