Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlog.py @ 30001:b5e5ddf48bd2
revlog: specify checkambig at writing to avoid file stat ambiguity
This allows revlog-style files to be written out with checkambig=True
easily.
Because avoiding file stat ambiguity is needed only for filecache-ed
manifest and changelog, this patch does:
- use False for default value of checkambig
- focus only on writing changes of index file out
This patch also adds optional argument checkambig to _divert/_delay
for changelog, to safely accept checkambig specified in revlog
layer. But this argument can be fully ignored, because:
- changes are written into other than index file, if name != target
- changes are never written into index file, otherwise
(into pending file by _divert, or into in-memory buffer by _delay)
This is a part of ExactCacheValidationPlan.
https://www.mercurial-scm.org/wiki/ExactCacheValidationPlan
author | FUJIWARA Katsunori <foozy@lares.dti.ne.jp> |
---|---|
date | Thu, 22 Sep 2016 21:51:58 +0900 |
parents | 92ac2baaea86 |
children | d81fe5af92b8 |
comparison
equal
deleted
inserted
replaced
30000:9766d88c2465 | 30001:b5e5ddf48bd2 |
---|---|
210 | 210 |
211 Both pieces of the revlog are written to in an append-only | 211 Both pieces of the revlog are written to in an append-only |
212 fashion, which means we never need to rewrite a file to insert or | 212 fashion, which means we never need to rewrite a file to insert or |
213 remove data, and can use some simple techniques to avoid the need | 213 remove data, and can use some simple techniques to avoid the need |
214 for locking while reading. | 214 for locking while reading. |
215 | |
216 If checkambig, indexfile is opened with checkambig=True at | |
217 writing, to avoid file stat ambiguity. | |
215 """ | 218 """ |
216 def __init__(self, opener, indexfile): | 219 def __init__(self, opener, indexfile, checkambig=False): |
217 """ | 220 """ |
218 create a revlog object | 221 create a revlog object |
219 | 222 |
220 opener is a function that abstracts the file opening operation | 223 opener is a function that abstracts the file opening operation |
221 and can be used to implement COW semantics or the like. | 224 and can be used to implement COW semantics or the like. |
222 """ | 225 """ |
223 self.indexfile = indexfile | 226 self.indexfile = indexfile |
224 self.datafile = indexfile[:-2] + ".d" | 227 self.datafile = indexfile[:-2] + ".d" |
225 self.opener = opener | 228 self.opener = opener |
229 # When True, indexfile is opened with checkambig=True at writing, to | |
230 # avoid file stat ambiguity. | |
231 self._checkambig = checkambig | |
226 # 3-tuple of (node, rev, text) for a raw revision. | 232 # 3-tuple of (node, rev, text) for a raw revision. |
227 self._cache = None | 233 self._cache = None |
228 # Maps rev to chain base rev. | 234 # Maps rev to chain base rev. |
229 self._chainbasecache = util.lrucachedict(100) | 235 self._chainbasecache = util.lrucachedict(100) |
230 # 2-tuple of (offset, data) of raw data from the revlog at an offset. | 236 # 2-tuple of (offset, data) of raw data from the revlog at an offset. |
1274 for r in self: | 1280 for r in self: |
1275 df.write(self._chunkraw(r, r)[1]) | 1281 df.write(self._chunkraw(r, r)[1]) |
1276 finally: | 1282 finally: |
1277 df.close() | 1283 df.close() |
1278 | 1284 |
1279 fp = self.opener(self.indexfile, 'w', atomictemp=True) | 1285 fp = self.opener(self.indexfile, 'w', atomictemp=True, |
1286 checkambig=self._checkambig) | |
1280 self.version &= ~(REVLOGNGINLINEDATA) | 1287 self.version &= ~(REVLOGNGINLINEDATA) |
1281 self._inline = False | 1288 self._inline = False |
1282 for i in self: | 1289 for i in self: |
1283 e = self._io.packentry(self.index[i], self.node, self.version, i) | 1290 e = self._io.packentry(self.index[i], self.node, self.version, i) |
1284 fp.write(e) | 1291 fp.write(e) |
1317 return node | 1324 return node |
1318 | 1325 |
1319 dfh = None | 1326 dfh = None |
1320 if not self._inline: | 1327 if not self._inline: |
1321 dfh = self.opener(self.datafile, "a+") | 1328 dfh = self.opener(self.datafile, "a+") |
1322 ifh = self.opener(self.indexfile, "a+") | 1329 ifh = self.opener(self.indexfile, "a+", checkambig=self._checkambig) |
1323 try: | 1330 try: |
1324 return self._addrevision(node, text, transaction, link, p1, p2, | 1331 return self._addrevision(node, text, transaction, link, p1, p2, |
1325 REVIDX_DEFAULT_FLAGS, cachedelta, ifh, dfh) | 1332 REVIDX_DEFAULT_FLAGS, cachedelta, ifh, dfh) |
1326 finally: | 1333 finally: |
1327 if dfh: | 1334 if dfh: |
1565 | 1572 |
1566 r = len(self) | 1573 r = len(self) |
1567 end = 0 | 1574 end = 0 |
1568 if r: | 1575 if r: |
1569 end = self.end(r - 1) | 1576 end = self.end(r - 1) |
1570 ifh = self.opener(self.indexfile, "a+") | 1577 ifh = self.opener(self.indexfile, "a+", checkambig=self._checkambig) |
1571 isize = r * self._io.size | 1578 isize = r * self._io.size |
1572 if self._inline: | 1579 if self._inline: |
1573 transaction.add(self.indexfile, end + isize, r) | 1580 transaction.add(self.indexfile, end + isize, r) |
1574 dfh = None | 1581 dfh = None |
1575 else: | 1582 else: |
1639 if not dfh and not self._inline: | 1646 if not dfh and not self._inline: |
1640 # addrevision switched from inline to conventional | 1647 # addrevision switched from inline to conventional |
1641 # reopen the index | 1648 # reopen the index |
1642 ifh.close() | 1649 ifh.close() |
1643 dfh = self.opener(self.datafile, "a+") | 1650 dfh = self.opener(self.datafile, "a+") |
1644 ifh = self.opener(self.indexfile, "a+") | 1651 ifh = self.opener(self.indexfile, "a+", |
1652 checkambig=self._checkambig) | |
1645 finally: | 1653 finally: |
1646 if dfh: | 1654 if dfh: |
1647 dfh.close() | 1655 dfh.close() |
1648 ifh.close() | 1656 ifh.close() |
1649 | 1657 |