Show More
@@ -506,9 +506,9 b' class changelog(revlog.revlog):' | |||
|
506 | 506 | |
|
507 | 507 | return False |
|
508 | 508 | |
|
509 |
def _enforceinlinesize(self, tr |
|
|
509 | def _enforceinlinesize(self, tr): | |
|
510 | 510 | if not self._delayed: |
|
511 |
revlog.revlog._enforceinlinesize(self, tr |
|
|
511 | revlog.revlog._enforceinlinesize(self, tr) | |
|
512 | 512 | |
|
513 | 513 | def read(self, nodeorrev): |
|
514 | 514 | """Obtain data from a parsed changelog revision. |
@@ -360,6 +360,8 b' class revlog(object):' | |||
|
360 | 360 | |
|
361 | 361 | # 2-tuple of file handles being used for active writing. |
|
362 | 362 | self._writinghandles = None |
|
363 | # prevent nesting of addgroup | |
|
364 | self._adding_group = None | |
|
363 | 365 | |
|
364 | 366 | self._loadindex() |
|
365 | 367 | |
@@ -1955,7 +1957,7 b' class revlog(object):' | |||
|
1955 | 1957 | raise error.CensoredNodeError(self.display_id, node, text) |
|
1956 | 1958 | raise |
|
1957 | 1959 | |
|
1958 |
def _enforceinlinesize(self, tr |
|
|
1960 | def _enforceinlinesize(self, tr): | |
|
1959 | 1961 | """Check if the revlog is too big for inline and convert if so. |
|
1960 | 1962 | |
|
1961 | 1963 | This should be called after revisions are added to the revlog. If the |
@@ -1975,21 +1977,27 b' class revlog(object):' | |||
|
1975 | 1977 | trindex = 0 |
|
1976 | 1978 | tr.add(self._datafile, 0) |
|
1977 | 1979 | |
|
1978 | if fp: | |
|
1980 | existing_handles = False | |
|
1981 | if self._writinghandles is not None: | |
|
1982 | existing_handles = True | |
|
1983 | fp = self._writinghandles[0] | |
|
1979 | 1984 | fp.flush() |
|
1980 | 1985 | fp.close() |
|
1981 | 1986 | # We can't use the cached file handle after close(). So prevent |
|
1982 | 1987 | # its usage. |
|
1983 | 1988 | self._writinghandles = None |
|
1984 | 1989 | |
|
1985 | if True: | |
|
1986 | with self._indexfp(b'r') as ifh, self._datafp(b'w') as dfh: | |
|
1990 | new_dfh = self._datafp(b'w+') | |
|
1991 | new_dfh.truncate(0) # drop any potentially existing data | |
|
1992 | try: | |
|
1993 | with self._indexfp(b'r') as read_ifh: | |
|
1987 | 1994 | for r in self: |
|
1988 | dfh.write(self._getsegmentforrevs(r, r, df=ifh)[1]) | |
|
1995 | new_dfh.write(self._getsegmentforrevs(r, r, df=read_ifh)[1]) | |
|
1989 | 1996 | if troffset <= self.start(r): |
|
1990 | 1997 | trindex = r |
|
1991 | ||
|
1992 | with self._indexfp(b'w') as fp: | |
|
1998 | new_dfh.flush() | |
|
1999 | ||
|
2000 | with self.opener(self._indexfile, mode=b'w', atomictemp=True) as fp: | |
|
1993 | 2001 | self._format_flags &= ~FLAG_INLINE_DATA |
|
1994 | 2002 | self._inline = False |
|
1995 | 2003 | for i in self: |
@@ -1999,7 +2007,6 b' class revlog(object):' | |||
|
1999 | 2007 | header = self.index.pack_header(header) |
|
2000 | 2008 | e = header + e |
|
2001 | 2009 | fp.write(e) |
|
2002 | ||
|
2003 | 2010 | # the temp file replace the real index when we exit the context |
|
2004 | 2011 | # manager |
|
2005 | 2012 | |
@@ -2007,9 +2014,50 b' class revlog(object):' | |||
|
2007 | 2014 | nodemaputil.setup_persistent_nodemap(tr, self) |
|
2008 | 2015 | self._chunkclear() |
|
2009 | 2016 | |
|
2017 | if existing_handles: | |
|
2018 | # switched from inline to conventional reopen the index | |
|
2019 | ifh = self._indexfp(b"a+") | |
|
2020 | self._writinghandles = (ifh, new_dfh) | |
|
2021 | new_dfh = None | |
|
2022 | finally: | |
|
2023 | if new_dfh is not None: | |
|
2024 | new_dfh.close() | |
|
2025 | ||
|
2010 | 2026 | def _nodeduplicatecallback(self, transaction, node): |
|
2011 | 2027 | """called when trying to add a node already stored.""" |
|
2012 | 2028 | |
|
2029 | @contextlib.contextmanager | |
|
2030 | def _writing(self, transaction): | |
|
2031 | if self._writinghandles is not None: | |
|
2032 | yield | |
|
2033 | else: | |
|
2034 | r = len(self) | |
|
2035 | dsize = 0 | |
|
2036 | if r: | |
|
2037 | dsize = self.end(r - 1) | |
|
2038 | dfh = None | |
|
2039 | if not self._inline: | |
|
2040 | dfh = self._datafp(b"a+") | |
|
2041 | transaction.add(self._datafile, dsize) | |
|
2042 | try: | |
|
2043 | isize = r * self.index.entry_size | |
|
2044 | ifh = self._indexfp(b"a+") | |
|
2045 | if self._inline: | |
|
2046 | transaction.add(self._indexfile, dsize + isize) | |
|
2047 | else: | |
|
2048 | transaction.add(self._indexfile, isize) | |
|
2049 | try: | |
|
2050 | self._writinghandles = (ifh, dfh) | |
|
2051 | try: | |
|
2052 | yield | |
|
2053 | finally: | |
|
2054 | self._writinghandles = None | |
|
2055 | finally: | |
|
2056 | ifh.close() | |
|
2057 | finally: | |
|
2058 | if dfh is not None: | |
|
2059 | dfh.close() | |
|
2060 | ||
|
2013 | 2061 | def addrevision( |
|
2014 | 2062 | self, |
|
2015 | 2063 | text, |
@@ -2105,11 +2153,7 b' class revlog(object):' | |||
|
2105 | 2153 | useful when reusing a revision not stored in this revlog (ex: received |
|
2106 | 2154 | over wire, or read from an external bundle). |
|
2107 | 2155 | """ |
|
2108 | dfh = None | |
|
2109 | if not self._inline: | |
|
2110 | dfh = self._datafp(b"a+") | |
|
2111 | ifh = self._indexfp(b"a+") | |
|
2112 | try: | |
|
2156 | with self._writing(transaction): | |
|
2113 | 2157 | return self._addrevision( |
|
2114 | 2158 | node, |
|
2115 | 2159 | rawtext, |
@@ -2119,15 +2163,9 b' class revlog(object):' | |||
|
2119 | 2163 | p2, |
|
2120 | 2164 | flags, |
|
2121 | 2165 | cachedelta, |
|
2122 | ifh, | |
|
2123 | dfh, | |
|
2124 | 2166 | deltacomputer=deltacomputer, |
|
2125 | 2167 | sidedata=sidedata, |
|
2126 | 2168 | ) |
|
2127 | finally: | |
|
2128 | if dfh: | |
|
2129 | dfh.close() | |
|
2130 | ifh.close() | |
|
2131 | 2169 | |
|
2132 | 2170 | def compress(self, data): |
|
2133 | 2171 | """Generate a possibly-compressed representation of data.""" |
@@ -2214,8 +2252,6 b' class revlog(object):' | |||
|
2214 | 2252 | p2, |
|
2215 | 2253 | flags, |
|
2216 | 2254 | cachedelta, |
|
2217 | ifh, | |
|
2218 | dfh, | |
|
2219 | 2255 | alwayscache=False, |
|
2220 | 2256 | deltacomputer=None, |
|
2221 | 2257 | sidedata=None, |
@@ -2244,11 +2280,14 b' class revlog(object):' | |||
|
2244 | 2280 | raise error.RevlogError( |
|
2245 | 2281 | _(b"%s: attempt to add wdir revision") % self.display_id |
|
2246 | 2282 | ) |
|
2283 | if self._writinghandles is None: | |
|
2284 | msg = b'adding revision outside `revlog._writing` context' | |
|
2285 | raise error.ProgrammingError(msg) | |
|
2247 | 2286 | |
|
2248 | 2287 | if self._inline: |
|
2249 |
fh = |
|
|
2288 | fh = self._writinghandles[0] | |
|
2250 | 2289 | else: |
|
2251 |
fh = |
|
|
2290 | fh = self._writinghandles[1] | |
|
2252 | 2291 | |
|
2253 | 2292 | btext = [rawtext] |
|
2254 | 2293 | |
@@ -2258,6 +2297,7 b' class revlog(object):' | |||
|
2258 | 2297 | offset = self._get_data_offset(prev) |
|
2259 | 2298 | |
|
2260 | 2299 | if self._concurrencychecker: |
|
2300 | ifh, dfh = self._writinghandles | |
|
2261 | 2301 | if self._inline: |
|
2262 | 2302 | # offset is "as if" it were in the .d file, so we need to add on |
|
2263 | 2303 | # the size of the entry metadata. |
@@ -2323,8 +2363,6 b' class revlog(object):' | |||
|
2323 | 2363 | entry = header + entry |
|
2324 | 2364 | self._writeentry( |
|
2325 | 2365 | transaction, |
|
2326 | ifh, | |
|
2327 | dfh, | |
|
2328 | 2366 | entry, |
|
2329 | 2367 | deltainfo.data, |
|
2330 | 2368 | link, |
@@ -2362,9 +2400,7 b' class revlog(object):' | |||
|
2362 | 2400 | offset = max(self.end(rev), offset, sidedata_end) |
|
2363 | 2401 | return offset |
|
2364 | 2402 | |
|
2365 | def _writeentry( | |
|
2366 | self, transaction, ifh, dfh, entry, data, link, offset, sidedata | |
|
2367 | ): | |
|
2403 | def _writeentry(self, transaction, entry, data, link, offset, sidedata): | |
|
2368 | 2404 | # Files opened in a+ mode have inconsistent behavior on various |
|
2369 | 2405 | # platforms. Windows requires that a file positioning call be made |
|
2370 | 2406 | # when the file handle transitions between reads and writes. See |
@@ -2377,6 +2413,10 b' class revlog(object):' | |||
|
2377 | 2413 | # Note: This is likely not necessary on Python 3. However, because |
|
2378 | 2414 | # the file handle is reused for reads and may be seeked there, we need |
|
2379 | 2415 | # to be careful before changing this. |
|
2416 | if self._writinghandles is None: | |
|
2417 | msg = b'adding revision outside `revlog._writing` context' | |
|
2418 | raise error.ProgrammingError(msg) | |
|
2419 | ifh, dfh = self._writinghandles | |
|
2380 | 2420 | ifh.seek(0, os.SEEK_END) |
|
2381 | 2421 | if dfh: |
|
2382 | 2422 | dfh.seek(0, os.SEEK_END) |
@@ -2399,7 +2439,7 b' class revlog(object):' | |||
|
2399 | 2439 | ifh.write(data[1]) |
|
2400 | 2440 | if sidedata: |
|
2401 | 2441 | ifh.write(sidedata) |
|
2402 |
self._enforceinlinesize(transaction |
|
|
2442 | self._enforceinlinesize(transaction) | |
|
2403 | 2443 | nodemaputil.setup_persistent_nodemap(transaction, self) |
|
2404 | 2444 | |
|
2405 | 2445 | def addgroup( |
@@ -2422,28 +2462,13 b' class revlog(object):' | |||
|
2422 | 2462 | this revlog and the node that was added. |
|
2423 | 2463 | """ |
|
2424 | 2464 | |
|
2425 |
if self._ |
|
|
2465 | if self._adding_group: | |
|
2426 | 2466 | raise error.ProgrammingError(b'cannot nest addgroup() calls') |
|
2427 | 2467 | |
|
2428 | r = len(self) | |
|
2429 | end = 0 | |
|
2430 | if r: | |
|
2431 | end = self.end(r - 1) | |
|
2432 | ifh = self._indexfp(b"a+") | |
|
2433 | isize = r * self.index.entry_size | |
|
2434 | if self._inline: | |
|
2435 | transaction.add(self._indexfile, end + isize) | |
|
2436 | dfh = None | |
|
2437 | else: | |
|
2438 | transaction.add(self._indexfile, isize) | |
|
2439 | transaction.add(self._datafile, end) | |
|
2440 | dfh = self._datafp(b"a+") | |
|
2441 | ||
|
2442 | self._writinghandles = (ifh, dfh) | |
|
2468 | self._adding_group = True | |
|
2443 | 2469 | empty = True |
|
2444 | ||
|
2445 | 2470 | try: |
|
2446 | if True: | |
|
2471 | with self._writing(transaction): | |
|
2447 | 2472 | deltacomputer = deltautil.deltacomputer(self) |
|
2448 | 2473 | # loop through our set of deltas |
|
2449 | 2474 | for data in deltas: |
@@ -2514,8 +2539,6 b' class revlog(object):' | |||
|
2514 | 2539 | p2, |
|
2515 | 2540 | flags, |
|
2516 | 2541 | (baserev, delta), |
|
2517 | ifh, | |
|
2518 | dfh, | |
|
2519 | 2542 | alwayscache=alwayscache, |
|
2520 | 2543 | deltacomputer=deltacomputer, |
|
2521 | 2544 | sidedata=sidedata, |
@@ -2524,20 +2547,8 b' class revlog(object):' | |||
|
2524 | 2547 | if addrevisioncb: |
|
2525 | 2548 | addrevisioncb(self, rev) |
|
2526 | 2549 | empty = False |
|
2527 | ||
|
2528 | if not dfh and not self._inline: | |
|
2529 | # addrevision switched from inline to conventional | |
|
2530 | # reopen the index | |
|
2531 | ifh.close() | |
|
2532 | dfh = self._datafp(b"a+") | |
|
2533 | ifh = self._indexfp(b"a+") | |
|
2534 | self._writinghandles = (ifh, dfh) | |
|
2535 | 2550 | finally: |
|
2536 |
self._ |
|
|
2537 | ||
|
2538 | if dfh: | |
|
2539 | dfh.close() | |
|
2540 | ifh.close() | |
|
2551 | self._adding_group = False | |
|
2541 | 2552 | return not empty |
|
2542 | 2553 | |
|
2543 | 2554 | def iscensored(self, rev): |
@@ -2868,13 +2879,7 b' class revlog(object):' | |||
|
2868 | 2879 | ) |
|
2869 | 2880 | flags = flags | new_flags[0] & ~new_flags[1] |
|
2870 | 2881 | |
|
2871 |
|
|
|
2872 | destrevlog._indexfile, b'a+', checkambig=False | |
|
2873 | ) | |
|
2874 | dfh = None | |
|
2875 | if not destrevlog._inline: | |
|
2876 | dfh = destrevlog.opener(destrevlog._datafile, b'a+') | |
|
2877 | try: | |
|
2882 | with destrevlog._writing(tr): | |
|
2878 | 2883 | destrevlog._addrevision( |
|
2879 | 2884 | node, |
|
2880 | 2885 | rawtext, |
@@ -2884,15 +2889,9 b' class revlog(object):' | |||
|
2884 | 2889 | p2, |
|
2885 | 2890 | flags, |
|
2886 | 2891 | cachedelta, |
|
2887 | ifh, | |
|
2888 | dfh, | |
|
2889 | 2892 | deltacomputer=deltacomputer, |
|
2890 | 2893 | sidedata=sidedata, |
|
2891 | 2894 | ) |
|
2892 | finally: | |
|
2893 | if dfh: | |
|
2894 | dfh.close() | |
|
2895 | ifh.close() | |
|
2896 | 2895 | |
|
2897 | 2896 | if addrevisioncb: |
|
2898 | 2897 | addrevisioncb(self, rev, node) |
@@ -91,7 +91,7 b' And no corruption in the changelog.' | |||
|
91 | 91 | $ hg debugrevlogindex -c |
|
92 | 92 | rev linkrev nodeid p1 p2 |
|
93 | 93 | 0 0 222799e2f90b 000000000000 000000000000 |
|
94 | 1 1 6f124f6007a0 222799e2f90b 000000000000 | |
|
94 | 1 1 6f124f6007a0 222799e2f90b 000000000000 (missing-correct-output !) | |
|
95 | 95 | And, because of transactions, there's none in the manifestlog either. |
|
96 | 96 | $ hg debugrevlogindex -m |
|
97 | 97 | rev linkrev nodeid p1 p2 |
@@ -19,6 +19,32 b' from mercurial.revlogutils import (' | |||
|
19 | 19 | flagutil, |
|
20 | 20 | ) |
|
21 | 21 | |
|
22 | ||
|
23 | class _NoTransaction(object): | |
|
24 | """transaction like object to update the nodemap outside a transaction""" | |
|
25 | ||
|
26 | def __init__(self): | |
|
27 | self._postclose = {} | |
|
28 | ||
|
29 | def addpostclose(self, callback_id, callback_func): | |
|
30 | self._postclose[callback_id] = callback_func | |
|
31 | ||
|
32 | def registertmp(self, *args, **kwargs): | |
|
33 | pass | |
|
34 | ||
|
35 | def addbackup(self, *args, **kwargs): | |
|
36 | pass | |
|
37 | ||
|
38 | def add(self, *args, **kwargs): | |
|
39 | pass | |
|
40 | ||
|
41 | def addabort(self, *args, **kwargs): | |
|
42 | pass | |
|
43 | ||
|
44 | def _report(self, *args): | |
|
45 | pass | |
|
46 | ||
|
47 | ||
|
22 | 48 | # TESTTMP is optional. This makes it convenient to run without run-tests.py |
|
23 | 49 | tvfs = vfs.vfs(encoding.environ.get(b'TESTTMP', b'/tmp')) |
|
24 | 50 | |
@@ -201,19 +227,17 b" def lowlevelcopy(rlog, tr, destname=b'_d" | |||
|
201 | 227 | text = None |
|
202 | 228 | cachedelta = (deltaparent, rlog.revdiff(deltaparent, r)) |
|
203 | 229 | flags = rlog.flags(r) |
|
204 | ifh = dfh = None | |
|
205 | try: | |
|
206 | ifh = dlog.opener(dlog._indexfile, b'a+') | |
|
207 | if not dlog._inline: | |
|
208 | dfh = dlog.opener(dlog._datafile, b'a+') | |
|
230 | with dlog._writing(_NoTransaction()): | |
|
209 | 231 | dlog._addrevision( |
|
210 | rlog.node(r), text, tr, r, p1, p2, flags, cachedelta, ifh, dfh | |
|
232 | rlog.node(r), | |
|
233 | text, | |
|
234 | tr, | |
|
235 | r, | |
|
236 | p1, | |
|
237 | p2, | |
|
238 | flags, | |
|
239 | cachedelta, | |
|
211 | 240 | ) |
|
212 | finally: | |
|
213 | if dfh is not None: | |
|
214 | dfh.close() | |
|
215 | if ifh is not None: | |
|
216 | ifh.close() | |
|
217 | 241 | return dlog |
|
218 | 242 | |
|
219 | 243 |
General Comments 0
You need to be logged in to leave comments.
Login now