install: Optimize clean_leftover to gain speed
This improves the installation time of packages that have
lots of files with the same name.
e.g. kernel-module-headers having lots of files named
"Makefile" and "Kconfig".
This commit is contained in:
+28
-18
@@ -418,37 +418,47 @@ class Install(AtomicOperation):
|
|||||||
|
|
||||||
# remove left over files from the old package.
|
# remove left over files from the old package.
|
||||||
def clean_leftovers():
|
def clean_leftovers():
|
||||||
new_files = dict((f.path, f) for f in self.files.list)
|
stat_cache = {}
|
||||||
|
|
||||||
|
files_by_name = {}
|
||||||
|
new_paths = []
|
||||||
|
for f in self.files.list:
|
||||||
|
files_by_name.setdefault(os.path.basename(f.path), []).append(f)
|
||||||
|
new_paths.append(f.path)
|
||||||
|
|
||||||
for old_file in self.old_files.list:
|
for old_file in self.old_files.list:
|
||||||
if old_file.path in new_files:
|
if old_file.path in new_paths:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
old_file_path = os.path.join(ctx.config.dest_dir(), old_file.path)
|
old_file_path = os.path.join(ctx.config.dest_dir(), old_file.path)
|
||||||
|
|
||||||
if not os.path.lexists(old_file_path):
|
try:
|
||||||
|
old_file_stat = os.lstat(old_file_path)
|
||||||
|
except OSError:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
old_file_stat = None
|
|
||||||
old_filename = os.path.basename(old_file.path)
|
old_filename = os.path.basename(old_file.path)
|
||||||
|
|
||||||
for new_file in self.files.list:
|
# If one of the parent directories is a symlink, it is possible
|
||||||
# If one of the parent directories is a symlink, it is possible
|
# that the new and old file paths refer to the same file.
|
||||||
# that the new and old file paths refer to the same file.
|
# In this case, we must not remove the old file.
|
||||||
# In this case, we must not remove the old file.
|
#
|
||||||
#
|
# e.g. /lib/libdl.so and /lib64/libdl.so when /lib64 is
|
||||||
# e.g. /lib/libdl.so and /lib64/libdl.so when /lib64 is
|
# a symlink to /lib.
|
||||||
# a symlink to /lib.
|
for new_file in files_by_name.get(old_filename, []):
|
||||||
|
|
||||||
if os.path.basename(new_file.path) != old_filename:
|
new_file_stat = stat_cache.get(new_file.path)
|
||||||
continue
|
|
||||||
|
|
||||||
new_file_path = os.path.join(ctx.config.dest_dir(), new_file.path)
|
if new_file_stat is None:
|
||||||
if not os.path.lexists(new_file_path):
|
path = os.path.join(ctx.config.dest_dir(), new_file.path)
|
||||||
continue
|
try:
|
||||||
|
new_file_stat = os.lstat(path)
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
|
||||||
old_file_stat = old_file_stat or os.lstat(old_file_path)
|
stat_cache[new_file.path] = new_file_stat
|
||||||
if os.path.samestat(os.lstat(new_file_path), old_file_stat):
|
|
||||||
|
if os.path.samestat(new_file_stat, old_file_stat):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
Remove.remove_file(old_file, self.pkginfo.name)
|
Remove.remove_file(old_file, self.pkginfo.name)
|
||||||
|
|||||||
Reference in New Issue
Block a user