[PATCH 3 of 3] revlog: read index data using mmap

Jun Wu quark at fb.com
Tue Oct 4 10:59:45 EDT 2016


# HG changeset patch
# User Jun Wu <quark at fb.com>
# Date 1475550701 -3600
#      Tue Oct 04 04:11:41 2016 +0100
# Node ID 99e7b0589b916b83d825882e907dd79082f4a2d7
# Parent  5ebdfd4ffbedbfe66b7a36cbd06b1e8e624ae7ad
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r 99e7b0589b91
revlog: read index data using mmap

Revlog indexes are suppose to be small but they can be not-so-small for
large repos, where the time needed to read the revlog index is not
negligible. This patch makes it use mmap to read the content. It has visible
performance improvement for large repos.

Unfortunately Python 2.6's mmap buffer does not support the Py_buffer
interface so we fallback to plain read for sys.version < 2.7.

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -19,4 +19,5 @@ import hashlib
 import os
 import struct
+import sys
 import zlib
 
@@ -114,4 +115,11 @@ def decompress(bin):
     raise RevlogError(_("unknown compression type %r") % t)
 
+if sys.version >= (2, 7):
+    def _readindexfile(fp):
+        return util.buffer(util.mmapread(fp))
+else: # mmap buffer in Python 2.6 does not work with C code
+    def _readindexfile(fp):
+        return fp.read()
+
 # index v0:
 #  4 bytes: offset
@@ -274,5 +282,5 @@ class revlog(object):
         try:
             f = self.opener(self.indexfile)
-            indexdata = f.read()
+            indexdata = _readindexfile(f)
             f.close()
             if len(indexdata) > 0:


More information about the Mercurial-devel mailing list