Main Page » XQuery » Functions » Cache Functions

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.

Conventions

All functions and errors are in the http://basex.org/modules/cache namespace, to which the cache prefix is statically bound.

Key-value Operations

cache:get

Signature
cache:get(  $key   as xs:string,  $name  as xs:string?  := '') as item()*create
SummaryRetrieves 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.

cache:put

Signature
cache:put(  $key    as xs:string,  $value  as item()*,  $name   as xs:string?  := '') as empty-sequence()create
SummaryStores 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.

cache:get-or-put

Signature
cache:get-or-put(  $key   as xs:string,  $put   as fn() as item()*,  $name  as xs:string?  := '') as item()*create
SummaryRetrieves 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.

cache:remove

Signature
cache:remove(  $key   as xs:string,  $name  as xs:string?  := '') as empty-sequence()create
SummaryRemoves 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.

cache:keys

Signature
cache:keys(  $name  as xs:string?  := '') as xs:string*create
SummaryLists the names of all keys of the default cache, or of a custom cache if $name is specified.

cache:size

Signature
cache:size(  $name  as xs:string?  := '') as xs:integercreate
SummaryReturns the number of entries in the default cache, or in a custom cache if $name is specified.

cache:info

Signature
cache:info(  $name  as xs:string?  := '') as map(xs:string, xs:integer)create
SummaryReturns 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.

Organize Caches

cache:init

Signature
cache:init(  $options  as map(*)?  := {},  $name     as xs:string?  := '') as empty-sequence()create
SummaryInitializes 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:

optiondefaultdescription
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.

cache:list

Signature
cache:list() as xs:string*create
SummaryLists the names of all custom caches.

cache:delete

Signature
cache:delete(  $name  as xs:string?  := '') as empty-sequence()create
SummaryRemoves all entries from the default cache, or deletes a custom cache if $name is specified. Options that were supplied via cache:init are preserved.

cache:clear

Signature
cache:clear() as empty-sequence()create
SummaryClears the default cache and removes all other caches, including the options that were supplied via cache:init.

Examples

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.

Changelog

Version 13.0
  • Added: New module.

⚡Generated with XQuery