comparison mercurial/revlog.py @ 47234:616b8f412676

revlogv2: introduce a very basic docket file This is the first stone toward using a docket file in revlogv2. Right now the docket is very basic and only store the version number (which is -also- stored into the index file…) and the other files have fixed name. This new implementation break transactionally… but they are no test checking transactionally for revlogv2… So I take this as an opportunity to start small. They are no usage of revlogv2 outside of tests anyway. The docket keeps the `.i` naming used by previous version index to preserve a unique entry point. We could decide to use a different name and look it up first, or to fully rework this in a future "store" version. However that does not seems necessary right now. We will re-introduces transactionality (and associated testing…) in a later changesets. A long list of TODOs have been added to the relevant comment. Differential Revision: https://phab.mercurial-scm.org/D10624
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Mon, 03 May 2021 12:34:11 +0200
parents 4d1c893b9095
children 6b1eae313b2f
comparison
equal deleted inserted replaced
47233:bcafcd779d2e 47234:616b8f412676
73 repository, 73 repository,
74 util as interfaceutil, 74 util as interfaceutil,
75 ) 75 )
76 from .revlogutils import ( 76 from .revlogutils import (
77 deltas as deltautil, 77 deltas as deltautil,
78 docket as docketutil,
78 flagutil, 79 flagutil,
79 nodemap as nodemaputil, 80 nodemap as nodemaputil,
80 revlogv0, 81 revlogv0,
81 sidedata as sidedatautil, 82 sidedata as sidedatautil,
82 ) 83 )
315 """ 316 """
316 self.upperboundcomp = upperboundcomp 317 self.upperboundcomp = upperboundcomp
317 318
318 self.radix = radix 319 self.radix = radix
319 320
321 self._docket_file = None
320 self._indexfile = None 322 self._indexfile = None
321 self._datafile = None 323 self._datafile = None
322 self._nodemap_file = None 324 self._nodemap_file = None
323 self.postfix = postfix 325 self.postfix = postfix
324 self.opener = opener 326 self.opener = opener
342 # How much data to read and cache into the raw revlog data cache. 344 # How much data to read and cache into the raw revlog data cache.
343 self._chunkcachesize = 65536 345 self._chunkcachesize = 65536
344 self._maxchainlen = None 346 self._maxchainlen = None
345 self._deltabothparents = True 347 self._deltabothparents = True
346 self.index = None 348 self.index = None
349 self._docket = None
347 self._nodemap_docket = None 350 self._nodemap_docket = None
348 # Mapping of partial identifiers to full nodes. 351 # Mapping of partial identifiers to full nodes.
349 self._pcache = {} 352 self._pcache = {}
350 # Mapping of revision integer to full node. 353 # Mapping of revision integer to full node.
351 self._compengine = b'zlib' 354 self._compengine = b'zlib'
503 features = FEATURES_BY_VERSION[self._format_version] 506 features = FEATURES_BY_VERSION[self._format_version]
504 self._inline = features[b'inline'](self._format_flags) 507 self._inline = features[b'inline'](self._format_flags)
505 self._generaldelta = features[b'generaldelta'](self._format_flags) 508 self._generaldelta = features[b'generaldelta'](self._format_flags)
506 self.hassidedata = features[b'sidedata'] 509 self.hassidedata = features[b'sidedata']
507 510
508 index_data = entry_data 511 if not features[b'docket']:
509 self._indexfile = entry_point 512 self._indexfile = entry_point
513 index_data = entry_data
514 else:
515 self._docket_file = entry_point
516 if self._initempty:
517 self._docket = docketutil.default_docket(self, header)
518 else:
519 self._docket = docketutil.parse_docket(self, entry_data)
520 self._indexfile = self._docket.index_filepath()
521 index_data = self._get_data(self._indexfile, mmapindexthreshold)
522 self._inline = False
523 # generaldelta implied by version 2 revlogs.
524 self._generaldelta = True
525 # the logic for persistent nodemap will be dealt with within the
526 # main docket, so disable it for now.
527 self._nodemap_file = None
510 528
511 if self.postfix is None or self.postfix == b'a': 529 if self.postfix is None or self.postfix == b'a':
512 self._datafile = b'%s.d' % self.radix 530 self._datafile = b'%s.d' % self.radix
513 else: 531 else:
514 self._datafile = b'%s.d.%s' % (self.radix, self.postfix) 532 self._datafile = b'%s.d.%s' % (self.radix, self.postfix)
2051 transaction.add(self._indexfile, isize) 2069 transaction.add(self._indexfile, isize)
2052 try: 2070 try:
2053 self._writinghandles = (ifh, dfh) 2071 self._writinghandles = (ifh, dfh)
2054 try: 2072 try:
2055 yield 2073 yield
2074 if self._docket is not None:
2075 self._docket.write(transaction)
2056 finally: 2076 finally:
2057 self._writinghandles = None 2077 self._writinghandles = None
2058 finally: 2078 finally:
2059 ifh.close() 2079 ifh.close()
2060 finally: 2080 finally:
3124 return d 3144 return d
3125 3145
3126 def rewrite_sidedata(self, transaction, helpers, startrev, endrev): 3146 def rewrite_sidedata(self, transaction, helpers, startrev, endrev):
3127 if not self.hassidedata: 3147 if not self.hassidedata:
3128 return 3148 return
3129 # inline are not yet supported because they suffer from an issue when 3149 # revlog formats with sidedata support does not support inline
3130 # rewriting them (since it's not an append-only operation).
3131 # See issue6485.
3132 assert not self._inline 3150 assert not self._inline
3133 if not helpers[1] and not helpers[2]: 3151 if not helpers[1] and not helpers[2]:
3134 # Nothing to generate or remove 3152 # Nothing to generate or remove
3135 return 3153 return
3136 3154