summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2016-06-12 18:16:04 +0300
committerLars Wirzenius <liw@liw.fi>2016-06-12 18:16:04 +0300
commit5ec6976eba38184d0a0bdf5ded0f59bfd417a99d (patch)
tree0ce53b5efd80dba176c8389aac8e92271ceb2b14
parent199c6665c1e3d9fbd29a5c67288c127c9cf2dc5a (diff)
downloadobnam-5ec6976eba38184d0a0bdf5ded0f59bfd417a99d.tar.gz
Try a faster approach
-rw-r--r--meliaereader/reader.py29
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])