filesystem: move lookup yielding to a batched location

Summary:
In a future diff we'll move lookup resolution into the filesystem
later. To do so, we need to refactor the lookup reporting logic to batch all
lookup reporting into a single place so that later we can insert remotefilelog
prefetches for those files.

This diff moves lookup detection to put them in a list before yielding them. The
next diff will resolve them instead of yielding lookup.

Reviewed By: quark-zju

Differential Revision: D17749375

fbshipit-source-id: 93f383031600525f137039dc955b5e46346754c5
This commit is contained in:
Durham Goode 2019-10-16 17:38:30 -07:00 committed by Facebook Github Bot
parent 815b95c925
commit 376162f3d3
2 changed files with 33 additions and 22 deletions

View File

@ -888,10 +888,17 @@ class fsmonitorfilesystem(filesystem.physicalfilesystem):
match = util.always
self.dirstate._map.preload()
lookups = []
for fn, st in self._fsmonitorwalk(match):
changed = self._ischanged(fn, st)
changed = self._ischanged(fn, st, lookups)
if changed:
yield changed
# Repackage it with a False bit to indicate no lookup necessary.
yield (changed[0], changed[1], False)
# Report all the files that need lookup resolution. This is temporary
# and will be replaced soon.
for fn in lookups:
yield (fn, True, True)
@util.timefunction("fsmonitorwalk", 0, "_ui")
def _fsmonitorwalk(self, match):

View File

@ -35,18 +35,18 @@ class physicalfilesystem(object):
self.mtolog = self.ui.configint("experimental", "samplestatus")
self.ltolog = self.mtolog
def _ischanged(self, fn, st):
def _ischanged(self, fn, st, lookups):
try:
t = self.dirstate._map[fn]
except KeyError:
t = ("?", 0, 0, 0)
if st is None:
return (fn, False, False)
return (fn, False)
state = t[0]
if state in "a?":
return (fn, True, False)
return (fn, True)
elif state in "mnr":
# 'm' and 'n' states mean the dirstate is tracking the file, so
# we need to check if it's modified.
@ -92,27 +92,24 @@ class physicalfilesystem(object):
reasons.append("mode changed (%s -> %s)" % (mode, st.st_mode))
self.ui.log("status", "M %s: %s" % (fn, ", ".join(reasons)))
return (fn, True, False)
elif time != st.st_mtime and time != st.st_mtime & _rangemask:
return (fn, True)
elif (
time != st.st_mtime and time != st.st_mtime & _rangemask
) or st.st_mtime == self.dirstate._lastnormaltime:
if self.ltolog:
self.ltolog -= 1
reason = "mtime changed (%s -> %s)" % (time, st.st_mtime)
if st.st_mtime == self.dirstate._lastnormaltime:
reason = "mtime untrusted (%s)" % (st.st_mtime)
else:
reason = "mtime changed (%s -> %s)" % (time, st.st_mtime)
self.ui.log("status", "L %s: %s" % (fn, reason))
return (fn, True, True)
elif st.st_mtime == self.dirstate._lastnormaltime:
# fn may have just been marked as normal and it may have
# changed in the same second without changing its size.
# This can happen if we quickly do multiple commits.
# Force lookup, so we don't miss such a racy file change.
if self.ltolog:
self.ltolog -= 1
reason = "mtime untrusted (%s)" % (st.st_mtime)
self.ui.log("status", "L %s: %s" % (fn, reason))
return (fn, True, True)
lookups.append(fn)
return None
else:
if self.dirstate._istreestate:
self.dirstate.clearneedcheck(fn)
return None
return False
else:
raise error.ProgrammingError(
"filesystem.walk should not yield state '%s' for '%s'" % (state, fn)
@ -141,11 +138,18 @@ class physicalfilesystem(object):
if self.ui.configbool("workingcopy", "enablerustwalker"):
walkfn = self._rustwalk
lookups = []
for fn, st in walkfn(match, listignored):
seen.add(fn)
changed = self._ischanged(fn, st)
changed = self._ischanged(fn, st, lookups)
if changed:
yield changed
# Repackage it with a False bit to indicate no lookup necessary.
yield (changed[0], changed[1], False)
# Report all the files that need lookup resolution. This is temporary
# and will be replaced soon.
for fn in lookups:
yield (fn, True, True)
auditpath = pathutil.pathauditor(self.root, cached=True)