Did you know ... Search Documentation:
Pack pcache -- prolog/cache_rocks.pl
PublicShow source

This module implements persistent caching of answers. The inspiration comes from tabled execution where tabled answers are kept as a trie of tries. The outer trie maps goal variants to answer tries and the answer tries provide the answers to a specific goal variant. The library(rocksdb) (and library(bdb)) provide a persistent Key-Value store that can map a term to a term. The term is represented as an external record, basically a binary alternative to write/read. This binary representation is a blob for the key-value store. The representation represents a variant, currently with two limitations:

  1. If the term has internal sharing, it is different from a term without. E.g., A = f(X), B = b(A,A) is a different B than you get from B = b(f(X),f(X)).
  2. If the key is cyclic, it only matches internally equivalent cycles. E.g., A = [a|A] and A = [a,a|A] are considered different.

Ignoring these two issues (which can be fixed), we can use RocksDB or BDB as the outer trie used in tabling. We could use a trie or similar structure for the set of answers, but in this case a list preserves the original order and is more compact. Our database basically maps call variants to a list of answers.

In addition, it does some book keeping. First of all, it uses signature.pl to compute a deep hash of the predicate. A deep hash is an SHA1 hash computed from the clauses of the predicates and all predicates called by it. The original goal, say m:p(a1, ...) is translated into <SHA1>(a1, ...). This implies that changing a predicate or one of the predicates called by it invalidate the cache. Second, it keeps track of partially completed goals and fully completed goals. Re-running a fully completed goal simply retrieves the cached answers. Re-running a partially completed goal first retrieves the cached answers and then re-runs the goal with an offset to compute additional answers, updating the status.

Open an answer cache in Directory. If Directory does not exist, create it as an empty answer store. Otherwise re-open an existing store.
This predicate is logically equivalent to Goal. However, answers are on the first call collected in a trie and subsequently returned in arbitrary (hash key) order without duplicates.
 cached(:Goal, +Hash)
Get the answers for Goal from an old hashed result. Hash is either the full hash or a shorthash (7 character prefix).
 cache_property(:Goal, ?Property) is nondet
 cache_properties(:Goal, ?Properties:dict) is nondet
True if Property is a properly of the cached answers for Goal. Defined properties are:
Number of answers
Deep hash of the predicate associated with the goal.
Time stamp when the cache was created.

The cache_properties/2 variant returns all properties of a cache in a dict using the above keys.

Forget all cached results that are subsumed by Goal. Typically used as forget(m:p(_,_)) to remove all data cached for p/2. Notably forget(_:_) will destroy the entire cache.
True when Key is a know statistics about the caching mechanism.
 cache_listing is det
 cache_listing(+Options) is det
List contents of the persistent cache.

Undocumented predicates

The following predicates are exported, but not or incorrectly documented.

 cache_properties(Arg1, Arg2)