81 |
81 |
82 |
82 |
83 def warm_cache(repo): |
83 def warm_cache(repo): |
84 """ensure the cache is properly filled""" |
84 """ensure the cache is properly filled""" |
85 unfi = repo.unfiltered() |
85 unfi = repo.unfiltered() |
86 tonode = unfi.changelog.node |
86 _getfnodes(repo.ui, repo, revs=unfi.changelog.revs()) |
87 nodes = [tonode(r) for r in unfi.changelog.revs()] |
|
88 _getfnodes(repo.ui, repo, nodes) |
|
89 |
87 |
90 |
88 |
91 def fnoderevs(ui, repo, revs): |
89 def fnoderevs(ui, repo, revs): |
92 """return the list of '.hgtags' fnodes used in a set revisions |
90 """return the list of '.hgtags' fnodes used in a set revisions |
93 |
91 |
496 # Caller has to iterate over all heads, but can use the filenodes in |
494 # Caller has to iterate over all heads, but can use the filenodes in |
497 # cachefnode to get to each .hgtags revision quickly. |
495 # cachefnode to get to each .hgtags revision quickly. |
498 return (repoheads, cachefnode, valid, None, True) |
496 return (repoheads, cachefnode, valid, None, True) |
499 |
497 |
500 |
498 |
501 def _getfnodes(ui, repo, nodes): |
499 def _getfnodes(ui, repo, nodes=None, revs=None): |
502 """return .hgtags fnodes for a list of changeset nodes |
500 """return .hgtags fnodes for a list of changeset nodes |
503 |
501 |
504 Return value is a {node: fnode} mapping. There will be no entry for nodes |
502 Return value is a {node: fnode} mapping. There will be no entry for nodes |
505 without a '.hgtags' file. |
503 without a '.hgtags' file. |
506 """ |
504 """ |
508 fnodescache = hgtagsfnodescache(repo.unfiltered()) |
506 fnodescache = hgtagsfnodescache(repo.unfiltered()) |
509 cachefnode = {} |
507 cachefnode = {} |
510 validated_fnodes = set() |
508 validated_fnodes = set() |
511 unknown_entries = set() |
509 unknown_entries = set() |
512 |
510 |
|
511 if nodes is None and revs is None: |
|
512 raise error.ProgrammingError("need to specify either nodes or revs") |
|
513 elif nodes is not None and revs is None: |
|
514 to_rev = repo.changelog.index.rev |
|
515 nodes_revs = ((n, to_rev(n)) for n in nodes) |
|
516 elif nodes is None and revs is not None: |
|
517 to_node = repo.changelog.node |
|
518 nodes_revs = ((to_node(r), r) for r in revs) |
|
519 else: |
|
520 msg = "need to specify only one of nodes or revs" |
|
521 raise error.ProgrammingError(msg) |
|
522 |
513 flog = None |
523 flog = None |
514 for node in nodes: |
524 for node, rev in nodes_revs: |
515 fnode = fnodescache.getfnode(node) |
525 fnode = fnodescache.getfnode(node=node, rev=rev) |
516 if fnode != repo.nullid: |
526 if fnode != repo.nullid: |
517 if fnode not in validated_fnodes: |
527 if fnode not in validated_fnodes: |
518 if flog is None: |
528 if flog is None: |
519 flog = repo.file(b'.hgtags') |
529 flog = repo.file(b'.hgtags') |
520 if flog.hasnode(fnode): |
530 if flog.hasnode(fnode): |
763 if self._dirtyoffset is None: |
773 if self._dirtyoffset is None: |
764 self._dirtyoffset = rawlen |
774 self._dirtyoffset = rawlen |
765 # TODO: zero fill entire record, because it's invalid not missing? |
775 # TODO: zero fill entire record, because it's invalid not missing? |
766 self._raw.extend(b'\xff' * (wantedlen - rawlen)) |
776 self._raw.extend(b'\xff' * (wantedlen - rawlen)) |
767 |
777 |
768 def getfnode(self, node, computemissing=True): |
778 def getfnode(self, node, computemissing=True, rev=None): |
769 """Obtain the filenode of the .hgtags file at a specified revision. |
779 """Obtain the filenode of the .hgtags file at a specified revision. |
770 |
780 |
771 If the value is in the cache, the entry will be validated and returned. |
781 If the value is in the cache, the entry will be validated and returned. |
772 Otherwise, the filenode will be computed and returned unless |
782 Otherwise, the filenode will be computed and returned unless |
773 "computemissing" is False. In that case, None will be returned if |
783 "computemissing" is False. In that case, None will be returned if |
778 returned. |
788 returned. |
779 """ |
789 """ |
780 if node == self._repo.nullid: |
790 if node == self._repo.nullid: |
781 return node |
791 return node |
782 |
792 |
783 rev = self._repo.changelog.rev(node) |
793 if rev is None: |
|
794 rev = self._repo.changelog.rev(node) |
784 |
795 |
785 self.lookupcount += 1 |
796 self.lookupcount += 1 |
786 |
797 |
787 offset = rev * _fnodesrecsize |
798 offset = rev * _fnodesrecsize |
788 record = b'%s' % self._raw[offset : offset + _fnodesrecsize] |
799 record = b'%s' % self._raw[offset : offset + _fnodesrecsize] |