Skip to content

Commit 6719da8

Browse files
authored
Added automatic ref and deref to SddNode wrapper. (#44)
1 parent 8704643 commit 6719da8

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

pysdd/sdd.pyx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ cdef class SddNode:
5353
wrapper._sddnode = node
5454
if wrapper.garbage_collected():
5555
return None
56+
wrapper.ref()
5657
if sddapi_c.sdd_node_is_literal(node):
5758
wrapper._name = sddapi_c.sdd_node_literal(node)
5859
elif sddapi_c.sdd_node_is_true(node):
@@ -63,6 +64,9 @@ cdef class SddNode:
6364
wrapper._name = "Decision"
6465
return wrapper
6566

67+
def __del__(self):
68+
# clean up _sddnode ref
69+
self.deref()
6670

6771
@property
6872
def id(self):
@@ -306,7 +310,6 @@ cdef class SddNode:
306310
307311
Returns the node.
308312
"""
309-
# TODO: Should we ref every Python SDDNode object on creation and deref on Python GC?
310313
sddapi_c.sdd_ref(self._sddnode, self._manager._sddmanager)
311314

312315
def deref(self):

tests/test_minimize.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,22 @@ def test_min2():
7474
# with (directory / "sdd2_before_b.gv").open("w") as out:
7575
# print(sdd_to_dot(sdd), file=out)
7676

77+
def test_refcount():
78+
sdd = SddManager(var_count=2)
79+
a, b = sdd.vars
80+
f = a | b
81+
assert f.ref_count() == 1
82+
f.ref()
83+
assert f.ref_count() == 2
84+
f.deref()
85+
assert f.ref_count() == 1
86+
# equivalent formula will
87+
# ref same formula object
88+
f2 = b | a
89+
assert f2.ref_count() == 2
90+
assert f.ref_count() == 2
91+
del f2
92+
assert f.ref_count() == 1
7793

7894
if __name__ == "__main__":
7995
logger.setLevel(logging.DEBUG)

0 commit comments

Comments
 (0)