You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rb...@locus.apache.org on 2000/07/29 16:44:26 UTC

cvs commit: apache-2.0/src/include ap_cache.h

rbb         00/07/29 07:44:26

  Modified:    src/include ap_cache.h
  Log:
  Add ScanDoc documentation to ap_cache.h.
  Submitted by:	Sam Magnuson <sm...@aventail.com>
  Reviewed by:	Ryan Bloom
  
  Revision  Changes    Path
  1.2       +313 -141  apache-2.0/src/include/ap_cache.h
  
  Index: ap_cache.h
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/include/ap_cache.h,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ap_cache.h	2000/06/12 20:42:02	1.1
  +++ ap_cache.h	2000/07/29 14:44:26	1.2
  @@ -1,141 +1,313 @@
  -#ifndef __AP_CACHE_H__
  -#define __AP_CACHE_H__
  -
  -#include <stdarg.h>
  -#include "httpd.h"
  -#include "apr_file_io.h"
  -#include "apr_network_io.h"
  -#include "buff.h"            /* get BUFF */
  -#include "apr_pools.h"       /* get ap_table */
  -#include "ap_hooks.h"        /* get hook defines */
  -#include "httpd.h"
  -
  -/* ***** Types used by clients of this library ***** */
  -typedef struct ap_cache_handle_t ap_cache_handle_t;
  -typedef struct ap_cache_el 
  -{
  -    ap_cache_handle_t *cache;
  -    const char *name;
  -} ap_cache_el;
  -
  -/* works on the cache database as a whole */
  -
  -/* database maintance */
  -ap_status_t ap_cache_init(ap_cache_handle_t **h, const char *desc, server_rec *r);
  -ap_status_t ap_cache_close(ap_cache_handle_t *);
  -ap_status_t ap_cache_garbage_collect(ap_cache_handle_t *h);
  -
  -/* insertion and query into database */
  -ap_status_t ap_cache_seek(ap_cache_handle_t *h, const char *name, ap_cache_el **);
  -ap_status_t ap_cache_create(ap_cache_handle_t *h, const char *name, ap_cache_el **);
  -ap_status_t ap_cache_remove(ap_cache_handle_t *h, const char *name);
  -
  -/* works on an actual element */
  -
  -/* works on the header section */
  -ap_status_t ap_cache_el_header(ap_cache_el *el, const char *hdr, char **val);
  -ap_status_t ap_cache_el_header_walk(ap_cache_el *el, 
  -                                    int (*comp)(void *, const char *, const char *), void *rec, ...);
  -ap_status_t ap_cache_el_header_merge(ap_cache_el *el, ap_table_t *tbl);
  -ap_status_t ap_cache_el_header_set(ap_cache_el *el, const char *hdrname, const char *hdrval);
  -ap_status_t ap_cache_el_header_add(ap_cache_el *el, const char *hdrname, const char *hdrval);
  -ap_status_t ap_cache_el_header_remove(ap_cache_el *el, const char *hdr);
  -ap_status_t ap_cache_el_header_clear(ap_cache_el *el);
  -
  -/* works on the data section */
  -ap_status_t ap_cache_el_data(ap_cache_el *el, BUFF **);
  -ap_status_t ap_cache_el_data_append(ap_cache_el *el, BUFF *data);
  -ap_status_t ap_cache_el_data_clear(ap_cache_el *el);
  -
  -/* complete element, it needs to be closed when you are done working with
  -   it, whether it comes from a query, or you created it and work on it */
  -ap_status_t ap_cache_el_finalize(ap_cache_el *el);
  -
  -/****** 
  -    These types are all used by implementors of modules using this
  -    API, NOBODY but caching modules should EVER use this part of the API. 
  -******/
  -typedef enum { AP_CACHE_SEEK, AP_CACHE_CREATE, AP_CACHE_CHANGE, AP_CACHE_REMOVE } ap_cache_query;
  -typedef enum { AP_CACHE_DATA, AP_CACHE_HEADER } ap_cache_part;
  -typedef struct ap_cache_methods 
  -{
  -    ap_status_t (*cache_close)(ap_cache_handle_t *h);
  -    ap_status_t (*cache_garbage_coll)(ap_cache_handle_t *h);
  -    ap_status_t (*cache_element)(ap_cache_handle_t *h, const char *name, ap_cache_el **,
  -                                 ap_cache_query flag);
  -    ap_status_t (*cache_el_header_walk)(ap_cache_el *el, 
  -                                     int (*comp)(void *, const char *, const char *), void *rec, va_list);
  -    ap_status_t (*cache_el_hdr)(ap_cache_el *el, const char *name, const char *val, ap_cache_query flag);
  -    ap_status_t (*cache_el_data)(ap_cache_el *el, BUFF **);
  -    ap_status_t (*cache_el_data_reset)(ap_cache_el *);
  -    ap_status_t (*cache_el_reset)(ap_cache_el *, ap_cache_part flag);
  -    ap_status_t (*cache_el_final)(ap_cache_el *el);
  -} ap_cache_methods;
  -/* This is how a cache module can grab control of a given cache */
  -AP_DECLARE_HOOK(ap_status_t, cache_init, (ap_cache_handle_t **, const char *desc, server_rec *t))
  -/* This is declared here because modules need to fill this in, however
  -   clients of the library should NEVER use this */
  -struct ap_cache_handle_t
  -{
  -    ap_pool_t *pool;        /* pool for alloc's */
  -    server_rec *server; /* access to configurations, used on init */
  -    ap_cache_methods meth;
  -};
  -
  -/* General ideas about this interface:
  -
  -   A cache element has two distinct parts, the header and the data. This
  -   happens to match perfectly for mod_proxy's use of cache, however it is
  -   fairly well suited to other needs, one of its uses will in fact be for
  -   expiration, ap_cache will use the "Cache-Control" header entry for this
  -   internally on ap_cache_garbage_collect.
  -   
  -   Client usage:
  -
  -   ap_cache_handle_t *my_cache;
  -   ap_cache_el *element;
  -   BUFF *element_buff;
  -
  -   ap_cache_create(&my_cache, "Cache of Farm Animals");
  -
  -   ap_cache_push(my_cache, "Pig", &element);
  -   ap_cache_el_header_add(element, "Sound", "Oink");
  -   ap_cache_el_data(element, &element_buff);
  -   ap_bputs("I smell bacon!\n", element_buff);
  -   ap_cache_el_finalize(element);
  -
  -   ap_cache_seek(my_cache", "Cow", &element);
  -   ap_cache_el_header_walk(my_cache, some_func, NULL, "Sound", NULL);
  -   ....
  -   
  -   ap_cache_close(my_cache);
  -
  -   A client can do anything it wants to an "active" cache_el however it
  -   must guarantee that when it is done with the cache element it will
  -   be finalized. In this way an element in a cache can only be active one
  -   time (and any cache_seek for this element will fail), for this reason
  -   one shouldn't stay open for long ammounts of time. The client is also
  -   responsible for calling garbage_collect periodically to give the cache a
  -   chance to clean up for itself if this is the behaviour it wants.
  -
  -   Implementation:
  -
  -   Just to take two different points of view, I'll outline how two
  -   different implementations of the cache modules may be written..
  -
  -   SHMEM cache - This cache might really not do anything on the
  -   finalization step as data may just be read and written live, however
  -   it'll probably implement its own iol_methods for the _el_data BUFF's
  -   such that writing to the data will in effect just advance the pointer
  -   and size count along and write to memory.
  -
  -   FILE cache - This cache would probably use a file BUFF for the data
  -   part, but a live ap_table_t for the headers so it would really write the
  -   headers on finalization. In this instance however there would probably
  -   be no price for loading up an element, and the open on the actual data
  -   might not really happen until _el_data or _el_header calls are made
  -   first which then requires the cache file be parsed. It might be most
  -   optimal though to have two files one for headers and one for data for
  -   part of the cache and open each when appropriate.  */
  -
  -#endif /* __AP_CACHE_H__ */
  +#ifndef __AP_CACHE_H__
  +#define __AP_CACHE_H__
  +
  +#include <stdarg.h>
  +#include "httpd.h"
  +#include "apr_file_io.h"
  +#include "apr_network_io.h"
  +#include "buff.h"
  +#include "apr_pools.h"
  +#include "ap_hooks.h"
  +#include "httpd.h"
  +
  +/**
  + * @package Apache Caching Module API
  + */
  +
  +/* Interface to caching modules
  + * This interface will allow access to special modules that will
  + * do actual caching calls and maintain elements appropriatly.
  + *
  + * To date there is only a file version and a shared memory of these caching
  + * backends. Clients of thie API need not know where their data will go, in
  + * general there are several calls (marked A) that will work on the database
  + * as a whole. From those points you will go onto (B) where you can seek, create
  + * and remove records. 
  + * Upon seeking or creating records you will have an active ap_cache_el. You may
  + * continue down into (C) section. 
  + *
  + * A cache element has two distinct parts, the header (D) and the data (E).
  + * One of the uses of the header section will, in fact, be internal to the
  + * cache backends to manage expiration. For example, ap_cache modules may
  + * use the "Cache-Control" header entry for ap_cache_garbage_collect().
  + * All data portions or headers may be used for any purpose, and are not
  + * actually used by the API, though some headers may have special meanings
  + * to certain backends.
  + */
  +
  +/* *********************
  + *  Example client usage:
  + *
  + *  ap_cache_handle_t *my_cache;
  + *  ap_cache_el *element;
  + *  BUFF *element_buff;
  + *
  + *  ap_cache_create(&my_cache, "Cache of Farm Animals");
  + *
  + *  ap_cache_push(my_cache, "Pig", &element);
  + *  ap_cache_el_header_add(element, "Sound", "Oink");
  + *  ap_cache_el_data(element, &element_buff);
  + *  ap_bputs("I smell bacon!\n", element_buff);
  + *  ap_cache_el_finalize(element);
  + *
  + *  ap_cache_seek(my_cache", "Cow", &element);
  + *  ap_cache_el_header_walk(my_cache, some_func, NULL, "Sound", NULL);
  + *  ....
  + *  
  + *  ap_cache_close(my_cache);
  + *
  + *  A client can do anything it wants to an "active" cache_el however it
  + *  must guarantee that when it is done with the cache element it will
  + *  be finalized. In this way an element in a cache can only be active one
  + *  time (and any cache_seek for this element will fail), for this reason
  + *  one shouldn't stay open for long ammounts of time. The client is also
  + *  responsible for calling garbage_collect periodically to give the cache a
  + *  chance to clean up for itself if this is the behaviour it wants.
  + */
  +
  +/* Types used by clients of this interface */
  +typedef struct ap_cache_handle_t ap_cache_handle_t;
  +typedef struct ap_cache_el 
  +{
  +    ap_cache_handle_t *cache;
  +    const char *name;
  +} ap_cache_el;
  +
  +/* A) Works on the cache database as a whole */
  +/**
  + * This will initialize a cache_handle. This is the main entry point into the 
  + * caching API, from this point active caching modules will be asked to fill 
  + * in the cache_handle.
  + * @param  Where to put the handle
  + * @param  A descriptive unique string for your client, this description could
  + *         used by caching modules to determine if the their backend is suitable
  + *         for this client.
  + * @param  Current server_rec, this will be used for retreiving configuration, 
  + *         and various other necesar server pieces.
  + * @deffunc ap_status_t ap_cache_init(ap_cache_handle_t **h, const char *desc, server_rec *r);
  + */
  +ap_status_t ap_cache_init(ap_cache_handle_t **h, const char *desc, server_rec *r);
  +
  +/**
  + * This function will finalize a cache_handle, after this call the handle will
  + * no longer be usable.
  + * @param  The handle to close
  + * @deffunc ap_status_t ap_cache_close(ap_cache_handle_t *);
  + */
  +ap_status_t ap_cache_close(ap_cache_handle_t *);
  +
  +/**
  + * Force a garbage collection of the cache_handle, the client should call this periodically,
  + * the caching module will not do this on its own, however it isn't required to actually 
  + * garbage collect anything, and may defer the call until later.
  + * @param  The handle to force a garbage collection.
  + * @deffunc ap_status_t ap_cache_garbage_collect(ap_cache_handle_t *h);
  + */
  +ap_status_t ap_cache_garbage_collect(ap_cache_handle_t *h);
  +
  +/* B) insertion and query into database */
  +/**
  + * Seek for a given element in an open cache. This call will fail if the requested element
  + * is already "in use" by previous call to ap_cache_seek or ap_cache_create.
  + * When finished with the element you must call ap_cache_el_finalize immediatly so the 
  + * element is no longer locked.
  + * @param  The cache to search in.
  + * @param  The name of the record you are looking for
  + * @param  Where to put the cache element if a seek succeeds.
  + * @deffunc ap_status_t ap_cache_seek(ap_cache_handle_t *h, const char *name, ap_cache_el **);
  + */
  +ap_status_t ap_cache_seek(ap_cache_handle_t *h, const char *name, ap_cache_el **);
  +
  +/**
  + * Create a new element inside of a cache, you must call this first function to put 
  + * something new into a cache; after calling you may use the cache_el passed in as
  + * you would use one retrieved from an ap_cache_seek. The element will be locked after
  + * this call.
  + * When finished with the element you must call ap_cache_el_finalize immediatly so the 
  + * element is no longer locked.
  + * @param  The cache to create this element in.
  + * @param  The name to give this new record
  + * @param  Where to put this new element. 
  + * @deffunc ap_status_t ap_cache_create(ap_cache_handle_t *h, const char *name, ap_cache_el **);
  + */
  +ap_status_t ap_cache_create(ap_cache_handle_t *h, const char *name, ap_cache_el **);
  +
  +/**
  + * Remove a record from a cache. This call will fail if the requested element
  + * is already "in use" by previous call to ap_cache_seek or ap_cache_create.
  + * When finished with the element you must call ap_cache_el_finalize immediatly so the 
  + * element is no longer locked.
  + * @param  The cache to remove this record from.
  + * @param  The name of the record to remove from the cache.
  + * @deffunc ap_status_t ap_cache_remove(ap_cache_handle_t *h, const char *name);
  + */
  +ap_status_t ap_cache_remove(ap_cache_handle_t *h, const char *name);
  +
  +/* (C) Works on an actual element */
  +
  +/* (D) Works on the header section */
  +/**
  + * This will retrieve a header value from the element.
  + * @param  A previously ap-cache_seek()'d or ap_cache_create()'d element.
  + * @param  Header name looking to retrieve, must be null terminated.
  + * @param  Where to put the value
  + * @deffunc ap_status_t ap_cache_el_header(ap_cache_el *el, const char *hdr, char **val);
  + */
  +ap_status_t ap_cache_el_header(ap_cache_el *el, const char *hdr, char **val);
  +
  +/**
  + * Walk through all the headers for given values. This function is synonymous with 
  + * ap_table_walk.
  + * @param  The element to walk through.
  + * @param  The callback function to use for each element. The paramaters for this function:
  + *         1) Client defined data, as passed in by the next paramater to ap-cache_el_header_walk
  + *         2) The name of current header that forced this callback.
  + *         3) The value of the current header.
  + * @param  User defined data passed back to the callback as argument 1.
  + * @param  NULL terminated list of headers to walk through. If the first value 
  + *         of this list is NULL then ALL element will be walked over.
  + * @deffunc ap_status_t ap_cache_el_header_walk(ap_cache_el *el, 
  + *                                 int (*comp)(void *, const char *, const char *), void *rec, ...);
  + */
  +ap_status_t ap_cache_el_header_walk(ap_cache_el *el, 
  +                                    int (*comp)(void *, const char *, const char *), void *rec, ...);
  +
  +/**
  + * This will merge an existing ap_table_t into a cache_el's header section.
  + * @param  The cache element to merge onto.
  + * @param  The filled in ap_table_t to merge in.
  + * @deffunc ap_status_t ap_cache_el_header_merge(ap_cache_el *el, ap_table_t *tbl);
  + */
  +ap_status_t ap_cache_el_header_merge(ap_cache_el *el, ap_table_t *tbl);
  +
  +/**
  + * This will set the current value of a header name to a given value. Using this function
  + * the same as first ap_cache_el_header_remove, and then ap-cache_el_header_add.
  + * @param  The cache element to modify
  + * @param  The name of the header to change
  + * @param  The value to assign to the given name.
  + * @deffunc ap_status_t ap_cache_el_header_set(ap_cache_el *el, const char *hdrname, const char *hdrval);
  + */
  +ap_status_t ap_cache_el_header_set(ap_cache_el *el, const char *hdrname, const char *hdrval);
  +
  +/**
  + * Each header may have more than one value, you may call this function repeatedly and it will
  + * continue adding values onto a header element. If you want to assign a single value to a
  + * header you must use ap_cache_el_header_set instead.
  + * @param  The cache element to add to
  + * @param  The name of the header to append values to.
  + * @param  The value to append to the given header name.
  + * @deffunc ap_status_t ap_cache_el_header_add(ap_cache_el *el, const char *hdrname, const char *hdrval);
  + */
  +ap_status_t ap_cache_el_header_add(ap_cache_el *el, const char *hdrname, const char *hdrval);
  +
  +/**
  + * This will remove all headers of a given name.
  + * @param  The cache element to remove headers from
  + * @param  The name of the header to remove. This will remove ALL values assigned to this
  + *         header (via the ap_cache_el_header_add call).
  + * @deffunc ap_status_t ap_cache_el_header_remove(ap_cache_el *el, const char *hdr);
  + */
  +ap_status_t ap_cache_el_header_remove(ap_cache_el *el, const char *hdr);
  +
  +/**
  + * This will clear out an entire header section. You may use this if you are intending
  + * to change the entire value of the header section of a cache element.
  + * @param  The element to clear 
  + * @deffunc ap_status_t ap_cache_el_header_clear(ap_cache_el *el);
  + */
  +ap_status_t ap_cache_el_header_clear(ap_cache_el *el);
  +
  +/* (E) Works on the data section */
  +/**
  + * Retrieve a BUFF for a given cache element, where this data goes is opaque to all
  + * clients of this API. You can do all operations on the BUFF and trust the underlying
  + * caching module will accept the data and put it in the appropriate place.
  + * @param  The element to retrieve data
  + * @param  Where to put the BUFF structure when it comes back. In some cases this
  + *         will be a normal buff that will either write to a network, or disk - but
  + *         you should not rely on it going anywhere in a caching module as the destination
  + *         for all data is opaque.
  + * @deffunc ap_status_t ap_cache_el_data(ap_cache_el *el, BUFF **);
  + */
  +ap_status_t ap_cache_el_data(ap_cache_el *el, BUFF **);
  +
  +/**
  + * Convenience function to put an existing BUFF into a cache_el's data section. This
  + * function will probably not be fully optimal - and will actually just pipe one BUFF
  + * to another.
  + * @param  The element to append to
  + * @param  An existing BUFF to append onto the ap_cache_el's stream of data.
  + * @deffunc ap_status_t ap_cache_el_data_append(ap_cache_el *el, BUFF *data);
  + */
  +ap_status_t ap_cache_el_data_append(ap_cache_el *el, BUFF *data);
  +
  +/**
  + * Clear the data section of an existing cache_el. You may use this if you are 
  + * intending to change the entire value of the data section of a cache element.
  + * @param  The element to clear
  + * @deffunc ap_status_t ap_cache_el_data_clear(ap_cache_el *el);
  + */
  +ap_status_t ap_cache_el_data_clear(ap_cache_el *el);
  +
  +/**
  + * This will complete an open element. When you are done working on a caching
  + * element you must call this so the object will be unlocked and all data will
  + * be finalized, in some cases that means certain data won't make it into the
  + * destination backend until this call is made. Each module may decide how much
  + * this function actually does but you MUST call this function immediatly after
  + * completing a cache record.
  + * @param  The element to finalize, after calling this function the caching
  + *         element is no longer valid and you must ap_cache_seek for it again if
  + *         you want to make any further changes to it.
  + * @deffunc ap_status_t ap_cache_el_finalize(ap_cache_el *el);
  + */
  +ap_status_t ap_cache_el_finalize(ap_cache_el *el);
  +
  +/* ****************************************************************************/
  +/* ****************************************************************************/
  +/* This section is internal entirely, but it is exposed because
  + * implementors of caching modules will need to use some of this. Clients
  + * of the library are NEVER to use this interface however, and should use
  + * the above accessors to the cache.
  + */ 
  +
  +/* This is how a cache module can grab control. This will be fired once the 
  + * ap_cache_init call is made, each paramater will coorespond to the paramaters
  + * passed into ap_cache_init. If your cache wants to reject a hook call return 
  + * APR_ENOTIMPL from your hook and the next caching module will be tried.
  + */
  +AP_DECLARE_HOOK(ap_status_t, cache_init, (ap_cache_handle_t **, const char *desc, server_rec *t))
  +
  +/* These are various enum's passed into call back functions (as defined below) */
  +typedef enum { AP_CACHE_SEEK, AP_CACHE_CREATE, AP_CACHE_CHANGE, AP_CACHE_REMOVE } ap_cache_query;
  +typedef enum { AP_CACHE_DATA, AP_CACHE_HEADER } ap_cache_part;
  +
  +/* These are the callback functions filled in by handler of the cache_init hook. 
  + * function may be NULL and will in turn return APR_ENOTIMPL by any of the various 
  + * calls in the API.
  + */
  +typedef struct ap_cache_methods 
  +{
  +    ap_status_t (*cache_close)(ap_cache_handle_t *h);
  +    ap_status_t (*cache_garbage_coll)(ap_cache_handle_t *h);
  +    ap_status_t (*cache_element)(ap_cache_handle_t *h, const char *name, ap_cache_el **,
  +                                 ap_cache_query flag);
  +    ap_status_t (*cache_el_header_walk)(ap_cache_el *el, 
  +                                     int (*comp)(void *, const char *, const char *), void *rec, va_list);
  +    ap_status_t (*cache_el_hdr)(ap_cache_el *el, const char *name, const char *val, ap_cache_query flag);
  +    ap_status_t (*cache_el_data)(ap_cache_el *el, BUFF **);
  +    ap_status_t (*cache_el_reset)(ap_cache_el *, ap_cache_part flag);
  +    ap_status_t (*cache_el_final)(ap_cache_el *el);
  +} ap_cache_methods;
  +/* This is declared here because modules need to fill this in, however
  + *  clients of the library should NEVER use this 
  + */
  +struct ap_cache_handle_t
  +{
  +    ap_pool_t *pool;    /* pool for alloc's */
  +    server_rec *server; /* access to configurations, used on init */
  +    ap_cache_methods meth;
  +};
  +
  +#endif /* __AP_CACHE_H__ */