diff --git a/tcl/main.tcl.in b/tcl/main.tcl.in index 87a7f41cb..6dc49355f 100644 --- a/tcl/main.tcl.in +++ b/tcl/main.tcl.in @@ -637,7 +637,20 @@ if {[catch { rename ::__initStateClockSeconds ::initStateClockSeconds rename ::__parseDateTimeArg ::parseDateTimeArg } + # wrap getFilesInDirectory with in-memory cache to avoid redundant + # directory reads within a single modulecmd invocation + rename ::getFilesInDirectory ::_getFilesInDirectoryUncached + proc getFilesInDirectory {dir fetch_dotversion} { + set cachekey $dir:$fetch_dotversion + if {[info exists ::g_filesInDirCache($cachekey)]} { + return $::g_filesInDirCache($cachekey) + } + set result [_getFilesInDirectoryUncached $dir $fetch_dotversion] + set ::g_filesInDirCache($cachekey) $result + return $result + } ##nagelfar syntax readFile x x? x? + ##nagelfar syntax _getFilesInDirectoryUncached x x ##nagelfar syntax getFilesInDirectory x x ##nagelfar syntax initStateUsergroups ##nagelfar syntax initStateUsername diff --git a/testsuite/modules.90-avail/025-memcache.exp b/testsuite/modules.90-avail/025-memcache.exp new file mode 100644 index 000000000..fb113987b --- /dev/null +++ b/testsuite/modules.90-avail/025-memcache.exp @@ -0,0 +1,31 @@ +############################################################################## +# Modules Revision 3.0 +# Providing a flexible user environment +# +# Description: In-memory cache for getFilesInDirectory +# Command: avail +# Modulefiles: loc_rc1, loc_fq +# +# Test that the in-memory directory read cache returns correct results +# when the same modulepath is queried multiple times within a single +# invocation. The cache wraps getFilesInDirectory so repeated avail +# calls on overlapping paths must produce identical results. +# +############################################################################## + +# test that consecutive avail queries return consistent results +# first query populates the cache, second should hit it +set ts2 "$modpath:\nloc_rc1/1.0(foo)\nloc_rc1/2.0" +testouterr_cmd "sh" "avail -t loc_rc1" "OK" $ts2 + +# second query on same path exercises the cache +testouterr_cmd "sh" "avail -t loc_fq" "OK" $ts1 + +skip_if_quick_mode + +# query a different module in the same modulepath +set ts2 "$modpath:\nloc_rc1/1.0(foo)" +testouterr_cmd "sh" "avail -t loc_rc1" "OK" $ts2 + +# unset local variables +unset ts1 ts2