# HG changeset patch # User Andreas Hartmetz # Date 1224121668 14400 # Node ID a9c15cae50e57225d489de9166c6b8f2aef26230 # Parent d01196ca1e39295031ecda76614baed02fa17ac3 Faster append-only revmap implementation. diff --git a/fetch_command.py b/fetch_command.py --- a/fetch_command.py +++ b/fetch_command.py @@ -440,7 +440,7 @@ def stupid_svn_server_pull_rev(ui, svn, date, extra) ha = hg_editor.repo.commitctx(current_ctx) - hg_editor.revmap[r.revnum, b] = ha + hg_editor.add_to_revmap(r.revnum, b, ha) hg_editor._save_metadata() ui.status('committed as %s on branch %s\n' % (node.hex(ha), b or 'default')) diff --git a/hg_delta_editor.py b/hg_delta_editor.py --- a/hg_delta_editor.py +++ b/hg_delta_editor.py @@ -49,6 +49,13 @@ def stash_exception_on_self(fn): class HgChangeReceiver(delta.Editor): + def add_to_revmap(self, revnum, branch, node_hash): + f = open(self.revmap_file, 'a') + f.write(str(revnum) + ' ' + node.hex(node_hash) + ' ' + (branch or '') + '\n') + f.flush() + f.close() + self.revmap[revnum, branch] = node_hash + def __init__(self, path, ui_=None, subdir='', author_host='', tag_locations=['tags']): """path is the path to the target hg repo. @@ -67,7 +74,13 @@ class HgChangeReceiver(delta.Editor): self.revmap = {} if os.path.exists(self.revmap_file): f = open(self.revmap_file) - self.revmap = pickle.load(f) + for l in f: + revnum, node_hash, branch = l.split(' ', 2) + if branch == '\n': + branch = None + else: + branch = branch[:-1] + self.revmap[int(revnum), branch] = node.bin(node_hash) f.close() self.branches = {} if os.path.exists(self.branch_info_file): @@ -106,6 +119,7 @@ class HgChangeReceiver(delta.Editor): else: self.repo = hg.repository(self.ui, repo_path, create=True) os.makedirs(os.path.dirname(self.uuid_file)) + open(self.revmap_file, 'w') # make empty file def clear_current_info(self): '''Clear the info relevant to a replayed revision so that the next @@ -124,7 +138,6 @@ class HgChangeReceiver(delta.Editor): '''Save the Subversion metadata. This should really be called after every revision is created. ''' - pickle_atomic(self.revmap, self.revmap_file, self.meta_data_dir) pickle_atomic(self.branches, self.branch_info_file, self.meta_data_dir) pickle_atomic(self.tags, self.tag_info_file, self.meta_data_dir) @@ -373,8 +386,7 @@ class HgChangeReceiver(delta.Editor): self.ui.status('committed as %s on branch %s\n' % (node.hex(new_hash), (branch or 'default'))) if (rev.revnum, branch) not in self.revmap: - self.revmap[rev.revnum, branch] = new_hash - self._save_metadata() + self.add_to_revmap(rev.revnum, branch, new_hash) # now we handle branches that need to be committed without any files for branch in self.commit_branches_empty: ha = self.get_parent_revision(rev.revnum, branch) @@ -403,8 +415,7 @@ class HgChangeReceiver(delta.Editor): self.ui.status('committed as %s on branch %s\n' % (node.hex(new_hash), (branch or 'default'))) if (rev.revnum, branch) not in self.revmap: - self.revmap[rev.revnum, branch] = new_hash - self._save_metadata() + self.add_to_revmap(rev.revnum, branch, new_hash) self.clear_current_info() @property diff --git a/svncommand.py b/svncommand.py --- a/svncommand.py +++ b/svncommand.py @@ -64,6 +64,19 @@ def generate_hg_tags(ui, hg_repo_path, * source_ha = hg_editor.get_parent_revision(source[1]+1, source[0]) f.write('%s tag/%s\n' % (node.hex(source_ha), tag)) +def parse_revmap(revmap_filename): + revmap = {} + f = open(revmap_filename) + for l in f: + revnum, node_hash, branch = l.split(' ', 2) + if branch == '\n': + branch = None + else: + branch = branch[:-1] + revmap[int(revnum), branch] = node.bin(node_hash) + f.close() + return revmap + @register_subcommand('up') def update(ui, args, repo, clean=False, **opts): """Update to a specified Subversion revision number. @@ -72,7 +85,7 @@ def update(ui, args, repo, clean=False, rev = int(args[0]) path = os.path.join(repo.path, 'svn', 'rev_map') answers = [] - for k,v in pickle.load(open(path)).iteritems(): + for k,v in parse_revmap(path).iteritems(): if k[0] == rev: answers.append((v, k[1])) if len(answers) == 1: @@ -139,8 +152,7 @@ def verify_all_revisions(ui, args, repo, args = list(args) if args: start_rev = int(args.pop(0)) - revmap_f = open(os.path.join(repo.path, 'svn', 'rev_map')) - revmap = pickle.load(revmap_f) + revmap = parse_revmap(os.path.join(repo.path, 'svn', 'rev_map')) revs = sorted(revmap.keys()) for revnum, br in revs: if revnum < start_rev: