1 #ifdef __cplusplus
2 extern "C" {
3 #endif
4 
5 	/*
6 	 * gdcache.h
7 	 *
8 	 * Caches of pointers to user structs in which the least-recently-used
9 	 * element is replaced in the event of a cache miss after the cache has
10 	 * reached a given size.
11 	 *
12 	 * John Ellson  (ellson@graphviz.org)  Oct 31, 1997
13 	 *
14 	 * Test this with:
15 	 *		 gcc -o gdcache -g -Wall -DTEST -DNEED_CACHE gdcache.c -lgd
16    *		 or
17 	 *		 gcc -o gdcache -g -Wall -DTEST -DNEED_CACHE gdcache.c libgd.a
18 	 *
19 	 * The cache is implemented by a singly-linked list of elements
20 	 * each containing a pointer to a user struct that is being managed by
21 	 * the cache.
22 	 *
23 	 * The head structure has a pointer to the most-recently-used
24 	 * element, and elements are moved to this position in the list each
25 	 * time they are used.  The head also contains pointers to three
26 	 * user defined functions:
27 	 *		- a function to test if a cached userdata matches some keydata
28 	 *		- a function to provide a new userdata struct to the cache
29 	 *          if there has been a cache miss.
30 	 *		- a function to release a userdata struct when it is
31 	 *          no longer being managed by the cache
32 	 *
33 	 * In the event of a cache miss the cache is allowed to grow up to
34 	 * a specified maximum size.  After the maximum size is reached then
35 	 * the least-recently-used element is discarded to make room for the
36 	 * new.  The most-recently-returned value is always left at the
37 	 * beginning of the list after retrieval.
38 	 *
39 	 * In the current implementation the cache is traversed by a linear
40 	 * search from most-recent to least-recent.  This linear search
41 	 * probably limits the usefulness of this implementation to cache
42 	 * sizes of a few tens of elements.
43 	 */
44 
45 	/*********************************************************/
46 	/* header                                                */
47 	/*********************************************************/
48 
49 #include <stdlib.h>
50 #ifndef NULL
51 #	define NULL (void *)0
52 #endif
53 
54 	/* user defined function templates */
55 	typedef int (*gdCacheTestFn_t)(void *userdata, void *keydata);
56 	typedef void *(*gdCacheFetchFn_t)(char **error, void *keydata);
57 	typedef void (*gdCacheReleaseFn_t)(void *userdata);
58 
59 	/* element structure */
60 	typedef struct gdCache_element_s gdCache_element_t;
61 	struct gdCache_element_s {
62 		gdCache_element_t *next;
63 		void *userdata;
64 	};
65 
66 	/* head structure */
67 	typedef struct gdCache_head_s gdCache_head_t;
68 	struct gdCache_head_s {
69 		gdCache_element_t *mru;
70 		int size;
71 		char *error;
72 		gdCacheTestFn_t gdCacheTest;
73 		gdCacheFetchFn_t gdCacheFetch;
74 		gdCacheReleaseFn_t gdCacheRelease;
75 	};
76 
77 	/* function templates */
78 	gdCache_head_t *gdCacheCreate(int size,
79 	                              gdCacheTestFn_t gdCacheTest,
80 	                              gdCacheFetchFn_t gdCacheFetch,
81 	                              gdCacheReleaseFn_t gdCacheRelease
82 	                             );
83 
84 	void gdCacheDelete(gdCache_head_t *head);
85 
86 	void *gdCacheGet(gdCache_head_t *head, void *keydata);
87 
88 #ifdef __cplusplus
89 }
90 #endif
91