changeset 50515:b08243dbc2e3

store: also gather files per revlog in `topfiles` This conclude out revlog gathering.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Mon, 15 May 2023 08:59:06 +0200
parents d4f54aded22e
children 1fc25227b068
files mercurial/store.py tests/test-persistent-nodemap.t
diffstat 2 files changed, 58 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/store.py	Mon May 15 08:58:49 2023 +0200
+++ b/mercurial/store.py	Mon May 15 08:59:06 2023 +0200
@@ -563,6 +563,23 @@
     return filename[:idx], filename[idx:]
 
 
+def _ext_key(ext):
+    """a key to order revlog suffix
+
+    important to issue .i after other entry."""
+    # the only important part of this order is to keep the `.i` last.
+    if ext.endswith(b'.n'):
+        return (0, ext)
+    elif ext.endswith(b'.nd'):
+        return (10, ext)
+    elif ext.endswith(b'.d'):
+        return (20, ext)
+    elif ext.endswith(b'.i'):
+        return (50, ext)
+    else:
+        return (40, ext)
+
+
 class basicstore:
     '''base class for local repository stores'''
 
@@ -636,34 +653,44 @@
                 )
 
     def topfiles(self) -> Generator[BaseStoreEntry, None, None]:
-        # yield manifest before changelog
-        files = self._walk(b'', False)
-        # key is (type, path) (keeping ordering so we get 00changelog.i last)
-        type_key = lambda x: (x[1][0], x[0])
-        files = sorted(files, reverse=True, key=type_key)
+        files = reversed(self._walk(b'', False))
+
+        changelogs = collections.defaultdict(dict)
+        manifestlogs = collections.defaultdict(dict)
+
         for u, (t, s) in files:
             if u.startswith(b'00changelog'):
-                yield RevlogStoreEntry(
-                    unencoded_path=u,
-                    revlog_type=FILEFLAGS_CHANGELOG,
-                    is_revlog_main=bool(t & FILEFLAGS_REVLOG_MAIN),
-                    is_volatile=bool(t & FILEFLAGS_VOLATILE),
-                    file_size=s,
-                )
+                name, ext = _split_revlog_ext(u)
+                changelogs[name][ext] = (t, s)
             elif u.startswith(b'00manifest'):
-                yield RevlogStoreEntry(
-                    unencoded_path=u,
-                    revlog_type=FILEFLAGS_MANIFESTLOG,
-                    is_revlog_main=bool(t & FILEFLAGS_REVLOG_MAIN),
-                    is_volatile=bool(t & FILEFLAGS_VOLATILE),
-                    file_size=s,
-                )
+                name, ext = _split_revlog_ext(u)
+                manifestlogs[name][ext] = (t, s)
             else:
                 yield SimpleStoreEntry(
                     unencoded_path=u,
                     is_volatile=bool(t & FILEFLAGS_VOLATILE),
                     file_size=s,
                 )
+        # yield manifest before changelog
+        top_rl = [
+            (manifestlogs, FILEFLAGS_MANIFESTLOG),
+            (changelogs, FILEFLAGS_CHANGELOG),
+        ]
+        assert len(manifestlogs) <= 1
+        assert len(changelogs) <= 1
+        for data, revlog_type in top_rl:
+            for revlog, details in sorted(data.items()):
+                # (keeping ordering so we get 00changelog.i last)
+                key = lambda x: _ext_key(x[0])
+                for ext, (t, s) in sorted(details.items(), key=key):
+                    u = revlog + ext
+                    yield RevlogStoreEntry(
+                        unencoded_path=u,
+                        revlog_type=revlog_type,
+                        is_revlog_main=bool(t & FILEFLAGS_REVLOG_MAIN),
+                        is_volatile=bool(t & FILEFLAGS_VOLATILE),
+                        file_size=s,
+                    )
 
     def walk(self, matcher=None) -> Generator[BaseStoreEntry, None, None]:
         """return files related to data storage (ie: revlogs)
--- a/tests/test-persistent-nodemap.t	Mon May 15 08:58:49 2023 +0200
+++ b/tests/test-persistent-nodemap.t	Mon May 15 08:59:06 2023 +0200
@@ -1018,14 +1018,14 @@
   $ hg clone -U --stream ssh://user@dummy/test-repo stream-clone --debug | egrep '00(changelog|manifest)'
   adding [s] 00manifest.n (62 bytes)
   adding [s] 00manifest-*.nd (118 KB) (glob)
+  adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
+  adding [s] 00manifest.d (452 KB) (no-zstd !)
+  adding [s] 00manifest.d (492 KB) (zstd bigendian !)
+  adding [s] 00manifest.i (313 KB)
   adding [s] 00changelog.n (62 bytes)
   adding [s] 00changelog-*.nd (118 KB) (glob)
-  adding [s] 00manifest.d (452 KB) (no-zstd !)
-  adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
-  adding [s] 00manifest.d (492 KB) (zstd bigendian !)
   adding [s] 00changelog.d (360 KB) (no-zstd !)
   adding [s] 00changelog.d (368 KB) (zstd !)
-  adding [s] 00manifest.i (313 KB)
   adding [s] 00changelog.i (313 KB)
   $ ls -1 stream-clone/.hg/store/ | egrep '00(changelog|manifest)(\.n|-.*\.nd)'
   00changelog-*.nd (glob)
@@ -1090,14 +1090,14 @@
   $ cat clone-output
   adding [s] 00manifest.n (62 bytes)
   adding [s] 00manifest-*.nd (118 KB) (glob)
+  adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
+  adding [s] 00manifest.d (452 KB) (no-zstd !)
+  adding [s] 00manifest.d (492 KB) (zstd bigendian !)
+  adding [s] 00manifest.i (313 KB)
   adding [s] 00changelog.n (62 bytes)
   adding [s] 00changelog-*.nd (118 KB) (glob)
-  adding [s] 00manifest.d (452 KB) (no-zstd !)
-  adding [s] 00manifest.d (491 KB) (zstd no-bigendian !)
-  adding [s] 00manifest.d (492 KB) (zstd bigendian !)
+  adding [s] 00changelog.d (368 KB) (zstd !)
   adding [s] 00changelog.d (360 KB) (no-zstd !)
-  adding [s] 00changelog.d (368 KB) (zstd !)
-  adding [s] 00manifest.i (313 KB)
   adding [s] 00changelog.i (313 KB)
 
 Check the result state
@@ -1195,13 +1195,13 @@
   $ cat clone-output-2
   adding [s] 00manifest.n (62 bytes)
   adding [s] 00manifest-*.nd (118 KB) (glob)
-  adding [s] 00changelog.n (62 bytes)
-  adding [s] 00changelog-*.nd (118 KB) (glob)
   adding [s] 00manifest.d (492 KB) (zstd !)
   adding [s] 00manifest.d (452 KB) (no-zstd !)
+  adding [s] 00manifest.i (313 KB)
+  adding [s] 00changelog.n (62 bytes)
+  adding [s] 00changelog-*.nd (118 KB) (glob)
   adding [s] 00changelog.d (360 KB) (no-zstd !)
   adding [s] 00changelog.d (368 KB) (zstd !)
-  adding [s] 00manifest.i (313 KB)
   adding [s] 00changelog.i (313 KB)
 
 Check the result.