equal
deleted
inserted
replaced
373 |
373 |
374 # Make copy of flag processors so each revlog instance can support |
374 # Make copy of flag processors so each revlog instance can support |
375 # custom flags. |
375 # custom flags. |
376 self._flagprocessors = dict(_flagprocessors) |
376 self._flagprocessors = dict(_flagprocessors) |
377 |
377 |
|
378 # 2-tuple of file handles being used for active writing. |
|
379 self._writinghandles = None |
|
380 |
378 mmapindexthreshold = None |
381 mmapindexthreshold = None |
379 v = REVLOG_DEFAULT_VERSION |
382 v = REVLOG_DEFAULT_VERSION |
380 opts = getattr(opener, 'options', None) |
383 opts = getattr(opener, 'options', None) |
381 if opts is not None: |
384 if opts is not None: |
382 if 'revlogv2' in opts: |
385 if 'revlogv2' in opts: |
503 return self.opener(self.datafile, mode=mode) |
506 return self.opener(self.datafile, mode=mode) |
504 |
507 |
505 @contextlib.contextmanager |
508 @contextlib.contextmanager |
506 def _datareadfp(self, existingfp=None): |
509 def _datareadfp(self, existingfp=None): |
507 """file object suitable to read data""" |
510 """file object suitable to read data""" |
|
511 # Use explicit file handle, if given. |
508 if existingfp is not None: |
512 if existingfp is not None: |
509 yield existingfp |
513 yield existingfp |
|
514 |
|
515 # Use a file handle being actively used for writes, if available. |
|
516 # There is some danger to doing this because reads will seek the |
|
517 # file. However, _writeentry() performs a SEEK_END before all writes, |
|
518 # so we should be safe. |
|
519 elif self._writinghandles: |
|
520 if self._inline: |
|
521 yield self._writinghandles[0] |
|
522 else: |
|
523 yield self._writinghandles[1] |
|
524 |
|
525 # Otherwise open a new file handle. |
510 else: |
526 else: |
511 if self._inline: |
527 if self._inline: |
512 func = self._indexfp |
528 func = self._indexfp |
513 else: |
529 else: |
514 func = self._datafp |
530 func = self._datafp |
1748 tr.add(self.datafile, dataoff) |
1764 tr.add(self.datafile, dataoff) |
1749 |
1765 |
1750 if fp: |
1766 if fp: |
1751 fp.flush() |
1767 fp.flush() |
1752 fp.close() |
1768 fp.close() |
|
1769 # We can't use the cached file handle after close(). So prevent |
|
1770 # its usage. |
|
1771 self._writinghandles = None |
1753 |
1772 |
1754 with self._indexfp('r') as ifh, self._datafp('w') as dfh: |
1773 with self._indexfp('r') as ifh, self._datafp('w') as dfh: |
1755 for r in self: |
1774 for r in self: |
1756 dfh.write(self._getsegmentforrevs(r, r, df=ifh)[1]) |
1775 dfh.write(self._getsegmentforrevs(r, r, df=ifh)[1]) |
1757 |
1776 |
1994 # platforms, Python or the platform itself can be buggy. Some versions |
2013 # platforms, Python or the platform itself can be buggy. Some versions |
1995 # of Solaris have been observed to not append at the end of the file |
2014 # of Solaris have been observed to not append at the end of the file |
1996 # if the file was seeked to before the end. See issue4943 for more. |
2015 # if the file was seeked to before the end. See issue4943 for more. |
1997 # |
2016 # |
1998 # We work around this issue by inserting a seek() before writing. |
2017 # We work around this issue by inserting a seek() before writing. |
1999 # Note: This is likely not necessary on Python 3. |
2018 # Note: This is likely not necessary on Python 3. However, because |
|
2019 # the file handle is reused for reads and may be seeked there, we need |
|
2020 # to be careful before changing this. |
2000 ifh.seek(0, os.SEEK_END) |
2021 ifh.seek(0, os.SEEK_END) |
2001 if dfh: |
2022 if dfh: |
2002 dfh.seek(0, os.SEEK_END) |
2023 dfh.seek(0, os.SEEK_END) |
2003 |
2024 |
2004 curr = len(self) - 1 |
2025 curr = len(self) - 1 |
2026 log, the rest are against the previous delta. |
2047 log, the rest are against the previous delta. |
2027 |
2048 |
2028 If ``addrevisioncb`` is defined, it will be called with arguments of |
2049 If ``addrevisioncb`` is defined, it will be called with arguments of |
2029 this revlog and the node that was added. |
2050 this revlog and the node that was added. |
2030 """ |
2051 """ |
|
2052 |
|
2053 if self._writinghandles: |
|
2054 raise error.ProgrammingError('cannot nest addgroup() calls') |
2031 |
2055 |
2032 nodes = [] |
2056 nodes = [] |
2033 |
2057 |
2034 r = len(self) |
2058 r = len(self) |
2035 end = 0 |
2059 end = 0 |
2046 dfh = self._datafp("a+") |
2070 dfh = self._datafp("a+") |
2047 def flush(): |
2071 def flush(): |
2048 if dfh: |
2072 if dfh: |
2049 dfh.flush() |
2073 dfh.flush() |
2050 ifh.flush() |
2074 ifh.flush() |
|
2075 |
|
2076 self._writinghandles = (ifh, dfh) |
|
2077 |
2051 try: |
2078 try: |
2052 deltacomputer = deltautil.deltacomputer(self) |
2079 deltacomputer = deltautil.deltacomputer(self) |
2053 # loop through our set of deltas |
2080 # loop through our set of deltas |
2054 for data in deltas: |
2081 for data in deltas: |
2055 node, p1, p2, linknode, deltabase, delta, flags = data |
2082 node, p1, p2, linknode, deltabase, delta, flags = data |
2107 # addrevision switched from inline to conventional |
2134 # addrevision switched from inline to conventional |
2108 # reopen the index |
2135 # reopen the index |
2109 ifh.close() |
2136 ifh.close() |
2110 dfh = self._datafp("a+") |
2137 dfh = self._datafp("a+") |
2111 ifh = self._indexfp("a+") |
2138 ifh = self._indexfp("a+") |
|
2139 self._writinghandles = (ifh, dfh) |
2112 finally: |
2140 finally: |
|
2141 self._writinghandles = None |
|
2142 |
2113 if dfh: |
2143 if dfh: |
2114 dfh.close() |
2144 dfh.close() |
2115 ifh.close() |
2145 ifh.close() |
2116 |
2146 |
2117 return nodes |
2147 return nodes |