From 881a3de8afdcfdcb51170eca77acd685cb4021e8 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Mon, 23 Jun 2008 10:00:12 +0000 Subject: [PATCH] Bug #228977 - During dblink._preserve_libs() calls, cache results of LinkageMap.findProviders(), LinkageMap.findConsumers(), and os.path.realpath() calls in order to improve performance. This makes a huge difference in performance for glibc upgrades since glibc provides so many libs to check consumerge for. svn path=/main/trunk/; revision=10764 --- pym/portage/dbapi/vartree.py | 57 ++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index f71a20794..835892722 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -201,30 +201,48 @@ class LinkageMap(object): def findProviders(self, obj): if not self._libs: self.rebuild() + + realpath_cache = {} + def realpath(p): + real_path = realpath_cache.get(p) + if real_path is None: + real_path = os.path.realpath(p) + realpath_cache[p] = real_path + return real_path + rValue = {} if obj not in self._obj_properties: - obj = os.path.realpath(obj) + obj = realpath(obj) if obj not in self._obj_properties: raise KeyError("%s not in object list" % obj) arch, needed, path, soname = self._obj_properties[obj] path.extend(self._defpath) - path = [os.path.realpath(x) for x in path] + path = set(realpath(x) for x in path) for x in needed: rValue[x] = set() if x not in self._libs or arch not in self._libs[x]: continue for y in self._libs[x][arch]["providers"]: - if x[0] == os.sep and os.path.realpath(x) == os.path.realpath(y): + if x[0] == os.sep and realpath(x) == realpath(y): rValue[x].add(y) - elif os.path.realpath(os.path.dirname(y)) in path: + elif realpath(os.path.dirname(y)) in path: rValue[x].add(y) return rValue def findConsumers(self, obj): if not self._libs: self.rebuild() + + realpath_cache = {} + def realpath(p): + real_path = realpath_cache.get(p) + if real_path is None: + real_path = os.path.realpath(p) + realpath_cache[p] = real_path + return real_path + if obj not in self._obj_properties: - obj = os.path.realpath(obj) + obj = realpath(obj) if obj not in self._obj_properties: raise KeyError("%s not in object list" % obj) rValue = set() @@ -233,10 +251,10 @@ class LinkageMap(object): if obj in self._libs[soname][arch]["providers"]: for x in self._libs[soname][arch]["consumers"]: path = self._obj_properties[x][2] - path = [os.path.realpath(y) for y in path+self._defpath] - if soname[0] == os.sep and os.path.realpath(soname) == os.path.realpath(obj): + path = [realpath(y) for y in path+self._defpath] + if soname[0] == os.sep and realpath(soname) == realpath(obj): rValue.add(x) - elif os.path.realpath(os.path.dirname(obj)) in path: + elif realpath(os.path.dirname(obj)) in path: rValue.add(x) return rValue @@ -1995,9 +2013,15 @@ class dblink(object): if os.path.islink(x) and os.path.realpath(x) in candidates and x not in mycontents: candidates.add(x) + provider_cache = {} + consumer_cache = {} + # ignore any libs that are only internally used by the package def has_external_consumers(lib, contents, otherlibs): - consumers = linkmap.findConsumers(lib) + consumers = consumer_cache.get(lib) + if consumers is None: + consumers = linkmap.findConsumers(lib) + consumer_cache[lib] = consumers contents_without_libs = [x for x in contents if x not in otherlibs] # just used by objects that will be autocleaned @@ -2024,10 +2048,19 @@ class dblink(object): continue # only preserve the lib if there is no other copy to use for each consumer keep = False - for c in linkmap.findConsumers(lib): + + lib_consumers = consumer_cache.get(lib) + if lib_consumers is None: + lib_consumers = linkmap.findConsumers(lib) + consumer_cache[lib] = lib_consumers + + for c in lib_consumers: localkeep = True - providers = linkmap.findProviders(c) - + providers = provider_cache.get(c) + if providers is None: + providers = linkmap.findProviders(c) + provider_cache[c] = providers + for soname in providers: if lib in providers[soname]: for p in providers[soname]: -- 2.26.2