comparison mercurial/localrepo.py @ 14936:9dca7653b525

localrepo: unify tag related info into a tagscache class
author Idan Kamara <idankk86@gmail.com>
date Mon, 25 Jul 2011 15:08:57 +0300
parents 4ae7473f5b73
children 774da7121fc9
comparison
equal deleted inserted replaced
14935:4ae7473f5b73 14936:9dca7653b525
95 self.opener.createmode = self.store.createmode 95 self.opener.createmode = self.store.createmode
96 self._applyrequirements(requirements) 96 self._applyrequirements(requirements)
97 if create: 97 if create:
98 self._writerequirements() 98 self._writerequirements()
99 99
100 # These two define the set of tags for this repository. _tags
101 # maps tag name to node; _tagtypes maps tag name to 'global' or
102 # 'local'. (Global tags are defined by .hgtags across all
103 # heads, and local tags are defined in .hg/localtags.) They
104 # constitute the in-memory cache of tags.
105 self._tags = None
106 self._tagtypes = None
107 100
108 self._branchcache = None 101 self._branchcache = None
109 self._branchcachetip = None 102 self._branchcachetip = None
110 self.nodetagscache = None
111 self.filterpats = {} 103 self.filterpats = {}
112 self._datafilters = {} 104 self._datafilters = {}
113 self._transref = self._lockref = self._wlockref = None 105 self._transref = self._lockref = self._wlockref = None
114 106
115 # A cache for various files under .hg/ that tracks file changes, 107 # A cache for various files under .hg/ that tracks file changes,
266 fp.seek(0, 2) 258 fp.seek(0, 2)
267 if prevtags and prevtags[-1] != '\n': 259 if prevtags and prevtags[-1] != '\n':
268 fp.write('\n') 260 fp.write('\n')
269 for name in names: 261 for name in names:
270 m = munge and munge(name) or name 262 m = munge and munge(name) or name
271 if self._tagtypes and name in self._tagtypes: 263 if self._tagscache.tagtypes and name in self._tagscache.tagtypes:
272 old = self._tags.get(name, nullid) 264 old = self.tags().get(name, nullid)
273 fp.write('%s %s\n' % (hex(old), m)) 265 fp.write('%s %s\n' % (hex(old), m))
274 fp.write('%s %s\n' % (hex(node), m)) 266 fp.write('%s %s\n' % (hex(node), m))
275 fp.close() 267 fp.close()
276 268
277 prevtags = '' 269 prevtags = ''
342 '(please commit .hgtags manually)')) 334 '(please commit .hgtags manually)'))
343 335
344 self.tags() # instantiate the cache 336 self.tags() # instantiate the cache
345 self._tag(names, node, message, local, user, date) 337 self._tag(names, node, message, local, user, date)
346 338
339 @propertycache
340 def _tagscache(self):
341 '''Returns a tagscache object that contains various tags related caches.'''
342
343 # This simplifies its cache management by having one decorated
344 # function (this one) and the rest simply fetch things from it.
345 class tagscache(object):
346 def __init__(self):
347 # These two define the set of tags for this repository. tags
348 # maps tag name to node; tagtypes maps tag name to 'global' or
349 # 'local'. (Global tags are defined by .hgtags across all
350 # heads, and local tags are defined in .hg/localtags.)
351 # They constitute the in-memory cache of tags.
352 self.tags = self.tagtypes = None
353
354 self.nodetagscache = self.tagslist = None
355
356 cache = tagscache()
357 cache.tags, cache.tagtypes = self._findtags()
358
359 return cache
360
347 def tags(self): 361 def tags(self):
348 '''return a mapping of tag to node''' 362 '''return a mapping of tag to node'''
349 if self._tags is None: 363 return self._tagscache.tags
350 (self._tags, self._tagtypes) = self._findtags()
351
352 return self._tags
353 364
354 def _findtags(self): 365 def _findtags(self):
355 '''Do the hard work of finding tags. Return a pair of dicts 366 '''Do the hard work of finding tags. Return a pair of dicts
356 (tags, tagtypes) where tags maps tag name to node, and tagtypes 367 (tags, tagtypes) where tags maps tag name to node, and tagtypes
357 maps tag name to a string like \'global\' or \'local\'. 368 maps tag name to a string like \'global\' or \'local\'.
396 'local' : a local tag 407 'local' : a local tag
397 'global' : a global tag 408 'global' : a global tag
398 None : tag does not exist 409 None : tag does not exist
399 ''' 410 '''
400 411
401 self.tags() 412 return self._tagscache.tagtypes.get(tagname)
402
403 return self._tagtypes.get(tagname)
404 413
405 def tagslist(self): 414 def tagslist(self):
406 '''return a list of tags ordered by revision''' 415 '''return a list of tags ordered by revision'''
407 l = [] 416 if not self._tagscache.tagslist:
408 for t, n in self.tags().iteritems(): 417 l = []
409 r = self.changelog.rev(n) 418 for t, n in self.tags().iteritems():
410 l.append((r, t, n)) 419 r = self.changelog.rev(n)
411 return [(t, n) for r, t, n in sorted(l)] 420 l.append((r, t, n))
421 self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
422
423 return self._tagscache.tagslist
412 424
413 def nodetags(self, node): 425 def nodetags(self, node):
414 '''return the tags associated with a node''' 426 '''return the tags associated with a node'''
415 if not self.nodetagscache: 427 if not self._tagscache.nodetagscache:
416 self.nodetagscache = {} 428 nodetagscache = {}
417 for t, n in self.tags().iteritems(): 429 for t, n in self.tags().iteritems():
418 self.nodetagscache.setdefault(n, []).append(t) 430 nodetagscache.setdefault(n, []).append(t)
419 for tags in self.nodetagscache.itervalues(): 431 for tags in nodetagscache.itervalues():
420 tags.sort() 432 tags.sort()
421 return self.nodetagscache.get(node, []) 433 self._tagscache.nodetagscache = nodetagscache
434 return self._tagscache.nodetagscache.get(node, [])
422 435
423 def nodebookmarks(self, node): 436 def nodebookmarks(self, node):
424 marks = [] 437 marks = []
425 for bookmark, n in self._bookmarks.iteritems(): 438 for bookmark, n in self._bookmarks.iteritems():
426 if n == node: 439 if n == node:
790 return 1 803 return 1
791 finally: 804 finally:
792 release(lock, wlock) 805 release(lock, wlock)
793 806
794 def invalidatecaches(self): 807 def invalidatecaches(self):
795 self._tags = None 808 try:
796 self._tagtypes = None 809 delattr(self, '_tagscache')
797 self.nodetagscache = None 810 except AttributeError:
811 pass
812
798 self._branchcache = None # in UTF-8 813 self._branchcache = None # in UTF-8
799 self._branchcachetip = None 814 self._branchcachetip = None
800 815
801 def invalidatedirstate(self): 816 def invalidatedirstate(self):
802 '''Invalidates the dirstate, causing the next call to dirstate 817 '''Invalidates the dirstate, causing the next call to dirstate