You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ch...@locus.apache.org on 2000/06/12 22:42:03 UTC
cvs commit: apache-2.0/src/include ap_cache.h
chuck 00/06/12 13:42:03
Added: src/include ap_cache.h
Log:
Header for the file cache functions
Submitted by: Sam Magnuson
Reviewed by: Chuck Murcko
Revision Changes Path
1.1 apache-2.0/src/include/ap_cache.h
Index: 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" /* 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__ */