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', | ||||