comparison mercurial/manifest.py @ 24403:0e23faa1511c

treemanifest: store directory path in treemanifest nodes This leads to less concatenation while iterating, and it's useful for debugging.
author Martin von Zweigbergk <martinvonz@google.com>
date Mon, 23 Feb 2015 10:57:57 -0800
parents c2287f203ec4
children 96cccf1e3257
comparison
equal deleted inserted replaced
24402:c2287f203ec4 24403:0e23faa1511c
334 return dir + '/', subpath 334 return dir + '/', subpath
335 else: 335 else:
336 return '', f 336 return '', f
337 337
338 class treemanifest(object): 338 class treemanifest(object):
339 def __init__(self, text=''): 339 def __init__(self, dir='', text=''):
340 self._dir = dir
340 self._dirs = {} 341 self._dirs = {}
341 # Using _lazymanifest here is a little slower than plain old dicts 342 # Using _lazymanifest here is a little slower than plain old dicts
342 self._files = {} 343 self._files = {}
343 self._flags = {} 344 self._flags = {}
344 lm = _lazymanifest(text) 345 lm = _lazymanifest(text)
345 for f, n, fl in lm.iterentries(): 346 for f, n, fl in lm.iterentries():
346 self[f] = n 347 self[f] = n
347 if fl: 348 if fl:
348 self.setflag(f, fl) 349 self.setflag(f, fl)
349 350
351 def _subpath(self, path):
352 return self._dir + path
353
350 def __len__(self): 354 def __len__(self):
351 size = len(self._files) 355 size = len(self._files)
352 for m in self._dirs.values(): 356 for m in self._dirs.values():
353 size += m.__len__() 357 size += m.__len__()
354 return size 358 return size
355 359
360 def __str__(self):
361 return '<treemanifest dir=%s>' % self._dir
362
356 def iteritems(self): 363 def iteritems(self):
357 for p, n in sorted(self._dirs.items() + self._files.items()): 364 for p, n in sorted(self._dirs.items() + self._files.items()):
358 if p in self._files: 365 if p in self._files:
359 yield p, n 366 yield self._subpath(p), n
360 else: 367 else:
361 for sf, sn in n.iteritems(): 368 for f, sn in n.iteritems():
362 yield p + sf, sn 369 yield f, sn
363 370
364 def iterkeys(self): 371 def iterkeys(self):
365 for p in sorted(self._dirs.keys() + self._files.keys()): 372 for p in sorted(self._dirs.keys() + self._files.keys()):
366 if p in self._files: 373 if p in self._files:
367 yield p 374 yield self._subpath(p)
368 else: 375 else:
369 for f in self._dirs[p].iterkeys(): 376 for f in self._dirs[p].iterkeys():
370 yield p + f 377 yield f
371 378
372 def keys(self): 379 def keys(self):
373 return list(self.iterkeys()) 380 return list(self.iterkeys())
374 381
375 def __iter__(self): 382 def __iter__(self):
435 def __setitem__(self, f, n): 442 def __setitem__(self, f, n):
436 assert n is not None 443 assert n is not None
437 dir, subpath = _splittopdir(f) 444 dir, subpath = _splittopdir(f)
438 if dir: 445 if dir:
439 if dir not in self._dirs: 446 if dir not in self._dirs:
440 self._dirs[dir] = treemanifest() 447 self._dirs[dir] = treemanifest(self._subpath(dir))
441 self._dirs[dir].__setitem__(subpath, n) 448 self._dirs[dir].__setitem__(subpath, n)
442 else: 449 else:
443 self._files[f] = n 450 self._files[f] = n
444 451
445 def setflag(self, f, flags): 452 def setflag(self, f, flags):
446 """Set the flags (symlink, executable) for path f.""" 453 """Set the flags (symlink, executable) for path f."""
447 dir, subpath = _splittopdir(f) 454 dir, subpath = _splittopdir(f)
448 if dir: 455 if dir:
449 if dir not in self._dirs: 456 if dir not in self._dirs:
450 self._dirs[dir] = treemanifest() 457 self._dirs[dir] = treemanifest(self._subpath(dir))
451 self._dirs[dir].setflag(subpath, flags) 458 self._dirs[dir].setflag(subpath, flags)
452 else: 459 else:
453 self._flags[f] = flags 460 self._flags[f] = flags
454 461
455 def copy(self): 462 def copy(self):
456 copy = treemanifest() 463 copy = treemanifest(self._dir)
457 for d in self._dirs: 464 for d in self._dirs:
458 copy._dirs[d] = self._dirs[d].copy() 465 copy._dirs[d] = self._dirs[d].copy()
459 copy._files = dict.copy(self._files) 466 copy._files = dict.copy(self._files)
460 copy._flags = dict.copy(self._flags) 467 copy._flags = dict.copy(self._flags)
461 return copy 468 return copy
565 revlog.revlog.__init__(self, opener, "00manifest.i") 572 revlog.revlog.__init__(self, opener, "00manifest.i")
566 self._usetreemanifest = usetreemanifest 573 self._usetreemanifest = usetreemanifest
567 574
568 def _newmanifest(self, data=''): 575 def _newmanifest(self, data=''):
569 if self._usetreemanifest: 576 if self._usetreemanifest:
570 return treemanifest(data) 577 return treemanifest('', data)
571 return manifestdict(data) 578 return manifestdict(data)
572 579
573 def readdelta(self, node): 580 def readdelta(self, node):
574 r = self.rev(node) 581 r = self.rev(node)
575 d = mdiff.patchtext(self.revdiff(self.deltaparent(r), r)) 582 d = mdiff.patchtext(self.revdiff(self.deltaparent(r), r))