Design of persistent tag cache

Matt Mackall mpm at selenic.com
Wed Jul 8 12:39:20 CDT 2009


On Wed, 2009-07-08 at 12:33 -0400, Greg Ward wrote:
> [me, on Matt's tag cache design]
> >>   <headnode> <headrev> <tagnode>
> >>   [...repeat: 1 line per head...]
> >>
> >>   <node> <tag>
> >>   [...repeat: 1 line per tag...]
> >>
> >> Good things about this design:
> >>   * it's easy to detect if the entire cache is still valid: if the set
> >> of heads in the cache == the current repo heads, the cache is all good
> >> and we don't have to read any .hgtags files
> 
> [Matt reminds me]
> > We can do better. If the tip is stored correctly in the cache, we can
> > assume all the other heads are correct.
> 
> Sure, but that's a second-order optimization.  Given the proposed
> structure of the cache file, we still have to read the whole thing.
> Comparing tips just means we can test "cacheheads[0] ==
> currentheads[0]" and possibly skip comparing the whole lists.  And we
> don't have to store all the cached heads in a list anywhere.  Compared
> the cost of what we're *really* trying to avoid, this is small change.

True. But not calling heads can mean the difference between taking .5s
and .01s.

> > This ignores mq/strip, which
> > will have to invalidate/update the cache for all the rules it breaks.
> 
> On reflection, I think that rollback is equivalent to strip from the
> POV of tag caching. They can both destroy one or more changesets, they
> both remove a head, and they can possibly expose older heads.
> 
> So I think that whatever I do to handle strip also needs to be done
> for rollback.

Yes. I think the most reasonable thing to do here is to use the cache to
avoid manifest reads of all the still-good heads. Which is the same as
I'd expect we'd do for changing heads by adding csets. I think this can
be deferred until tags are actually needed? The algorithm might look
like this:

heads, tags = readcache()
if heads[0] == tip:
    return tags
# things have changed, need to refresh cache
newheads = []
for h in self.heads():
    if h in heads:
        # copy revision info from old heads
    else:
	# lookup relevant .hgtags in manifest
# read unique .hgtags revs to build tags

-- 
http://selenic.com : development and support for Mercurial and Linux




More information about the Mercurial-devel mailing list