[Zodb-checkins] SVN: ZODB/branches/tseaver-python_picklecache-2/src/persistent/ Add extra properties from the C implementation.

Tres Seaver tseaver at palladion.com
Tue Feb 15 13:55:54 EST 2011


Log message for revision 120353:
  Add extra properties from the C implementation.
  
  These attributes are not defined in IPersistent.
  

Changed:
  U   ZODB/branches/tseaver-python_picklecache-2/src/persistent/pypersistent.py
  U   ZODB/branches/tseaver-python_picklecache-2/src/persistent/tests/test_pypersistent.py

-=-
Modified: ZODB/branches/tseaver-python_picklecache-2/src/persistent/pypersistent.py
===================================================================
--- ZODB/branches/tseaver-python_picklecache-2/src/persistent/pypersistent.py	2011-02-15 18:55:53 UTC (rev 120352)
+++ ZODB/branches/tseaver-python_picklecache-2/src/persistent/pypersistent.py	2011-02-15 18:55:54 UTC (rev 120353)
@@ -11,7 +11,10 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
+import datetime
+import struct
 import sys
+import time
 
 from zope.interface import implements
 
@@ -23,9 +26,34 @@
 else:
     OID_TYPE = SERIAL_TYPE = bytes
 
+# Bitwise flags
 _CHANGED = 0x0001
 _STICKY = 0x0002
 
+# Allowed values for _p_state
+GHOST = -1
+UPTODATE = 0
+CHANGED = 1
+STICKY = 2
+
+_SCONV = 60.0 / (1<<16) / (1<<16)
+
+def makeTimestamp(year, month, day, hour, minute, second):
+    a = (((year - 1900) * 12 + month - 1) * 31 + day - 1)
+    a = (a * 24 + hour) * 60 + minute
+    b = int(second / _SCONV)
+    return struct.pack('>II', a, b)
+
+def parseTimestamp(octets):
+    a, b = struct.unpack('>II', octets)
+    minute = a % 60
+    hour = a // 60 % 24
+    day = a // (60 * 24) % 31 + 1
+    month = a // (60 * 24 * 31) % 12 + 1
+    year = a // (60 * 24 * 31 * 12) + 1900
+    second = b * _SCONV
+    return (year, month, day, hour, minute, second)
+
 class Persistent(object):
     __slots__ = ('__jar', '__oid', '__serial', '__flags')
     implements(IPersistent)
@@ -135,6 +163,41 @@
 
     _p_status = property(_get_status)
 
+    # These attributes are defined by the C type, but not IPersistent.
+    def _get_mtime(self):
+        if self.__serial is not None:
+            when = datetime.datetime(*parseTimestamp(self.__serial))
+            return time.mktime(when.timetuple())
+    _p_mtime = property(_get_mtime)
+
+    # _p_state
+    def _get_state(self):
+        if self.__flags is None:
+            if self.__jar is None:
+                return UPTODATE
+            return GHOST
+        if self.__flags & _CHANGED:
+            if self.__jar is None:
+                return UPTODATE
+            result = CHANGED
+        else:
+            result = UPTODATE
+        if self.__flags & _STICKY:
+            return STICKY
+        return result
+
+    _p_state = property(_get_state)
+
+    # _p_estimated_size:  XXX don't want to reserve the space?
+    def _get_estimated_size(self):
+        return 0
+
+    def _set_estimated_size(self, value):
+        pass
+
+    _p_estimated_size = property(_get_estimated_size, _set_estimated_size)
+
+    # Methods from IPersistent.
     def __getstate__(self):
         """ See IPersistent.
         """

Modified: ZODB/branches/tseaver-python_picklecache-2/src/persistent/tests/test_pypersistent.py
===================================================================
--- ZODB/branches/tseaver-python_picklecache-2/src/persistent/tests/test_pypersistent.py	2011-02-15 18:55:53 UTC (rev 120352)
+++ ZODB/branches/tseaver-python_picklecache-2/src/persistent/tests/test_pypersistent.py	2011-02-15 18:55:54 UTC (rev 120353)
@@ -358,6 +358,67 @@
         inst._p_sticky = True
         self.assertEqual(inst._p_status, 'saved (sticky)')
 
+    def test__p_mtime_no_serial(self):
+        inst = self._makeOne()
+        self.assertEqual(inst._p_mtime, None)
+
+    def test__p_mtime_w_serial(self):
+        import datetime
+        import time
+        from persistent.pypersistent import makeTimestamp
+        WHEN_TUPLE = (2011, 2, 15, 13, 33, 27.5)
+        WHEN = datetime.datetime(*WHEN_TUPLE)
+        inst, jar, OID = self._makeOneWithJar()
+        inst._p_serial = makeTimestamp(*WHEN_TUPLE)
+        self.assertEqual(inst._p_mtime, time.mktime(WHEN.timetuple()))
+
+    def test__p_state_new(self):
+        inst = self._makeOne()
+        self.assertEqual(inst._p_state, 0)
+
+    def test__p_state_unsaved(self):
+        inst = self._makeOne()
+        inst._p_changed = True
+        self.assertEqual(inst._p_state, 0)
+
+    def test__p_state_ghost(self):
+        inst, jar, OID = self._makeOneWithJar()
+        self.assertEqual(inst._p_state, -1)
+
+    def test__p_state_changed(self):
+        inst, jar, OID = self._makeOneWithJar()
+        inst._p_changed = True
+        self.assertEqual(inst._p_state, 1)
+
+    def test__p_state_changed_sticky(self):
+        # 'sticky' is not a state, but a separate flag.
+        inst, jar, OID = self._makeOneWithJar()
+        inst._p_changed = True
+        inst._p_sticky = True
+        self.assertEqual(inst._p_state, 2)
+
+    def test__p_state_saved(self):
+        inst, jar, OID = self._makeOneWithJar()
+        inst._p_changed = False
+        self.assertEqual(inst._p_state, 0)
+
+    def test__p_state_saved_sticky(self):
+        # 'sticky' is not a state, but a separate flag.
+        inst, jar, OID = self._makeOneWithJar()
+        inst._p_changed = False
+        inst._p_sticky = True
+        self.assertEqual(inst._p_state, 2)
+
+    def test_query_p_estimated_size(self):
+        inst = self._makeOne()
+        self.assertEqual(inst._p_estimated_size, 0)
+
+    def test_assign_p_estimated_size(self):
+        # XXX at the moment, we don't store this value.
+        inst = self._makeOne()
+        inst._p_estimated_size = 123
+        self.assertEqual(inst._p_estimated_size, 0)
+
     def test___getstate__(self):
         inst = self._makeOne()
         self.assertEqual(inst.__getstate__(), {})



More information about the Zodb-checkins mailing list