Viewing file: statcache.py (2.26 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
"""Maintain a cache of stat() information on files.
There are functions to reset the cache or to selectively remove items. """
import os as _os from stat import *
__all__ = ["stat","reset","forget","forget_prefix","forget_dir", "forget_except_prefix","isdir"]
# 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])
|