# HG changeset patch # User Pierre-Yves David # Date 1684133913 -7200 # Node ID 5217e36356bbb95541be16296a713f33552a176e # Parent 1c0244a8cdaf82aa4693e092675fddaec630f559 store: add logic to group revlog file together For now each file get its own entry, this will help stopping this, soon™. We use such gathering in the `basicstore` code. diff -r 1c0244a8cdaf -r 5217e36356bb mercurial/store.py --- a/mercurial/store.py Mon May 15 08:58:16 2023 +0200 +++ b/mercurial/store.py Mon May 15 08:58:33 2023 +0200 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. - +import collections import functools import os import re @@ -395,6 +395,13 @@ b'.nd', b'.sda', ) +# file extension that also use a `-SOMELONGIDHASH.ext` form +REVLOG_FILES_LONG_EXT = ( + b'.nd', + b'.idx', + b'.dat', + b'.sda', +) # files that are "volatile" and might change between listing and streaming # # note: the ".nd" file are nodemap data and won't "change" but they might be @@ -532,6 +539,30 @@ return 0 +def _gather_revlog(files_data): + """group files per revlog prefix + + The returns a two level nested dict. The top level key is the revlog prefix + without extension, the second level is all the file "suffix" that were + seen for this revlog and arbitrary file data as value. + """ + revlogs = collections.defaultdict(dict) + for u, value in files_data: + name, ext = _split_revlog_ext(u) + revlogs[name][ext] = value + return sorted(revlogs.items()) + + +def _split_revlog_ext(filename): + """split the revlog file prefix from the variable extension""" + if filename.endswith(REVLOG_FILES_LONG_EXT): + char = b'-' + else: + char = b'.' + idx = filename.rfind(char) + return filename[:idx], filename[idx:] + + class basicstore: '''base class for local repository stores''' @@ -592,8 +623,10 @@ be a list and the filenames that can't be decoded are added to it instead. This is very rarely needed.""" files = self._walk(b'data', True) + self._walk(b'meta', True) - for u, (t, s) in files: - if t is not None: + files = (f for f in files if f[1][0] is not None) + for revlog, details in _gather_revlog(files): + for ext, (t, s) in sorted(details.items()): + u = revlog + ext yield RevlogStoreEntry( unencoded_path=u, revlog_type=FILEFLAGS_FILELOG,