[Python-checkins] r72228 - in python/branches/py3k: Lib/mailbox.py Lib/test/test_mailbox.py

andrew.kuchling python-checkins at python.org
Sun May 3 04:52:21 CEST 2009


Author: andrew.kuchling
Date: Sun May  3 04:52:20 2009
New Revision: 72228

Log:
Merged revisions 72213 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r72213 | andrew.kuchling | 2009-05-02 15:17:28 -0400 (Sat, 02 May 2009) | 3 lines
  
  #1607951: Make mailbox.Maildir re-read the directories less frequently.
  This is done by recording the current time -1sec, and not re-reading unless
  the directory mod. times are >= the recorded time.
........


Modified:
   python/branches/py3k/   (props changed)
   python/branches/py3k/Lib/mailbox.py
   python/branches/py3k/Lib/test/test_mailbox.py

Modified: python/branches/py3k/Lib/mailbox.py
==============================================================================
--- python/branches/py3k/Lib/mailbox.py	(original)
+++ python/branches/py3k/Lib/mailbox.py	Sun May  3 04:52:20 2009
@@ -233,6 +233,7 @@
             else:
                 raise NoSuchMailboxError(self._path)
         self._toc = {}
+        self._last_read = None          # Records last time we read cur/new
 
     def add(self, message):
         """Add message and return assigned key."""
@@ -457,16 +458,35 @@
 
     def _refresh(self):
         """Update table of contents mapping."""
+        new_mtime = os.path.getmtime(os.path.join(self._path, 'new'))
+        cur_mtime = os.path.getmtime(os.path.join(self._path, 'cur'))
+
+        if (self._last_read is not None and
+            new_mtime <= self._last_read and cur_mtime <= self._last_read):
+            return
+
         self._toc = {}
-        for subdir in ('new', 'cur'):
-            subdir_path = os.path.join(self._path, subdir)
-            for entry in os.listdir(subdir_path):
-                p = os.path.join(subdir_path, entry)
+        def update_dir (subdir):
+            path = os.path.join(self._path, subdir)
+            for entry in os.listdir(path):
+                p = os.path.join(path, entry)
                 if os.path.isdir(p):
                     continue
                 uniq = entry.split(self.colon)[0]
                 self._toc[uniq] = os.path.join(subdir, entry)
 
+        update_dir('new')
+        update_dir('cur')
+
+        # We record the current time - 1sec so that, if _refresh() is called
+        # again in the same second, we will always re-read the mailbox
+        # just in case it's been modified.  (os.path.mtime() only has
+        # 1sec resolution.)  This results in a few unnecessary re-reads
+        # when _refresh() is called multiple times in the same second,
+        # but once the clock ticks over, we will only re-read as needed.
+        now = int(time.time() - 1)
+        self._last_read = time.time() - 1
+
     def _lookup(self, key):
         """Use TOC to return subpath for given key, or raise a KeyError."""
         try:

Modified: python/branches/py3k/Lib/test/test_mailbox.py
==============================================================================
--- python/branches/py3k/Lib/test/test_mailbox.py	(original)
+++ python/branches/py3k/Lib/test/test_mailbox.py	Sun May  3 04:52:20 2009
@@ -740,6 +740,37 @@
         perms = st.st_mode
         self.assertFalse((perms & 0o111)) # Execute bits should all be off.
 
+    def test_reread(self):
+        # Wait for 2 seconds
+        time.sleep(2)
+
+        # Initially, the mailbox has not been read and the time is null.
+        assert getattr(self._box, '_last_read', None) is None
+
+        # Refresh mailbox; the times should now be set to something.
+        self._box._refresh()
+        assert getattr(self._box, '_last_read', None) is not None
+
+        # Try calling _refresh() again; the modification times shouldn't have
+        # changed, so the mailbox should not be re-reading.  Re-reading causes
+        # the ._toc attribute to be assigned a new dictionary object, so
+        # we'll check that the ._toc attribute isn't a different object.
+        orig_toc = self._box._toc
+        def refreshed():
+            return self._box._toc is not orig_toc
+
+        time.sleep(1)         # Wait 1sec to ensure time.time()'s value changes
+        self._box._refresh()
+        assert not refreshed()
+
+        # Now, write something into cur and remove it.  This changes
+        # the mtime and should cause a re-read.
+        filename = os.path.join(self._path, 'cur', 'stray-file')
+        f = open(filename, 'w')
+        f.close()
+        os.unlink(filename)
+        self._box._refresh()
+        assert refreshed()
 
 class _TestMboxMMDF(TestMailbox):
 


More information about the Python-checkins mailing list