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