# HG changeset patch # User Boris Feld # Date 1517849849 -3600 # Node ID 4d66993bdcff7a96904f1b653396fb0c6245c84e # Parent 82afb1a5ed94a20f2cf8a4ff05e512654bb55dff revlog: add a _datareadfp context manager for data access needs The helper handles: 1) is there a file handle already open that we shall just reuse, 2) is the revlog inlined or not. Using a context manager for all read access will help setting up file pointer caching in later changesets. diff -r 82afb1a5ed94 -r 4d66993bdcff mercurial/revlog.py --- a/mercurial/revlog.py Mon Feb 05 17:35:14 2018 +0100 +++ b/mercurial/revlog.py Mon Feb 05 17:57:29 2018 +0100 @@ -15,6 +15,7 @@ import binascii import collections +import contextlib import errno import hashlib import heapq @@ -694,6 +695,19 @@ """file object for the revlog's data file""" return self.opener(self.datafile, mode=mode) + @contextlib.contextmanager + def _datareadfp(self, existingfp=None): + """file object suitable to read data""" + if existingfp is not None: + yield existingfp + else: + if self._inline: + func = self._indexfp + else: + func = self._datafp + with func() as fp: + yield fp + def tip(self): return self.node(len(self.index) - 2) def __contains__(self, rev): @@ -1502,15 +1516,6 @@ Returns a str or buffer of raw byte data. """ - if df is not None: - closehandle = False - else: - if self._inline: - df = self._indexfp() - else: - df = self._datafp() - closehandle = True - # Cache data both forward and backward around the requested # data, in a fixed size window. This helps speed up operations # involving reading the revlog backwards. @@ -1518,10 +1523,9 @@ realoffset = offset & ~(cachesize - 1) reallength = (((offset + length + cachesize) & ~(cachesize - 1)) - realoffset) - df.seek(realoffset) - d = df.read(reallength) - if closehandle: - df.close() + with self._datareadfp(df) as df: + df.seek(realoffset) + d = df.read(reallength) self._cachesegment(realoffset, d) if offset != realoffset or reallength != length: return util.buffer(d, offset - realoffset, length)