Merge branch 'dev' into avoid-isfiles

This commit is contained in:
AUTOMATIC1111
2024-01-04 11:15:50 +03:00
committed by GitHub
4 changed files with 95 additions and 19 deletions

View File

@@ -66,3 +66,73 @@ def truncate_path(target_path, base_path=cwd):
except ValueError:
pass
return abs_target
class MassFileListerCachedDir:
"""A class that caches file metadata for a specific directory."""
def __init__(self, dirname):
self.files = None
self.files_cased = None
self.dirname = dirname
stats = ((x.name, x.stat(follow_symlinks=False)) for x in os.scandir(self.dirname))
files = [(n, s.st_mtime, s.st_ctime) for n, s in stats]
self.files = {x[0].lower(): x for x in files}
self.files_cased = {x[0]: x for x in files}
class MassFileLister:
"""A class that provides a way to check for the existence and mtime/ctile of files without doing more than one stat call per file."""
def __init__(self):
self.cached_dirs = {}
def find(self, path):
"""
Find the metadata for a file at the given path.
Returns:
tuple or None: A tuple of (name, mtime, ctime) if the file exists, or None if it does not.
"""
dirname, filename = os.path.split(path)
cached_dir = self.cached_dirs.get(dirname)
if cached_dir is None:
cached_dir = MassFileListerCachedDir(dirname)
self.cached_dirs[dirname] = cached_dir
stats = cached_dir.files_cased.get(filename)
if stats is not None:
return stats
stats = cached_dir.files.get(filename.lower())
if stats is None:
return None
try:
os_stats = os.stat(path, follow_symlinks=False)
return filename, os_stats.st_mtime, os_stats.st_ctime
except Exception:
return None
def exists(self, path):
"""Check if a file exists at the given path."""
return self.find(path) is not None
def mctime(self, path):
"""
Get the modification and creation times for a file at the given path.
Returns:
tuple: A tuple of (mtime, ctime) if the file exists, or (0, 0) if it does not.
"""
stats = self.find(path)
return (0, 0) if stats is None else stats[1:3]
def reset(self):
"""Clear the cache of all directories."""
self.cached_dirs.clear()