for those of you with 3.2.x sites, here is a drop-in replacement for util_memoize that is about 30% faster thanks to using catch {nsv_get ...} rather than a separate nsv_exists calls.
proc_doc util_memoize {tcl_statement {oldest_acceptable_value_in_seconds ""}} {
Returns the result of evaluating the Tcl statement argument
and remembers that value in a cache; the memory persists
for the specified number of seconds
(or until the server is restarted if the second argument is not supplied)
or until someone calls util_memoize_flush with the same Tcl statement.
Note that this procedure should be used with care because it calls the
eval built-in procedure (and therefore an unscrupulous user could do Bad Things.
} {
# we look up the statement in the cache to see if it has already
# been eval'd. The statement itself is the key
if {[catch {
set statement_value [nsv_get util_memoize_cache_value $tcl_statement]
}] \
|| (![empty_string_p $oldest_acceptable_value_in_seconds] \
&& [nsv_get util_memoize_cache_timestamp $tcl_statement] + $oldest_acceptable_value_in_seconds < [ns_time]) \
} {
# not in the cache already OR the caller spec'd an expiration
# time and our cached value is too old
set statement_value [eval $tcl_statement]
nsv_set util_memoize_cache_value $tcl_statement $statement_value
# store the time in seconds since 1970
nsv_set util_memoize_cache_timestamp $tcl_statement [ns_time]
}
return $statement_value
}