mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 09:17:30 +03:00
Faster append-only revmap implementation.
This commit is contained in:
parent
b168704b66
commit
4430556e43
@ -440,7 +440,7 @@ def stupid_svn_server_pull_rev(ui, svn, hg_editor, r):
|
|||||||
date,
|
date,
|
||||||
extra)
|
extra)
|
||||||
ha = hg_editor.repo.commitctx(current_ctx)
|
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()
|
hg_editor._save_metadata()
|
||||||
ui.status('committed as %s on branch %s\n' %
|
ui.status('committed as %s on branch %s\n' %
|
||||||
(node.hex(ha), b or 'default'))
|
(node.hex(ha), b or 'default'))
|
||||||
|
@ -49,6 +49,13 @@ def stash_exception_on_self(fn):
|
|||||||
|
|
||||||
|
|
||||||
class HgChangeReceiver(delta.Editor):
|
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='',
|
def __init__(self, path, ui_=None, subdir='', author_host='',
|
||||||
tag_locations=['tags']):
|
tag_locations=['tags']):
|
||||||
"""path is the path to the target hg repo.
|
"""path is the path to the target hg repo.
|
||||||
@ -67,7 +74,13 @@ class HgChangeReceiver(delta.Editor):
|
|||||||
self.revmap = {}
|
self.revmap = {}
|
||||||
if os.path.exists(self.revmap_file):
|
if os.path.exists(self.revmap_file):
|
||||||
f = open(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()
|
f.close()
|
||||||
self.branches = {}
|
self.branches = {}
|
||||||
if os.path.exists(self.branch_info_file):
|
if os.path.exists(self.branch_info_file):
|
||||||
@ -106,6 +119,7 @@ class HgChangeReceiver(delta.Editor):
|
|||||||
else:
|
else:
|
||||||
self.repo = hg.repository(self.ui, repo_path, create=True)
|
self.repo = hg.repository(self.ui, repo_path, create=True)
|
||||||
os.makedirs(os.path.dirname(self.uuid_file))
|
os.makedirs(os.path.dirname(self.uuid_file))
|
||||||
|
open(self.revmap_file, 'w') # make empty file
|
||||||
|
|
||||||
def clear_current_info(self):
|
def clear_current_info(self):
|
||||||
'''Clear the info relevant to a replayed revision so that the next
|
'''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
|
'''Save the Subversion metadata. This should really be called after
|
||||||
every revision is created.
|
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.branches, self.branch_info_file, self.meta_data_dir)
|
||||||
pickle_atomic(self.tags, self.tag_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' %
|
self.ui.status('committed as %s on branch %s\n' %
|
||||||
(node.hex(new_hash), (branch or 'default')))
|
(node.hex(new_hash), (branch or 'default')))
|
||||||
if (rev.revnum, branch) not in self.revmap:
|
if (rev.revnum, branch) not in self.revmap:
|
||||||
self.revmap[rev.revnum, branch] = new_hash
|
self.add_to_revmap(rev.revnum, branch, new_hash)
|
||||||
self._save_metadata()
|
|
||||||
# now we handle branches that need to be committed without any files
|
# now we handle branches that need to be committed without any files
|
||||||
for branch in self.commit_branches_empty:
|
for branch in self.commit_branches_empty:
|
||||||
ha = self.get_parent_revision(rev.revnum, branch)
|
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' %
|
self.ui.status('committed as %s on branch %s\n' %
|
||||||
(node.hex(new_hash), (branch or 'default')))
|
(node.hex(new_hash), (branch or 'default')))
|
||||||
if (rev.revnum, branch) not in self.revmap:
|
if (rev.revnum, branch) not in self.revmap:
|
||||||
self.revmap[rev.revnum, branch] = new_hash
|
self.add_to_revmap(rev.revnum, branch, new_hash)
|
||||||
self._save_metadata()
|
|
||||||
self.clear_current_info()
|
self.clear_current_info()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -64,6 +64,19 @@ def generate_hg_tags(ui, hg_repo_path, **opts):
|
|||||||
source_ha = hg_editor.get_parent_revision(source[1]+1, source[0])
|
source_ha = hg_editor.get_parent_revision(source[1]+1, source[0])
|
||||||
f.write('%s tag/%s\n' % (node.hex(source_ha), tag))
|
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')
|
@register_subcommand('up')
|
||||||
def update(ui, args, repo, clean=False, **opts):
|
def update(ui, args, repo, clean=False, **opts):
|
||||||
"""Update to a specified Subversion revision number.
|
"""Update to a specified Subversion revision number.
|
||||||
@ -72,7 +85,7 @@ def update(ui, args, repo, clean=False, **opts):
|
|||||||
rev = int(args[0])
|
rev = int(args[0])
|
||||||
path = os.path.join(repo.path, 'svn', 'rev_map')
|
path = os.path.join(repo.path, 'svn', 'rev_map')
|
||||||
answers = []
|
answers = []
|
||||||
for k,v in pickle.load(open(path)).iteritems():
|
for k,v in parse_revmap(path).iteritems():
|
||||||
if k[0] == rev:
|
if k[0] == rev:
|
||||||
answers.append((v, k[1]))
|
answers.append((v, k[1]))
|
||||||
if len(answers) == 1:
|
if len(answers) == 1:
|
||||||
@ -139,8 +152,7 @@ def verify_all_revisions(ui, args, repo, **opts):
|
|||||||
args = list(args)
|
args = list(args)
|
||||||
if args:
|
if args:
|
||||||
start_rev = int(args.pop(0))
|
start_rev = int(args.pop(0))
|
||||||
revmap_f = open(os.path.join(repo.path, 'svn', 'rev_map'))
|
revmap = parse_revmap(os.path.join(repo.path, 'svn', 'rev_map'))
|
||||||
revmap = pickle.load(revmap_f)
|
|
||||||
revs = sorted(revmap.keys())
|
revs = sorted(revmap.keys())
|
||||||
for revnum, br in revs:
|
for revnum, br in revs:
|
||||||
if revnum < start_rev:
|
if revnum < start_rev:
|
||||||
|
Loading…
Reference in New Issue
Block a user