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__ */