[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])