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