##// END OF EJS Templates
treemanifest: rework lazy-copying code (issue4840)...
Augie Fackler -
r26402:05871262 default
parent child Browse files
Show More
@@ -442,13 +442,14 b' def _splittopdir(f):'
442 442 else:
443 443 return '', f
444 444
445 _noop = lambda: None
445 _noop = lambda s: None
446 446
447 447 class treemanifest(object):
448 448 def __init__(self, dir='', text=''):
449 449 self._dir = dir
450 450 self._node = revlog.nullid
451 self._load = _noop
451 self._loadfunc = _noop
452 self._copyfunc = _noop
452 453 self._dirty = False
453 454 self._dirs = {}
454 455 # Using _lazymanifest here is a little slower than plain old dicts
@@ -479,7 +480,7 b' class treemanifest(object):'
479 480 def __repr__(self):
480 481 return ('<treemanifest dir=%s, node=%s, loaded=%s, dirty=%s at 0x%x>' %
481 482 (self._dir, revlog.hex(self._node),
482 bool(self._load is _noop),
483 bool(self._loadfunc is _noop),
483 484 self._dirty, id(self)))
484 485
485 486 def dir(self):
@@ -598,6 +599,14 b' class treemanifest(object):'
598 599 self._files[f] = n[:21] # to match manifestdict's behavior
599 600 self._dirty = True
600 601
602 def _load(self):
603 if self._loadfunc is not _noop:
604 lf, self._loadfunc = self._loadfunc, _noop
605 lf(self)
606 elif self._copyfunc is not _noop:
607 cf, self._copyfunc = self._copyfunc, _noop
608 cf(self)
609
601 610 def setflag(self, f, flags):
602 611 """Set the flags (symlink, executable) for path f."""
603 612 assert 'd' not in flags
@@ -615,19 +624,19 b' class treemanifest(object):'
615 624 copy = treemanifest(self._dir)
616 625 copy._node = self._node
617 626 copy._dirty = self._dirty
618 def _load_for_copy():
627 if self._copyfunc is _noop:
628 def _copyfunc(s):
619 629 self._load()
620 630 for d in self._dirs:
621 copy._dirs[d] = self._dirs[d].copy()
622 copy._files = dict.copy(self._files)
623 copy._flags = dict.copy(self._flags)
624 copy._load = _noop
625 copy._load = _load_for_copy
626 if self._load == _noop:
627 # Chaining _load if it's _noop is functionally correct, but the
628 # chain may end up excessively long (stack overflow), and
629 # will prevent garbage collection of 'self'.
630 copy._load()
631 s._dirs[d] = self._dirs[d].copy()
632 s._files = dict.copy(self._files)
633 s._flags = dict.copy(self._flags)
634 if self._loadfunc is _noop:
635 _copyfunc(copy)
636 else:
637 copy._copyfunc = _copyfunc
638 else:
639 copy._copyfunc = self._copyfunc
631 640 return copy
632 641
633 642 def filesnotin(self, m2):
@@ -834,13 +843,10 b' class treemanifest(object):'
834 843 return _text(sorted(dirs + files), usemanifestv2)
835 844
836 845 def read(self, gettext, readsubtree):
837 def _load_for_read():
838 # Mark as loaded already here, so __setitem__ and setflag() don't
839 # cause infinite loops when they try to load.
840 self._load = _noop
841 self.parse(gettext(), readsubtree)
842 self._dirty = False
843 self._load = _load_for_read
846 def _load_for_read(s):
847 s.parse(gettext(), readsubtree)
848 s._dirty = False
849 self._loadfunc = _load_for_read
844 850
845 851 def writesubtrees(self, m1, m2, writesubtree):
846 852 self._load() # for consistency; should never have any effect here
General Comments 0
You need to be logged in to leave comments. Login now