summaryrefslogtreecommitdiffstats
path: root/Lib/statcache.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/statcache.py')
-rw-r--r--Lib/statcache.py90
1 files changed, 90 insertions, 0 deletions
diff --git a/Lib/statcache.py b/Lib/statcache.py
new file mode 100644
index 0000000..eeb0ca4
--- /dev/null
+++ b/Lib/statcache.py
@@ -0,0 +1,90 @@
+# Module 'statcache'
+#
+# Maintain a cache of file stats.
+# There are functions to reset the cache or to selectively remove items.
+
+import posix
+
+
+# The cache.
+# Keys are pathnames, values are `posix.stat' outcomes.
+#
+cache = {}
+
+
+# Stat a file, possibly out of the cache.
+#
+def stat(path):
+ try:
+ return cache[path]
+ except RuntimeError:
+ pass
+ cache[path] = ret = posix.stat(path)
+ return ret
+
+
+# Reset the cache completely.
+# Hack: to reset a global variable, we import this module.
+#
+def reset():
+ import statcache
+ # Check that we really imported the same module
+ if cache is not statcache.cache:
+ raise 'sorry, statcache identity crisis'
+ statcache.cache = {}
+
+
+# Remove a given item from the cache, if it exists.
+#
+def forget(path):
+ try:
+ del cache[path]
+ except RuntimeError:
+ pass
+
+
+# Remove all pathnames with a given prefix.
+#
+def forget_prefix(prefix):
+ n = len(prefix)
+ for path in cache.keys():
+ if path[:n] = prefix:
+ del cache[path]
+
+
+# Forget about a directory and all entries in it, but not about
+# entries in subdirectories.
+#
+def forget_dir(prefix):
+ 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]
+
+
+# Remove all pathnames except with a given prefix.
+# Normally used with prefix = '/' after a chdir().
+#
+def forget_except_prefix(prefix):
+ n = len(prefix)
+ for path in cache.keys():
+ if path[:n] <> prefix:
+ del cache[path]
+
+
+# Check for directory.
+#
+def isdir(path):
+ try:
+ # mode is st[0]; type is mode/4096; S_IFDIR is 4
+ return stat(path)[0] / 4096 = 4
+ except RuntimeError:
+ return 0