diff options
author | Lars Wirzenius <liw@liw.fi> | 2016-06-12 18:16:04 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2016-06-12 18:16:04 +0300 |
commit | 5ec6976eba38184d0a0bdf5ded0f59bfd417a99d (patch) | |
tree | 0ce53b5efd80dba176c8389aac8e92271ceb2b14 | |
parent | 199c6665c1e3d9fbd29a5c67288c127c9cf2dc5a (diff) | |
download | obnam-5ec6976eba38184d0a0bdf5ded0f59bfd417a99d.tar.gz |
Try a faster approach
-rw-r--r-- | meliaereader/reader.py | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/meliaereader/reader.py b/meliaereader/reader.py index be38ef8d..139cf574 100644 --- a/meliaereader/reader.py +++ b/meliaereader/reader.py @@ -66,11 +66,34 @@ class MeliaeReader(object): def compute_closures(self): sys.stderr.write('computing closures for {} objects'.format(len(self))) - for ref in self._objs: - sys.stderr.write('{} closures to go\n'.format(len(self) - len(self._closures))) - self._closures[ref] = self._simple_get_closure(ref) + + all_refs = self._objs.keys() + + # Set all closures to be just the object itself. + for ref in all_refs: + self._closures[ref] = set([ref]) + + # Find new objects that can be reached from current closures. + # Repeat until no more. + added = True + while added and all_refs: + added = False + for ref in all_refs: + added = self.add_to_closure(ref) or added + assert set(self._objs.keys()) == set(self._closures.keys()) + def add_to_closure(self, ref): + added = False + closure = self._closures[ref] + children = [self.get_object(r) for r in closure] + for child in children: + delta = set(child['refs']).difference(closure) + if delta: + closure.update(delta) + added = True + return added + def _simple_get_closure(self, ref): # pragma: no cover closure = set() todo = set([ref]) |