Rev 166: Change the api a bit. obj.iter_recursive_refs() now returns self. in http://bazaar.launchpad.net/~meliae-dev/meliae/trunk
John Arbash Meinel
john at arbash-meinel.com
Thu Jul 29 16:50:48 BST 2010
At http://bazaar.launchpad.net/~meliae-dev/meliae/trunk
------------------------------------------------------------
revno: 166
revision-id: john at arbash-meinel.com-20100729155028-7s18qj51b22v4o08
parent: john at arbash-meinel.com-20100729152358-4p8h7ke9rwvxb5it
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: trunk
timestamp: Thu 2010-07-29 10:50:28 -0500
message:
Change the api a bit. obj.iter_recursive_refs() now returns self.
This allows us to:
a) skip over it if it is what we really want
b) simplify some code that wanted to exclude everything referenced from an object
including itself, which I imagine is more common.
-------------- next part --------------
=== modified file 'meliae/_loader.pyx'
--- a/meliae/_loader.pyx 2010-07-29 15:23:58 +0000
+++ b/meliae/_loader.pyx 2010-07-29 15:50:28 +0000
@@ -605,9 +605,18 @@
as_dict[key] = val
return as_dict
- def iter_recursive_refs(self):
+ def iter_recursive_refs(self, excluding=None):
+ """Find all objects referenced from this one (including self).
+
+ Self will always be the first object returned, in case you want to
+ exclude it (though it can be excluded in the excluding list).
+
+ :param excluding: This can be any iterable of addresses. We will not
+ walk to anything in this list (including self).
+ :return: Iterator over all objects that can be reached.
+ """
cdef _MOPReferencedIterator iterator
- iterator = _MOPReferencedIterator(self)
+ iterator = _MOPReferencedIterator(self, excluding)
return iterator
@@ -991,16 +1000,18 @@
cdef list pending_addresses
cdef int pending_offset
- def __init__(self, proxy):
+ def __init__(self, proxy, excluding=None):
cdef _MemObjectProxy c_proxy
from meliae import _intset
c_proxy = proxy
self.collection = c_proxy.collection
- self.seen_addresses = _intset.IDSet()
- self.seen_addresses.add(c_proxy.address)
- self.pending_addresses = list(c_proxy.children)
- self.pending_offset = len(self.pending_addresses) - 1
+ if excluding is not None:
+ self.seen_addresses = _intset.IDSet(excluding)
+ else:
+ self.seen_addresses = _intset.IDSet()
+ self.pending_addresses = [c_proxy.address]
+ self.pending_offset = 0
def __iter__(self):
return self
=== modified file 'meliae/loader.py'
--- a/meliae/loader.py 2010-07-29 15:23:58 +0000
+++ b/meliae/loader.py 2010-07-29 15:50:28 +0000
@@ -316,8 +316,7 @@
def compute_total_size(self, obj):
"""Sum the size of all referenced objects (recursively)."""
- obj.total_size = (obj.size
- + sum(c.size for c in obj.iter_recursive_refs()))
+ obj.total_size = sum(c.size for c in obj.iter_recursive_refs())
return obj
def summarize(self):
=== modified file 'meliae/tests/test__loader.py'
--- a/meliae/tests/test__loader.py 2010-07-29 15:23:58 +0000
+++ b/meliae/tests/test__loader.py 2010-07-29 15:50:28 +0000
@@ -523,16 +523,16 @@
self.moc.add(0, 'foo', 100)
self.moc.add(255, 'baz', 300)
- def assertIterRecursiveRefs(self, addresses, obj):
+ def assertIterRecursiveRefs(self, addresses, obj, excluding=None):
self.assertEqual(addresses,
- [o.address for o in obj.iter_recursive_refs()])
+ [o.address for o in obj.iter_recursive_refs(excluding=excluding)])
def test_no_refs(self):
- self.assertIterRecursiveRefs([], self.moc[1024])
+ self.assertIterRecursiveRefs([1024], self.moc[1024])
def test_single_depth_refs(self):
obj = self.moc.add(1, 'test', 1234, children=[1024])
- self.assertIterRecursiveRefs([1024], obj)
+ self.assertIterRecursiveRefs([1, 1024], obj)
def test_deep_refs(self):
obj = self.moc.add(1, '1', 1234, children=[2])
@@ -541,9 +541,33 @@
self.moc.add(4, '4', 1234, children=[5])
self.moc.add(5, '5', 1234, children=[6])
self.moc.add(6, '6', 1234, children=[])
- self.assertIterRecursiveRefs([2, 3, 4, 5, 6], obj)
+ self.assertIterRecursiveRefs([1, 2, 3, 4, 5, 6], obj)
def test_self_referenced(self):
self.moc.add(1, 'test', 1234, children=[1024, 2])
obj = self.moc.add(2, 'test2', 1234, children=[1])
- self.assertIterRecursiveRefs([1, 1024], obj)
+ self.assertIterRecursiveRefs([2, 1, 1024], obj)
+
+ def test_excluding(self):
+ obj = self.moc.add(1, 'test', 1234, children=[1024])
+ self.assertIterRecursiveRefs([1], obj, excluding=[1024])
+
+ def test_excluding_nested(self):
+ self.moc.add(1, 'test', 1234, children=[1024])
+ obj = self.moc.add(2, 'test', 1234, children=[1])
+ self.assertIterRecursiveRefs([2, 1, 1024], obj)
+ self.assertIterRecursiveRefs([2], obj, excluding=[1])
+
+ def test_excluding_wraparound(self):
+ self.moc.add(1, 'test', 1234, children=[1024])
+ self.moc.add(2, 'test', 1234, children=[1024])
+ obj = self.moc.add(3, 'test', 1234, children=[1, 2])
+ self.assertIterRecursiveRefs([3, 2, 1024, 1], obj)
+ self.assertIterRecursiveRefs([3, 2, 1024], obj, excluding=[1])
+ refed = (o.address for o in self.moc[1].iter_recursive_refs())
+ self.assertIterRecursiveRefs([3, 2], obj, excluding=refed)
+
+ def test_excluding_self(self):
+ self.assertIterRecursiveRefs([], self.moc[1024], excluding=[1024])
+ obj = self.moc.add(1, '1', 1234, children=[1024])
+ self.assertIterRecursiveRefs([], obj, excluding=[1])
More information about the bazaar-commits
mailing list