Index: openacs-4/packages/acs-tcl/tcl/memoize-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/memoize-procs.tcl,v diff -u -N -r1.1 -r1.2 --- openacs-4/packages/acs-tcl/tcl/memoize-procs.tcl 13 Mar 2001 22:59:26 -0000 1.1 +++ openacs-4/packages/acs-tcl/tcl/memoize-procs.tcl 12 Apr 2001 16:58:18 -0000 1.2 @@ -8,254 +8,130 @@ @cvs-id $Id$ } -if {[llength [info commands ns_cache]] > 0} { +# Use shiny new ns_cache-based util_memoize. - # Use shiny new ns_cache-based util_memoize. +ad_proc util_memoize {script {max_age ""}} { + If script has been executed before, return the value it + returned last time, unless it was more than max_age seconds ago. - ad_proc util_memoize {script {max_age ""}} { - If script has been executed before, return the value it - returned last time, unless it was more than max_age seconds ago. +

Otherwise, evaluate script and cache and return the + result. -

Otherwise, evaluate script and cache and return the - result. +

Note: script is not evaluated with uplevel. -

Note: script is not evaluated with uplevel. + @param script A Tcl script whose value should be memoized. May be + best to pass this as a list, e.g. [list someproc $arg1 $arg2]. - @param script A Tcl script whose value should be memoized. May be - best to pass this as a list, e.g. [list someproc $arg1 $arg2]. + @param max_age The maximum age in seconds for the cached value of + script. If the cached value is older than max_age + seconds, script will be re-executed. - @param max_age The maximum age in seconds for the cached value of - script. If the cached value is older than max_age - seconds, script will be re-executed. + @return The possibly-cached value returned by script. +} { - @return The possibly-cached value returned by script. - } { - if {![string equal $max_age ""] && $max_age < 0} { - error "max_age must not be negative" - } - - set current_time [ns_time] - - set cached_p [ns_cache get util_memoize $script pair] - - if {$cached_p && [string compare $max_age ""] != 0} { - set cache_time [lindex $pair 0] - if {$current_time - $cache_time > $max_age} { - ns_cache flush util_memoize $script - set cached_p 0 - } - } - - if {!$cached_p} { - set pair [ns_cache eval util_memoize $script { - list $current_time [eval $script] - }] - } - - return [lindex $pair 1] + if {![string equal $max_age ""] && $max_age < 0} { + error "max_age must not be negative" } - ad_proc util_memoize_seed {script value {max_age ""}} { - Pretend util_memoize was called with script and - it returned value. Cache value, replacing any - previous cache entry for script. + set current_time [ns_time] -

If clustering is enabled, this command flushes script's - value from the caches on all servers in the cluster before storing - the new value. The new value is only stored in the local cache. + set cached_p [ns_cache get util_memoize $script pair] - @param script A Tcl script that presumably would return - value. - - @param value The value to cache for script. - - @param max_age Not used. - } { - util_memoize_flush $script - - ns_cache set util_memoize $script [list [ns_time] $value] + if {$cached_p && [string compare $max_age ""] != 0} { + set cache_time [lindex $pair 0] + if {$current_time - $cache_time > $max_age} { + ns_cache flush util_memoize $script + set cached_p 0 + } } - ad_proc util_memoize_flush_local {script} { - Forget any cached value for script. You probably want to use - util_memoize_flush to flush the caches on all servers - in the cluster, in case clustering is enabled. - - @param script The Tcl script whose cached value should be flushed. - } { - ns_cache flush util_memoize $script + if {!$cached_p} { + set pair [ns_cache eval util_memoize $script { + list $current_time [eval $script] + }] } - # We construct the body of util_memoize_flush differently depending - # on whether clustering is enabled and what command is available for - # cluster-wide flushing. + return [lindex $pair 1] +} - if {[llength [info commands ncf.send]] > 0} { - set flush_body { - ncf.send util_memoize $script - } - } elseif {[llength [info commands server_cluster_httpget_from_peers]] > 0} { - set flush_body { - server_cluster_httpget_from_peers "/SYSTEM/flush-memoized-statement.tcl?statement=[ns_urlencode $script]" - } - } else { - set flush_body {} - } +ad_proc util_memoize_seed {script value {max_age ""}} { + Pretend util_memoize was called with script and + it returned value. Cache value, replacing any + previous cache entry for script. - append flush_body { - ns_cache flush util_memoize $script - } +

If clustering is enabled, this command flushes script's + value from the caches on all servers in the cluster before storing + the new value. The new value is only stored in the local cache. - ad_proc util_memoize_flush {script} { - Forget any cached value for script. If clustering is - enabled, flush the caches on all servers in the cluster. + @param script A Tcl script that presumably would return + value. - @param script The Tcl script whose cached value should be flushed. - } $flush_body + @param value The value to cache for script. - unset flush_body + @param max_age Not used. +} { + util_memoize_flush $script - ad_proc util_memoize_cached_p {script {max_age ""}} { - Check whether script's value has been cached, and whether it - was cached no more than max_age seconds ago. + ns_cache set util_memoize $script [list [ns_time] $value] +} - @param script A Tcl script. +ad_proc util_memoize_flush_local {script} { + Forget any cached value for script. You probably want to use + util_memoize_flush to flush the caches on all servers + in the cluster, in case clustering is enabled. - @param max_age Maximum age of cached value in seconds. + @param script The Tcl script whose cached value should be flushed. +} { + ns_cache flush util_memoize $script +} - @return Boolean value. - } { - if {![ns_cache get util_memoize $script pair]} { - return 0 - } +# We construct the body of util_memoize_flush differently depending +# on whether clustering is enabled and what command is available for +# cluster-wide flushing. - if {[string equal $max_age ""]} { - return 1 - } else { - set cache_time [lindex $pair 0] - return [expr {[ns_time] - $cache_time <= $max_age}] - } +if {[llength [info commands ncf.send]] > 0} { + set flush_body { + ncf.send util_memoize $script } - +} elseif {[llength [info commands server_cluster_httpget_from_peers]] > 0} { + set flush_body { + server_cluster_httpget_from_peers "/SYSTEM/flush-memoized-statement.tcl?statement=[ns_urlencode $script]" + } } else { + set flush_body {} +} - # Use crusty old NSV-based util_memoize. +append flush_body { + ns_cache flush util_memoize $script +} - ad_proc util_memoize { - tcl_statement - {oldest_acceptable_value_in_seconds ""} - } { +ad_proc util_memoize_flush {script} { + Forget any cached value for script. If clustering is + enabled, flush the caches on all servers in the cluster. - Returns the result of evaluating the Tcl statement argument and - then 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. + @param script The Tcl script whose cached value should be flushed. +} $flush_body - @param tcl_statement The tcl statement to be memoized. Usually - best to put this in a list, e.g. [list proc $arg1 $arg2] +unset flush_body - @param oldest_acceptable_value_in_seconds Specifies how long the - memoization should persist. +ad_proc util_memoize_cached_p {script {max_age ""}} { + Check whether script's value has been cached, and whether it + was cached no more than max_age seconds ago. - @return The cached value of the tcl_statement. - } { + @param script A Tcl script. - # we look up the statement in the cache to see if it has already - # been eval'd. The statement itself is the key + @param max_age Maximum age of cached value in seconds. - if { - ![nsv_exists 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 [nsv_get util_memoize_cache_value $tcl_statement] + @return Boolean value. +} { + if {![ns_cache get util_memoize $script pair]} { + return 0 } - proc_doc util_memoize_seed { - tcl_statement - value - {oldest_acceptable_value_in_seconds ""} - } { - Seeds the memoize catch with a particular value. - If clustering is enabled, flushes cached values - from peers in the cluster. - } { - if {[llength [info procs server_cluster_httpget_from_peers]] == 1} { - server_cluster_httpget_from_peers "/SYSTEM/flush-memoized-statement.tcl?statement=[ns_urlencode $tcl_statement]" - } - - nsv_set util_memoize_cache_value $tcl_statement $value - # store the time in seconds since 1970 - nsv_set util_memoize_cache_timestamp $tcl_statement [ns_time] + if {[string equal $max_age ""]} { + return 1 + } else { + set cache_time [lindex $pair 0] + return [expr {[ns_time] - $cache_time <= $max_age}] } - - proc_doc util_memoize_flush_local {tcl_statement} { - Flush the cached value only on the local server. - In general you will want to use util_memoize_flush instead of this! - } { - if [nsv_exists util_memoize_cache_value $tcl_statement] { - nsv_unset util_memoize_cache_value $tcl_statement - } - if [nsv_exists util_memoize_cache_timestamp $tcl_statement] { - nsv_unset util_memoize_cache_timestamp $tcl_statement - } - } - - proc_doc util_memoize_flush {tcl_statement} { - Flush the cached value (established with util_memoize - associated with the argument). If clustering is enabled, - flushes cached values from peers in the cluster. - } { - if {[llength [info procs server_cluster_httpget_from_peers]] == 1} { - server_cluster_httpget_from_peers "/SYSTEM/flush-memoized-statement.tcl?statement=[ns_urlencode $tcl_statement]" - } - util_memoize_flush_local $tcl_statement - } - - proc_doc util_memoize_value_cached_p { - tcl_statement - {oldest_acceptable_value_in_seconds ""} - } { - Returns 1 if there is a cached value for this Tcl expression. If a second argument is supplied, only returns 1 if the cached value isn't too old. - } { - - # we look up the statement in the cache to see if it has already - # been eval'd. The statement itself is the key - - if { - ![nsv_exists 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] - ) - ) - } { - return 0 - } else { - return 1 - } - } - }