[entropy.graph] implement Graph.destroy() to free circular references (was causing interesting memleak)

This commit is contained in:
Fabio Erculiani
2011-02-11 19:06:22 +01:00
parent 2d7d1675b2
commit bf4dc1cd37
3 changed files with 82 additions and 0 deletions
+2
View File
@@ -385,6 +385,7 @@ def _revgraph_package(installed_pkg_id, package, dbconn, show_complete = False):
_show_graph_legend()
del stack
graph.destroy()
del graph
return 0
@@ -471,6 +472,7 @@ def _graph_package(match, package, entropy_intf, show_complete = False):
_show_dependencies_legend()
del stack
graph.destroy()
del graph
return 0
@@ -1334,12 +1334,14 @@ class CalculatorsMixin:
deptree_conflicts |= conflicts
if deps_not_found:
graph.destroy()
del graph
raise DependenciesNotFound(deps_not_found)
# solve depgraph and append conflicts
deptree = graph.solve()
if 0 in deptree:
graph.destroy()
del graph
raise KeyError("Graph contains a dep_level == 0")
@@ -1354,6 +1356,7 @@ class CalculatorsMixin:
_colliding_deps = [x for x in _dup_deps_collisions.values() if \
len(x) > 1]
if _colliding_deps:
graph.destroy()
del graph
raise DependenciesCollision(_colliding_deps)
@@ -1364,6 +1367,7 @@ class CalculatorsMixin:
level_count += 1
reverse_tree[level_count] = deptree[key]
graph.destroy()
del deptree, graph
reverse_tree[0] = deptree_conflicts
@@ -1660,6 +1664,7 @@ class CalculatorsMixin:
deptree = graph.solve()
del flat_dep_tree
graph.destroy()
del graph
if self.xcache:
+75
View File
@@ -35,6 +35,25 @@ class GraphNode(object):
self.__item = item
self.__arches = set()
def __del__(self):
try:
self._clear()
except (NameError, AttributeError):
pass
def _clear(self):
"""
Clear the object
"""
try:
self.__arches.clear()
except (NameError, AttributeError):
pass
try:
self.__item = None
except (NameError, AttributeError):
pass
def __str__(self):
"""
Default string representation.
@@ -135,6 +154,22 @@ class GraphArchSet(object):
self.__origin = starting_point
self.__endpoints = set()
def __del__(self):
try:
self._clear()
except (NameError, AttributeError):
pass
def _clear(self):
"""
Cleanup the object
"""
try:
self.__endpoints.clear()
del self.__origin
except (NameError, AttributeError):
pass
def __str__(self):
"""
Default string representation.
@@ -210,6 +245,16 @@ class TopologicalSorter(object):
self.__adjacency_map = adjacency_map
self.__stack = Lifo()
def __del__(self):
try:
self.__adjacency_map.clear()
except (NameError, AttributeError):
pass
try:
self.__stack.clear()
except (NameError, AttributeError):
pass
def __topological_sort_visit_node(self, node, low, result):
"""
Internal method, visits a node ad push to stack.
@@ -340,6 +385,36 @@ class Graph(object):
self.__archs_map = {}
self.__graph_map_cache = None
def __del__(self):
try:
self.destroy()
except (AttributeError, NameError):
pass
def destroy(self):
"""
Cleanup any reference.
"""
try:
for obj in self.__graph.values():
obj._clear()
self.__graph.clear()
except (NameError, AttributeError):
pass
try:
for obj in self.__archs_map.values():
obj._clear()
self.__archs_map.clear()
except (NameError, AttributeError):
pass
try:
if self.__graph_map_cache is not None:
for obj in self.__graph_map_cache.values():
obj._clear()
self.__graph_map_cache.clear()
except (NameError, AttributeError):
pass
def __invalidate_cache(self):
"""
Private method, stay away from here.