Commit deb8aea1 authored by Ximin Luo's avatar Ximin Luo

Greatly improve speed by cutting out O(n^2) lookup in libarchive.py

parent 00294d4b
......@@ -195,3 +195,16 @@ class LibarchiveContainer(Archive):
else:
return LibarchiveMember(self, entry)
raise KeyError('%s not found in archive', member_name)
def get_all_members(self):
with libarchive.file_reader(self.source.path) as archive:
for entry in archive:
p = entry.pathname
if entry.isdir:
yield p, LibarchiveDirectory(self, entry)
elif entry.issym:
yield p, LibarchiveSymlink(self, entry)
elif entry.isblk or entry.ischr:
yield p, LibarchiveDevice(self, entry)
else:
yield p, LibarchiveMember(self, entry)
......@@ -172,7 +172,7 @@ class Container(object, metaclass=abc.ABCMeta):
def get_members(self):
"""Returns a directory. The key is what is used to match when comparing containers."""
return collections.OrderedDict([(name, self.get_member(name)) for name in self.get_member_names()])
return collections.OrderedDict(self.get_all_members())
def lookup_file(self, *names):
"""Try to fetch a specific file by digging in containers."""
......@@ -198,6 +198,12 @@ class Container(object, metaclass=abc.ABCMeta):
def get_member(self, member_name):
raise NotImplementedError()
def get_all_members(self):
# If your get_member implementation is O(n) then this will be O(n^2) cost
# In such cases it is HIGHLY RECOMMENDED to override this as well
for name in self.get_member_names():
yield name, self.get_member(name)
def comparisons(self, other):
my_members = self.get_members()
my_reminders = collections.OrderedDict()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment