diff -r c089a0947f3e -r f7459da77f23 mercurial/revlogutils/nodemap.py --- a/mercurial/revlogutils/nodemap.py Fri Feb 14 15:03:26 2020 +0100 +++ b/mercurial/revlogutils/nodemap.py Tue Feb 11 11:18:52 2020 +0100 @@ -8,6 +8,7 @@ from __future__ import absolute_import +import errno import os import re import struct @@ -45,11 +46,18 @@ docket.data_unused = data_unused filename = _rawdata_filepath(revlog, docket) - data = revlog.opener.tryread(filename) + use_mmap = revlog.opener.options.get("exp-persistent-nodemap.mmap") + try: + with revlog.opener(filename) as fd: + if use_mmap: + data = util.buffer(util.mmapread(fd, data_length)) + else: + data = fd.read(data_length) + except OSError as e: + if e.errno != errno.ENOENT: + raise if len(data) < data_length: return None - elif len(data) > data_length: - data = data[:data_length] return docket, data @@ -81,6 +89,8 @@ can_incremental = util.safehasattr(revlog.index, "nodemap_data_incremental") ondisk_docket = revlog._nodemap_docket + feed_data = util.safehasattr(revlog.index, "update_nodemap_data") + use_mmap = revlog.opener.options.get("exp-persistent-nodemap.mmap") data = None # first attemp an incremental update of the data @@ -97,12 +107,18 @@ datafile = _rawdata_filepath(revlog, target_docket) # EXP-TODO: if this is a cache, this should use a cache vfs, not a # store vfs + new_length = target_docket.data_length + len(data) with revlog.opener(datafile, b'r+') as fd: fd.seek(target_docket.data_length) fd.write(data) - fd.seek(0) - new_data = fd.read(target_docket.data_length + len(data)) - target_docket.data_length += len(data) + if feed_data: + if use_mmap: + fd.seek(0) + new_data = fd.read(new_length) + else: + fd.flush() + new_data = util.buffer(util.mmapread(fd, new_length)) + target_docket.data_length = new_length target_docket.data_unused += data_changed_count if data is None: @@ -115,9 +131,14 @@ data = persistent_data(revlog.index) # EXP-TODO: if this is a cache, this should use a cache vfs, not a # store vfs - new_data = data - with revlog.opener(datafile, b'w') as fd: + with revlog.opener(datafile, b'w+') as fd: fd.write(data) + if feed_data: + if use_mmap: + new_data = data + else: + fd.flush() + new_data = util.buffer(util.mmapread(fd, len(data))) target_docket.data_length = len(data) target_docket.tip_rev = revlog.tiprev() # EXP-TODO: if this is a cache, this should use a cache vfs, not a @@ -125,7 +146,7 @@ with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp: fp.write(target_docket.serialize()) revlog._nodemap_docket = target_docket - if util.safehasattr(revlog.index, "update_nodemap_data"): + if feed_data: revlog.index.update_nodemap_data(target_docket, new_data) # EXP-TODO: if the transaction abort, we should remove the new data and