self._root = self._dbapi.root
self._libs = {}
self._obj_properties = {}
- self._defpath = set(getlibpaths(self._root))
self._obj_key_cache = {}
+ self._defpath = set()
+ self._path_key_cache = {}
+
+ def _clear_cache(self):
+ self._libs.clear()
+ self._obj_properties.clear()
+ self._obj_key_cache.clear()
+ self._defpath.clear()
+ self._path_key_cache.clear()
+
+ def _path_key(self, path):
+ key = self._path_key_cache.get(path)
+ if key is None:
+ key = self._ObjectKey(path, self._root)
+ self._path_key_cache[path] = key
+ return key
class _ObjectKey(object):
def rebuild(self, exclude_pkgs=None, include_file=None):
root = self._root
- self._defpath = set(getlibpaths(root))
- libs = {}
- obj_key_cache = {}
- obj_properties = {}
+ self._clear_cache()
+ self._defpath.update(getlibpaths(self._root))
+ libs = self._libs
+ obj_key_cache = self._obj_key_cache
+ obj_properties = self._obj_properties
+
lines = []
for cpv in self._dbapi.cpv_all():
if exclude_pkgs is not None and cpv in exclude_pkgs:
obj = fields[1]
obj_key = self._ObjectKey(obj, root)
soname = fields[2]
- path = set([
- normalize_path(os.path.join(self._root, x.lstrip(os.path.sep)))
+ path = set([normalize_path(x) \
for x in filter(None, fields[3].replace(
"${ORIGIN}", os.path.dirname(obj)).replace(
"$ORIGIN", os.path.dirname(obj)).split(":"))])
obj_properties.setdefault(obj_key, \
(arch, needed, path, soname, set()))[4].add(obj)
- self._libs = libs
- self._obj_properties = obj_properties
- self._obj_key_cache = obj_key_cache
-
def listBrokenBinaries(self, debug=False):
"""
Find binaries and their needed sonames, which have no providers.
raise KeyError("%s (%s) not in object list" % (obj_key, obj))
arch, needed, path, _, _ = self._obj_properties[obj_key]
- path = path.union(self._defpath)
+ path_keys = set(self._path_key(x) for x in path.union(self._defpath))
for soname in needed:
rValue[soname] = set()
if soname not in self._libs or arch not in self._libs[soname]:
for provider_key in self._libs[soname][arch]["providers"]:
providers = self._obj_properties[provider_key][4]
for provider in providers:
- if os.path.join(self._root,
- os.path.dirname(provider).lstrip(os.path.sep)) in path:
+ if self._path_key(os.path.dirname(provider)) in path_keys:
rValue[soname].add(provider)
return rValue
if obj_key not in self._obj_properties:
raise KeyError("%s (%s) not in object list" % (obj_key, obj))
- # Determine the directory(ies) from the set of objects.
- objs_dirs = set(os.path.join(self._root,
- os.path.dirname(x).lstrip(os.sep)) for x in objs)
-
# If there is another version of this lib with the
# same soname and the master link points to that
# other version, this lib will be shadowed and won't
(master_st.st_dev, master_st.st_ino):
return set()
+ # Determine the directory(ies) from the set of objects.
+ objs_dir_keys = set(self._path_key(os.path.dirname(x)) for x in objs)
+ defpath_keys = set(self._path_key(x) for x in self._defpath)
+
arch, _, _, soname, _ = self._obj_properties[obj_key]
if soname in self._libs and arch in self._libs[soname]:
# For each potential consumer, add it to rValue if an object from the
for consumer_key in self._libs[soname][arch]["consumers"]:
_, _, path, _, consumer_objs = \
self._obj_properties[consumer_key]
- path = path.union(self._defpath)
- if objs_dirs.intersection(path):
+ path_keys = defpath_keys.union(self._path_key(x) for x in path)
+ if objs_dir_keys.intersection(path_keys):
rValue.update(consumer_objs)
return rValue