Rev 5362: SimpleSet now has a __sizeof__ member which knows about its internal table. in http://bazaar.launchpad.net/~jameinel/bzr/2.3-sizeof

John Arbash Meinel john at arbash-meinel.com
Wed Jul 28 22:37:00 BST 2010


At http://bazaar.launchpad.net/~jameinel/bzr/2.3-sizeof

------------------------------------------------------------
revno: 5362
revision-id: john at arbash-meinel.com-20100728213644-3k50bbdkq4r1fb9j
parent: pqm at pqm.ubuntu.com-20100726115129-2uy7vwm0v2ergzk3
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.3-sizeof
timestamp: Wed 2010-07-28 16:36:44 -0500
message:
  SimpleSet now has a __sizeof__ member which knows about its internal table.
-------------- next part --------------
=== modified file 'bzrlib/_simple_set_pyx.pyx'
--- a/bzrlib/_simple_set_pyx.pyx	2010-02-17 17:11:16 +0000
+++ b/bzrlib/_simple_set_pyx.pyx	2010-07-28 21:36:44 +0000
@@ -115,6 +115,9 @@
             raise MemoryError()
         memset(self._table, 0, n_bytes)
 
+    def __sizeof__(self):
+        return sizeof(SimpleSet) + (self._mask + 1) * (sizeof(PyObject**))
+
     def __dealloc__(self):
         if self._table != NULL:
             PyMem_Free(self._table)

=== modified file 'bzrlib/tests/test__simple_set.py'
--- a/bzrlib/tests/test__simple_set.py	2010-02-17 17:11:16 +0000
+++ b/bzrlib/tests/test__simple_set.py	2010-07-28 21:36:44 +0000
@@ -379,3 +379,41 @@
         # And even removing an item still causes it to fail
         obj.discard(k2)
         self.assertRaises(RuntimeError, iterator.next)
+
+    def get_platform_size(self):
+        """Try to determine if we are on 32-bit or 64-bit architecture."""
+        sizeof = getattr(sys, 'getsizeof', None)
+        if sizeof is not None:
+            int_size = sizeof(1)
+            # A python Int is 3 longs
+            # 1: PyType *
+            # 2: refcnt
+            # 3: long val
+            return int_size / 3
+        return None
+
+    def test__sizeof__(self):
+        # SimpleSet needs a custom sizeof implementation, because it allocates
+        # memory that Python cannot directly see (_table).
+        # The size of a SimpleSet object is (in 32/64-bit objects)
+        # 1: PyType *
+        # 2: refcnt
+        # 3: vtable *
+        # 4: _used
+        # 5: _fill
+        # 6: _mask
+        # 7: _table*
+        # (_mask+1) pointers
+        # Default size is 1024 pointers
+        obj = self.module.SimpleSet()
+        n_words = 7 + 1024
+        s = obj.__sizeof__()
+        plat_size = self.get_platform_size()
+        if plat_size is None:
+            # We should either be 64-bit or 32-bit, but I don't know which
+            if s != n_words * 8 and s != n_words * 4:
+                self.fail("SimpleSet.__sizeof__() returned %s which is not"
+                          " a 32-bit or 64-bit multiple of %s words"
+                          % (s, n_words))
+        else:
+            self.assertEqual(n_words * plat_size, s)



More information about the bazaar-commits mailing list