From 32be80a2a01e7c5369ebc2a1687a55bda00abf4d Mon Sep 17 00:00:00 2001 From: zapdos26 Date: Mon, 16 Feb 2026 22:21:56 -0500 Subject: [PATCH 1/3] perf: add in-memory cache for getFilesInDirectory results Wrap getFilesInDirectory (C extension or Tcl fallback) with an in-memory cache keyed by directory path and fetch_dotversion flag. The cache lives for the duration of a single modulecmd process, avoiding redundant directory reads when the same directory is accessed multiple times during module resolution or overlapping search traversals. This reduces NFS round-trips on systems with thousands of modulefiles across deep directory structures. Signed-off-by: zapdos26 --- tcl/main.tcl.in | 13 +++++++++++++ 1 file changed, 13 insertions(+) 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 From 45e34c03069542c30ad22708e90f9b5b7f422b25 Mon Sep 17 00:00:00 2001 From: zapdos26 Date: Mon, 16 Feb 2026 23:58:45 -0500 Subject: [PATCH 2/3] test: add directory read cache consistency tests Verify that the in-memory getFilesInDirectory cache returns correct results on repeated queries within a single invocation. Tests exercise cache population and cache hit paths. Signed-off-by: zapdos26 --- testsuite/modules.90-avail/025-memcache.exp | 31 +++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 testsuite/modules.90-avail/025-memcache.exp diff --git a/testsuite/modules.90-avail/025-memcache.exp b/testsuite/modules.90-avail/025-memcache.exp new file mode 100644 index 000000000..08fd1b049 --- /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 ts1 "$modpath:\nloc_fq/1.0" +testouterr_cmd "sh" "avail -t loc_fq" "OK" $ts1 + +# 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 From 450d178dbfc169f4b5e041509bd42cfd3bc9b4e5 Mon Sep 17 00:00:00 2001 From: zapdos26 Date: Tue, 17 Feb 2026 01:07:36 -0500 Subject: [PATCH 3/3] Fix test to include the 2.0 which is not hidden due to not setting set env(TESTSUITE_MCOOKIE_CHECK) evalhide Signed-off-by: zapdos26 --- testsuite/modules.90-avail/025-memcache.exp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testsuite/modules.90-avail/025-memcache.exp b/testsuite/modules.90-avail/025-memcache.exp index 08fd1b049..fb113987b 100644 --- a/testsuite/modules.90-avail/025-memcache.exp +++ b/testsuite/modules.90-avail/025-memcache.exp @@ -15,8 +15,8 @@ # test that consecutive avail queries return consistent results # first query populates the cache, second should hit it -set ts1 "$modpath:\nloc_fq/1.0" -testouterr_cmd "sh" "avail -t loc_fq" "OK" $ts1 +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