[Python-checkins] CVS: python/dist/src/Lib statcache.py,1.9,1.10

Tim Peters tim_one@users.sourceforge.net
Sat, 27 Jan 2001 21:07:02 -0800


Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv23494/python/dist/src/Lib

Modified Files:
	statcache.py 
Log Message:
SF bug #130306:  statcache.py full of thread problems.
Fixed the thread races.  Function forget_dir was also utterly Unix-specific.


Index: statcache.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/statcache.py,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -r1.9 -r1.10
*** statcache.py	2001/01/15 01:36:40	1.9
--- statcache.py	2001/01/28 05:07:00	1.10
***************
*** 4,75 ****
  """
  
! import os
  from stat import *
  
! # The cache.
! # Keys are pathnames, values are `os.stat' outcomes.
! #
! cache = {}
  
  
  def stat(path):
      """Stat a file, possibly out of the cache."""
!     if cache.has_key(path):
!         return cache[path]
!     cache[path] = ret = os.stat(path)
      return ret
  
- 
  def reset():
!     """Reset the cache completely."""
!     global cache
!     cache = {}
  
! 
  def forget(path):
      """Remove a given item from the cache, if it exists."""
!     if cache.has_key(path):
          del cache[path]
! 
  
  def forget_prefix(prefix):
      """Remove all pathnames with a given prefix."""
-     n = len(prefix)
      for path in cache.keys():
!         if path[:n] == prefix:
!             del cache[path]
  
- 
  def forget_dir(prefix):
!     """Forget about a directory and all entries in it, but not about
!     entries in subdirectories."""
!     if prefix[-1:] == '/' and prefix != '/':
!         prefix = prefix[:-1]
      forget(prefix)
-     if prefix[-1:] != '/':
-         prefix = prefix + '/'
-     n = len(prefix)
      for path in cache.keys():
!         if path[:n] == prefix:
!             rest = path[n:]
!             if rest[-1:] == '/': rest = rest[:-1]
!             if '/' not in rest:
!                 del cache[path]
! 
  
  def forget_except_prefix(prefix):
      """Remove all pathnames except with a given prefix.
-     Normally used with prefix = '/' after a chdir()."""
-     n = len(prefix)
-     for path in cache.keys():
-         if path[:n] != prefix:
-             del cache[path]
  
  
  def isdir(path):
!     """Check for directory."""
      try:
          st = stat(path)
!     except os.error:
          return 0
      return S_ISDIR(st[ST_MODE])
--- 4,74 ----
  """
  
! import os as _os
  from stat import *
  
! # The cache.  Keys are pathnames, values are os.stat outcomes.
! # Remember that multiple threads may be calling this!  So, e.g., that
! # cache.has_key(path) returns 1 doesn't mean the cache will still contain
! # path on the next line.  Code defensively.
  
+ cache = {}
  
  def stat(path):
      """Stat a file, possibly out of the cache."""
!     ret = cache.get(path, None)
!     if ret is None:
!         cache[path] = ret = _os.stat(path)
      return ret
  
  def reset():
!     """Clear the cache."""
!     cache.clear()
  
! # For thread saftey, always use forget() internally too.
  def forget(path):
      """Remove a given item from the cache, if it exists."""
!     try:
          del cache[path]
!     except KeyError:
!         pass
  
  def forget_prefix(prefix):
      """Remove all pathnames with a given prefix."""
      for path in cache.keys():
!         if path.startswith(prefix):
!             forget(path)
  
  def forget_dir(prefix):
!     """Forget a directory and all entries except for entries in subdirs."""
! 
!     # Remove trailing separator, if any.  This is tricky to do in a
!     # x-platform way.  For example, Windows accepts both / and \ as
!     # separators, and if there's nothing *but* a separator we want to
!     # preserve that this is the root.  Only os.path has the platform
!     # knowledge we need.
!     from os.path import split, join
!     prefix = split(join(prefix, "xxx"))[0]
      forget(prefix)
      for path in cache.keys():
!         # First check that the path at least starts with the prefix, so
!         # that when it doesn't we can avoid paying for split().
!         if path.startswith(prefix) and split(path)[0] == prefix:
!             forget(path)
  
  def forget_except_prefix(prefix):
      """Remove all pathnames except with a given prefix.
  
+     Normally used with prefix = '/' after a chdir().
+     """
+ 
+     for path in cache.keys():
+         if not path.startswith(prefix):
+             forget(path)
  
  def isdir(path):
!     """Return 1 if directory, else 0."""
      try:
          st = stat(path)
!     except _os.error:
          return 0
      return S_ISDIR(st[ST_MODE])