Rev 176: Add more convenience helpers. in http://bazaar.launchpad.net/~meliae-dev/meliae/trunk
John Arbash Meinel
john at arbash-meinel.com
Sat Jul 31 07:39:46 BST 2010
At http://bazaar.launchpad.net/~meliae-dev/meliae/trunk
------------------------------------------------------------
revno: 176
revision-id: john at arbash-meinel.com-20100731063943-7sa8xnqy62eiuaj2
parent: john at arbash-meinel.com-20100731042353-kl5zhs13vsqpo6ui
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: trunk
timestamp: Sat 2010-07-31 01:39:43 -0500
message:
Add more convenience helpers.
These are actually pretty nice for probing into the details about what is
semi-exclusively referenced from X.
Note that because of refcycles it can be tricky to determine if objects
share intermediate resources. For example:
b <= Y <=> Z => a
In this case, Z looks like it references both a and b. However, if the
cycle was broken, then it would not. One option is to refine exclusion lists.
o_from_y = [o.address for o in y.iter_recursive_refs(excluding=[z.address])]
o_from_just_z = [o for o in z.iter_recursive_refs(excluding=o_from_y)]
etc.
I'm also not perfectly satisfied that excluding takes addresses vs objects.
Though I think it performs better that way, since you avoid all the extra
proxy objects, and just have a set/list of python integers.
-------------- next part --------------
=== modified file 'CHANGES.txt'
--- a/CHANGES.txt 2010-07-31 04:23:53 +0000
+++ b/CHANGES.txt 2010-07-31 06:39:43 +0000
@@ -30,6 +30,12 @@
``ObjectManager.summarize(obj, [not_address1, not_address2])``.
(John Arbash Meinel)
+* ``obj.all()`` and ``obj.compute_total_size()`` helpers. These let you
+ get the set of referenced objects matching the type (like
+ ``om.get_all()``). But they *also* allow you to pass an exclusion
+ list, so you can only get things reachable from here and not
+ reachable from there. (John Arbash Meinel)
+
Meliae 0.2.1
############
=== modified file 'meliae/_loader.pyx'
--- a/meliae/_loader.pyx 2010-07-29 21:44:49 +0000
+++ b/meliae/_loader.pyx 2010-07-31 06:39:43 +0000
@@ -627,6 +627,42 @@
iterator = _MOPReferencedIterator(self, excluding)
return iterator
+ def compute_total_size(self, excluding=None):
+ """Compute the number of bytes of this and all referenced objects.
+
+ This layers on top of iter_recursive_refs to give just the interesting
+ bits.
+
+ :return: total_size, this will also be set on self.
+ """
+ cdef _MOPReferencedIterator iterator
+ cdef _MemObjectProxy item
+ cdef unsigned long total_size
+ total_size = 0
+ iterator = self.iter_recursive_refs(excluding=excluding)
+ for item in iterator:
+ total_size += item._obj.size
+ self._obj.total_size = total_size
+ return self.total_size
+
+ def all(self, type_str, excluding=None):
+ """Retrieve a list of all the referenced items matching type_str.
+
+ :param type_str: Children must match this type string.
+ :param excluding: See iter_recursive_refs
+ :return: A list of all entries, sorted with the largest entries first.
+ """
+ cdef list all
+ all = []
+ for item in self.iter_recursive_refs(excluding=excluding):
+ if item.type_str == type_str:
+ all.append(item)
+ all.sort(key=_all_sort_key, reverse=True)
+ return all
+
+
+def _all_sort_key(proxy_obj):
+ return (proxy_obj.size, len(proxy_obj), proxy_obj.num_parents)
cdef class MemObjectCollection:
=== modified file 'meliae/tests/test__loader.py'
--- a/meliae/tests/test__loader.py 2010-07-29 21:44:49 +0000
+++ b/meliae/tests/test__loader.py 2010-07-31 06:39:43 +0000
@@ -576,6 +576,22 @@
5, 6, 7, 8, 9, 10],
_scanner.get_referents(mop))
+ def test_compute_total_size(self):
+ obj = self.moc.add(1, 'test', 1234, children=[0])
+ obj = self.moc.add(2, 'other', 4567, children=[1])
+ self.assertEqual(1234+4567+100, obj.compute_total_size())
+ self.assertEqual(1234+4567, obj.compute_total_size(excluding=[0]))
+
+ def test_all(self):
+ self.moc.add(1, 'foo', 1234, children=[0])
+ obj = self.moc.add(2, 'other', 4567, children=[1])
+ self.assertEqual([1, 0], [o.address for o in obj.all('foo')])
+ self.assertEqual([1],
+ [o.address for o in obj.all('foo', excluding=[0])])
+ # Excluding 1 actually prevents us from walking further
+ self.assertEqual([],
+ [o.address for o in obj.all('foo', excluding=[1])])
+
class Test_MemObjectProxyIterRecursiveRefs(tests.TestCase):
More information about the bazaar-commits
mailing list