Reap passes

When the number of references to a key storable object equals the number of references to an object from keys in the Store, we know that we can remove all the items which have that object as part of the key. This is done by running a pass over the store, `reaping' those items.

If a key does not consist of any storable objects, then the needs_reap entry in its fz_store_type can safely be left as NULL. If it does, however, it must provide an implementation to check whether a reap pass is required. Essentially this needs to check if any of its constituent fz_key_storable objects need reaping, which can be done by a call to:


\begin{lstlisting}
int fz_key_storable_needs_reaping(fz_context *ctx, const fz_key_storable *ks);
\end{lstlisting}

Reap passes are slower than we would like as they touch every item in the store. We therefore provide a way to `batch' such reap passes together, using fz_defer_reap_start and fz_defer_reap_end to bracket a region in which many may be triggered.

The need for a reap is detected as part of normal operations in the core code, and such passes are then triggered automatically as required. The user need never (and indeed cannot) trigger such passes manually. The user can, however, exercise some control over when such operations take place.

If an application is about to perform an operation that may drop many objects (say dropping a collection of cached display lists), then it should call fz_defer_reap_start beforehand, and match that with a fz_defer_reap_end afterwards. Any reap passes triggered by the dropping of objects within the display lists would be deferred until the end - resulting in at most one pass rather than potentially many.