comparison mercurial/manifest.py @ 39521:154e4f84b51c

treemanifest: use visitchildrenset when filtering a manifest to a matcher Differential Revision: https://phab.mercurial-scm.org/D4370
author Kyle Lippincott <spectral@google.com>
date Thu, 23 Aug 2018 00:44:10 -0700
parents c29548ba4a75
children 3ba9ef0fb693
comparison
equal deleted inserted replaced
39520:0612e4c6fda0 39521:154e4f84b51c
708 def _loadlazy(self, d): 708 def _loadlazy(self, d):
709 path, node, readsubtree = self._lazydirs[d] 709 path, node, readsubtree = self._lazydirs[d]
710 self._dirs[d] = readsubtree(path, node) 710 self._dirs[d] = readsubtree(path, node)
711 del self._lazydirs[d] 711 del self._lazydirs[d]
712 712
713 def _loadchildrensetlazy(self, visit):
714 if not visit:
715 return None
716 if visit == 'all' or visit == 'this':
717 self._loadalllazy()
718 return None
719
720 todel = []
721 for k in visit:
722 kslash = k + '/'
723 ld = self._lazydirs.get(kslash)
724 if ld:
725 path, node, readsubtree = ld
726 self._dirs[kslash] = readsubtree(path, node)
727 todel.append(kslash)
728 for kslash in todel:
729 del self._lazydirs[kslash]
730 return visit
731
713 def __len__(self): 732 def __len__(self):
714 self._load() 733 self._load()
715 size = len(self._files) 734 size = len(self._files)
716 self._loadalllazy() 735 self._loadalllazy()
717 for m in self._dirs.values(): 736 for m in self._dirs.values():
1041 1060
1042 def _matches(self, match): 1061 def _matches(self, match):
1043 '''recursively generate a new manifest filtered by the match argument. 1062 '''recursively generate a new manifest filtered by the match argument.
1044 ''' 1063 '''
1045 1064
1046 visit = match.visitdir(self._dir[:-1] or '.') 1065 visit = match.visitchildrenset(self._dir[:-1] or '.')
1047 if visit == 'all': 1066 if visit == 'all':
1048 return self.copy() 1067 return self.copy()
1049 ret = treemanifest(self._dir) 1068 ret = treemanifest(self._dir)
1050 if not visit: 1069 if not visit:
1051 return ret 1070 return ret
1052 1071
1053 self._load() 1072 self._load()
1054 for fn in self._files: 1073 for fn in self._files:
1074 # While visitchildrenset *usually* lists only subdirs, this is
1075 # actually up to the matcher and may have some files in the set().
1076 # If visit == 'this', we should obviously look at the files in this
1077 # directory; if visit is a set, and fn is in it, we should inspect
1078 # fn (but no need to inspect things not in the set).
1079 if visit != 'this' and fn not in visit:
1080 continue
1055 fullp = self._subpath(fn) 1081 fullp = self._subpath(fn)
1082 # visitchildrenset isn't perfect, we still need to call the regular
1083 # matcher code to further filter results.
1056 if not match(fullp): 1084 if not match(fullp):
1057 continue 1085 continue
1058 ret._files[fn] = self._files[fn] 1086 ret._files[fn] = self._files[fn]
1059 if fn in self._flags: 1087 if fn in self._flags:
1060 ret._flags[fn] = self._flags[fn] 1088 ret._flags[fn] = self._flags[fn]
1061 1089
1062 # OPT: use visitchildrenset to avoid loading everything 1090 visit = self._loadchildrensetlazy(visit)
1063 self._loadalllazy()
1064 for dir, subm in self._dirs.iteritems(): 1091 for dir, subm in self._dirs.iteritems():
1092 if visit and dir[:-1] not in visit:
1093 continue
1065 m = subm._matches(match) 1094 m = subm._matches(match)
1066 if not m._isempty(): 1095 if not m._isempty():
1067 ret._dirs[dir] = m 1096 ret._dirs[dir] = m
1068 1097
1069 if not ret._isempty(): 1098 if not ret._isempty():