Mercurial > public > mercurial-scm > hg
comparison mercurial/revlogutils/nodemap.py @ 44312:563dfdfd01a4
nodemap: delete older raw data file when creating a new ones
When we write new full files, it replace an older one with a different name. We
add the associated cleanup for the older file to be removed after the
transaction.
We delete all file matching the expected pattern to give use extra chance to
delete orphan files we might have failed to delete earlier.
Note: eventually we won't rewrite all data for each transaction. This is coming
in later changesets.
Differential Revision: https://phab.mercurial-scm.org/D7839
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 15 Jan 2020 15:47:59 +0100 |
parents | 2b72c4ff8ed1 |
children | 7f4f7ef3133e |
comparison
equal
deleted
inserted
replaced
44311:2b72c4ff8ed1 | 44312:563dfdfd01a4 |
---|---|
7 # GNU General Public License version 2 or any later version. | 7 # GNU General Public License version 2 or any later version. |
8 | 8 |
9 from __future__ import absolute_import | 9 from __future__ import absolute_import |
10 | 10 |
11 import os | 11 import os |
12 import re | |
12 import struct | 13 import struct |
13 | 14 |
14 from .. import ( | 15 from .. import ( |
15 error, | 16 error, |
16 node as nodemod, | 17 node as nodemod, |
69 msg = "calling persist nodemap on a revlog without the feature enableb" | 70 msg = "calling persist nodemap on a revlog without the feature enableb" |
70 raise error.ProgrammingError(msg) | 71 raise error.ProgrammingError(msg) |
71 data = persistent_data(revlog.index) | 72 data = persistent_data(revlog.index) |
72 uid = _make_uid() | 73 uid = _make_uid() |
73 datafile = _rawdata_filepath(revlog, uid) | 74 datafile = _rawdata_filepath(revlog, uid) |
75 olds = _other_rawdata_filepath(revlog, uid) | |
76 if olds: | |
77 realvfs = getattr(revlog, '_realopener', revlog.opener) | |
78 | |
79 def cleanup(tr): | |
80 for oldfile in olds: | |
81 realvfs.tryunlink(oldfile) | |
82 | |
83 callback_id = b"revlog-cleanup-nodemap-%s" % revlog.nodemap_file | |
84 tr.addpostclose(callback_id, cleanup) | |
74 # EXP-TODO: if this is a cache, this should use a cache vfs, not a | 85 # EXP-TODO: if this is a cache, this should use a cache vfs, not a |
75 # store vfs | 86 # store vfs |
76 with revlog.opener(datafile, b'w') as fd: | 87 with revlog.opener(datafile, b'w') as fd: |
77 fd.write(data) | 88 fd.write(data) |
78 # EXP-TODO: if this is a cache, this should use a cache vfs, not a | 89 # EXP-TODO: if this is a cache, this should use a cache vfs, not a |
132 | 143 |
133 def _rawdata_filepath(revlog, uid): | 144 def _rawdata_filepath(revlog, uid): |
134 """The (vfs relative) nodemap's rawdata file for a given uid""" | 145 """The (vfs relative) nodemap's rawdata file for a given uid""" |
135 prefix = revlog.nodemap_file[:-2] | 146 prefix = revlog.nodemap_file[:-2] |
136 return b"%s-%s.nd" % (prefix, uid) | 147 return b"%s-%s.nd" % (prefix, uid) |
148 | |
149 | |
150 def _other_rawdata_filepath(revlog, uid): | |
151 prefix = revlog.nodemap_file[:-2] | |
152 pattern = re.compile(b"(^|/)%s-[0-9a-f]+\.nd$" % prefix) | |
153 new_file_path = _rawdata_filepath(revlog, uid) | |
154 new_file_name = revlog.opener.basename(new_file_path) | |
155 dirpath = revlog.opener.dirname(new_file_path) | |
156 others = [] | |
157 for f in revlog.opener.listdir(dirpath): | |
158 if pattern.match(f) and f != new_file_name: | |
159 others.append(f) | |
160 return others | |
137 | 161 |
138 | 162 |
139 ### Nodemap Trie | 163 ### Nodemap Trie |
140 # | 164 # |
141 # This is a simple reference implementation to compute and persist a nodemap | 165 # This is a simple reference implementation to compute and persist a nodemap |