Simple, filesystem-based caching. Wrap your large computations in a thunk and let with-cache deal with saving and retrieving the result.
By default, any cache built by an older version of with-cache is invalid. Set *current-cache-keys* to override this default.
Here’s a diagram of what’s happening in with-cache :
The dollar sign on the left represents a value that is expensive to compute.
The box in the left-middle is a serialized version of the expensive value.
The yellow box in the right-middle is the serialized data paired with a (yellow) label.
The file symbol on the right represents a location on the filesystem.
#:write and #:read are optional arguments to with-cache . They default to serialize and deserialize .
add-keys is a hidden function that adds the value of *current-cache-keys* to a cached value.
keys-equal? compares the keys in a cache file to the now-current value of *current-cache-keys* .
write-data and read-data are s-exp->fasl and fasl->s-exp when the parameter *with-cache-fasl?* is #t. Otherwise, these functions are write and read .
procedure
thunk[ #:readread-proc#:writewrite-proc#:use-cache?use-cache?#:fasl?fasl?#:keyskeyscache-path:path-string?
reads the contents of cache-path (using s-exp->fasl if *with-cache-fasl?* is #t and read otherwise);
checks whether the result contains keys equal to *current-cache-keys* , where "equal" is determined by keys-equal?;
if so, removes the keys and deserializes a value.
executes thunk, obtains result r;
retrieves the values of *current-cache-keys* ;
saves the keys and r to cache-path;
returns r
Uses call-with-file-lock/timeout to protect concurrent reads and writes to the same cache-path. If a thread fails to lock cache-path, with-cache throws an exception (exn:fail:filesystem ) giving the location of the problematic lock file. All lock files are generated by make-lock-file-name and stored in (find-system-path 'temp-dir).
Diagnostic information is logged under the with-cache topic. To see logging information, use either:
racket -W with-cache <file.rkt>
or, if you are not invoking racket directly:
PLTSTDERR="error info@with-cache" <CMD>
parameter
( *use-cache?* )→boolean?
use-cache?:boolean?= #t
parameter
fasl?:boolean?= #t
Note that byte strings written using s-exp->fasl cannot be read by code running a different version of Racket.
parameter
parameter
Before writing a cache file, with-cache gets the value of *current-cache-keys* (by taking the value of the parameters and forcing the thunks) and writes the result to the file. When reading a cache file, with-cache gets the current value of *current-cache-keys* and compares this value to the value written in the cache file. If the current keys are NOT equal to the old keys (equal in the sense of *keys-equal?* ), then the cache is invalid.
For example, (*current-cache-keys* (list current-seconds )) causes with-cache to ignore cachefiles written more than 1 second ago.
(fresh-fish);Writes to "compiled/with-cache/stdfish.rktd"(fresh-fish);Reads from "compiled/with-cache/stdfish.rktd"(fresh-fish);Writes to "compiled/with-cache/stdfish.rktd"
By default, the only key is a thunk that retrieves the installed version of the with-cache package.
parameter
= equal?
A cache is invalid if (=?old-keyscurrent-keys) returns #false, where current-keys is the current value of *current-cache-keys* .
(=?kk) returns a true value for all k;
(=?k1k2) returns the same value as (=?k2k1); and
(and (=?k1k2)(=?k2k3)) implies (=?k1k3) is true.
The contract equivalence/c does not enforce these laws, but it might in the future.
procedure
( cachefile filename)→parent-directory-exists?
filename:path-string?
procedure
x:any/c
procedure
( equivalence/c x)→boolean?
x:any/c
procedure
value