Details
Details
- Reviewers
- None
- Group Reviewers
hg-reviewers - Commits
- rHG6770df6e4365: tags: avoid double-reversing a list
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Lint
Lint Skipped - Unit
Unit Tests Skipped
( )
hg-reviewers |
Lint Skipped |
Unit Tests Skipped |
Path | Packages | |||
---|---|---|---|---|
M | mercurial/tags.py (7 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
Martin von Zweigbergk | May 3 2019, 3:32 PM |
def fnoderevs(ui, repo, revs): | def fnoderevs(ui, repo, revs): | ||||
"""return the list of '.hgtags' fnodes used in a set revisions | """return the list of '.hgtags' fnodes used in a set revisions | ||||
This is returned as list of unique fnodes. We use a list instead of a set | This is returned as list of unique fnodes. We use a list instead of a set | ||||
because order matters when it comes to tags.""" | because order matters when it comes to tags.""" | ||||
unfi = repo.unfiltered() | unfi = repo.unfiltered() | ||||
tonode = unfi.changelog.node | tonode = unfi.changelog.node | ||||
nodes = [tonode(r) for r in revs] | nodes = [tonode(r) for r in revs] | ||||
fnodes = _getfnodes(ui, repo, nodes[::-1]) # reversed help the cache | fnodes = _getfnodes(ui, repo, nodes) | ||||
fnodes = _filterfnodes(fnodes, nodes) | fnodes = _filterfnodes(fnodes, nodes) | ||||
return fnodes | return fnodes | ||||
def _nulltonone(value): | def _nulltonone(value): | ||||
"""convert nullid to None | """convert nullid to None | ||||
For tag value, nullid means "deleted". This small utility function helps | For tag value, nullid means "deleted". This small utility function helps | ||||
translating that to None.""" | translating that to None.""" | ||||
# potentially expensive search. | # potentially expensive search. | ||||
return ([], {}, valid, None, True) | return ([], {}, valid, None, True) | ||||
# Now we have to lookup the .hgtags filenode for every new head. | # Now we have to lookup the .hgtags filenode for every new head. | ||||
# This is the most expensive part of finding tags, so performance | # This is the most expensive part of finding tags, so performance | ||||
# depends primarily on the size of newheads. Worst case: no cache | # depends primarily on the size of newheads. Worst case: no cache | ||||
# file, so newheads == repoheads. | # file, so newheads == repoheads. | ||||
cachefnode = _getfnodes(ui, repo, repoheads) | # Reversed order helps the cache ('repoheads' is in descending order) | ||||
cachefnode = _getfnodes(ui, repo, reversed(repoheads)) | |||||
# Caller has to iterate over all heads, but can use the filenodes in | # Caller has to iterate over all heads, but can use the filenodes in | ||||
# cachefnode to get to each .hgtags revision quickly. | # cachefnode to get to each .hgtags revision quickly. | ||||
return (repoheads, cachefnode, valid, None, True) | return (repoheads, cachefnode, valid, None, True) | ||||
def _getfnodes(ui, repo, nodes): | def _getfnodes(ui, repo, nodes): | ||||
"""return .hgtags fnodes for a list of changeset nodes | """return .hgtags fnodes for a list of changeset nodes | ||||
Return value is a {node: fnode} mapping. There will be no entry for nodes | Return value is a {node: fnode} mapping. There will be no entry for nodes | ||||
without a '.hgtags' file. | without a '.hgtags' file. | ||||
""" | """ | ||||
starttime = util.timer() | starttime = util.timer() | ||||
fnodescache = hgtagsfnodescache(repo.unfiltered()) | fnodescache = hgtagsfnodescache(repo.unfiltered()) | ||||
cachefnode = {} | cachefnode = {} | ||||
for node in reversed(nodes): | for node in nodes: | ||||
fnode = fnodescache.getfnode(node) | fnode = fnodescache.getfnode(node) | ||||
if fnode != nullid: | if fnode != nullid: | ||||
cachefnode[node] = fnode | cachefnode[node] = fnode | ||||
fnodescache.write() | fnodescache.write() | ||||
duration = util.timer() - starttime | duration = util.timer() - starttime | ||||
ui.log('tagscache', | ui.log('tagscache', |