Cache Functions
Added: New module.
This module provides functions to store transient data in main-memory caches.
Computing a result can be expensive. If it is frequently needed, for example in a Web Application, it can be cheaper to cache it in main memory. The architecture has the following properties:
- Data can be distributed across multiple caches, which are identified by names. If no name is specified in a cache operation, data is stored in the default cache (named
""). - A single cache is limited to a maximum number of entries, defined by
CACHEMAX, and its entries expire after the number of seconds defined by CACHETTL. Both defaults can be adjusted at startup time, depending on server characteristics, and they can be overridden for a single cache with cache:init. - The caches use the LRU replacement policy: Least recently used entries are dropped first.
- Expired entries are discarded when the cache is accessed the next time.
The Key/Value Store provides similar functionality, but entries in the store never expire, and can be made persistent.
Functions of this module are nondeterministic and side-effecting: Updates will immediately be visible, and a repeated call of the same function may yield different results if the contents of the cache have changed.
All functions and errors are in the http://basex.org/modules/cache namespace, to which the cache prefix is statically bound.
| Signature | cache:get( $key as xs:string, $name as xs:string? := '') as item()*create |
|---|
| Summary | Retrieves an entry with the given $key from the default cache, or from a custom cache if $name is specified:
- If the addressed entry does not exist, an empty sequence is returned.
- When a cache entry is accessed, it will remain longer in the cache.
|
|---|
| Signature | cache:put( $key as xs:string, $value as item()*, $name as xs:string? := '') as empty-sequence()create |
|---|
| Summary | Stores an entry with the given $key and $value in the default cache, or in a custom cache if $name is specified:
- If the addressed cache does not exist yet, it will be created automatically.
- If the value is an empty sequence, its entry is removed.
- Before a value is stored, it is compactified (see
prof:shrink for more information). - Additionally, if a value refers to an opened database or is a lazy item, its contents are materialized in main memory.
- Values with function items are rejected.
|
|---|
| Signature | cache:get-or-put( $key as xs:string, $put as fn() as item()*, $name as xs:string? := '') as item()*create |
|---|
| Summary | Retrieves an entry with the given $key from the default cache, or from a custom cache if $name is specified. The $put function will only be invoked if the entry does not exist, and its result will be cached and returned:
- The lookup and the invocation of the function are not atomic. If several queries request the same missing entry at the same time, the function will be evaluated by each of them, and the last result will be cached.
|
|---|
| Signature | cache:remove( $key as xs:string, $name as xs:string? := '') as empty-sequence()create |
|---|
| Summary | Removes an entry with the given $key from the default cache, or from a custom cache if $name is specified. No error will be raised if an addressed entry does not exist. |
|---|
| Signature | cache:keys( $name as xs:string? := '') as xs:string*create |
|---|
| Summary | Lists the names of all keys of the default cache, or of a custom cache if $name is specified. |
|---|
| Signature | cache:size( $name as xs:string? := '') as xs:integercreate |
|---|
| Summary | Returns the number of entries in the default cache, or in a custom cache if $name is specified. |
|---|
| Signature | cache:info( $name as xs:string? := '') as map(xs:string, xs:integer)create |
|---|
| Summary | Returns statistics on the default cache, or on a custom cache if $name is specified:
entries: current number of entries.hits: number of lookups that found an entry.misses: number of lookups that found no entry.evictions: number of entries that were dropped by the replacement policy.expirations: number of entries that were discarded because their lifetime had elapsed.- The counters are bound to the lifetime of a cache: They start at zero and are discarded if the cache is deleted or cleared. Lookups on a cache that does not exist yet are not counted.
|
|---|
| Signature | cache:init( $options as map(*)? := {}, $name as xs:string? := '') as empty-sequence()create |
|---|
| Summary | Initializes the default cache, or a custom cache if $name is specified:
- The function can be called before every cache operation: If a cache has already been initialized with the same options, nothing happens.
- If the options differ, they will replace the existing ones. Existing entries are preserved, but entries that exceed a reduced maximum are dropped at once. A changed lifetime only applies to entries that are stored afterwards.
- The options of a cache are preserved by
cache:delete and discarded by cache:clear. A cache that has not been initialized uses the default options.
The following $options are available:
| option | default | description |
|---|
max-entries | – |
Maximum number of entries. If the limit is exceeded, the least recently used entry is dropped. Defaults to CACHEMAX.
| ttl | – |
Lifetime of an entry in seconds. If the value is 0, entries will never expire. Defaults to CACHETTL.
|
|
|---|
| Signature | cache:list() as xs:string*create |
|---|
| Summary | Lists the names of all custom caches. |
|---|
| Signature | cache:delete( $name as xs:string? := '') as empty-sequence()create |
|---|
| Summary | Removes all entries from the default cache, or deletes a custom cache if $name is specified. Options that were supplied via cache:init are preserved. |
|---|
| Signature | cache:clear() as empty-sequence()create |
|---|
| Summary | Clears the default cache and removes all other caches, including the options that were supplied via cache:init. |
|---|
Use Case: Cache RESTXQ responses
declare
%rest:path('/person/{$name}')
function local:search(
$name as xs:string
) as element()* {
let $result := fn() { db:get('persons')//person/name[text() contains text { $name }] }
return (
cache:init({ 'max-entries': 1000, 'ttl': 600 }, 'persons'),
cache:get-or-put('person:' || $name, $result, 'persons')
)
};
If many clients request the same RESTXQ endpoint, it can be cheaper to cache the result instead of computing it again and again. In this example, person data is looked up in a database. If a cache entry for the given person exists, a previously computed result will be returned. Otherwise, the result will be generated and returned to the client.
As cache:init does nothing if the cache has already been initialized with the same options, it can be called on every request. The lifetime of ten minutes limits how long a client can be served a result that was invalidated by an update of the database. If updates need to be reflected at once, the affected entries can be dropped with cache:remove.
Version 13.0
⚡Generated with XQuery