00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef LUMIERA_CACHE_H
00023 #define LUMIERA_CACHE_H
00024
00025 #include "lib/llist.h"
00026
00027 #include <nobug.h>
00028
00044 typedef void* (*lumiera_cache_destructor_fn)(LList node);
00045
00046 struct lumiera_mrucache_struct
00047 {
00048 llist cache_list;
00049 size_t cached;
00050 lumiera_cache_destructor_fn destructor_cb;
00051 };
00052 typedef struct lumiera_mrucache_struct lumiera_mrucache;
00053 typedef lumiera_mrucache* LumieraMruCache;
00054
00061 LumieraMruCache
00062 lumiera_mrucache_init (LumieraMruCache self, lumiera_cache_destructor_fn destructor_cb);
00063
00070 LumieraMruCache
00071 lumiera_mrucache_destroy (LumieraMruCache self);
00072
00073
00082 static inline void
00083 lumiera_mrucache_checkin (LumieraMruCache self, LList node)
00084 {
00085 REQUIRE (self);
00086 REQUIRE (node && llist_is_empty (node));
00087 llist_insert_head (&self->cache_list, node);
00088 ++self->cached;
00089 }
00090
00091
00101 static inline void
00102 lumiera_mrucache_drop (LumieraMruCache self, LList node)
00103 {
00104 REQUIRE (self);
00105 REQUIRE (node);
00106
00107 if (llist_is_empty (node))
00108 {
00109
00110 ++self->cached;
00111 }
00112 else
00113 {
00114
00115 REQUIRE (llist_is_member (&self->cache_list, node), "node must be empty or member of cache");
00116 }
00117 llist_insert_tail (&self->cache_list, node);
00118
00119 if (self->destructor_cb)
00120 self->destructor_cb (node);
00121 }
00122
00123
00132 static inline void
00133 lumiera_mrucache_checkout (LumieraMruCache self, LList node)
00134 {
00135 REQUIRE (self);
00136
00137 REQUIRE (node && llist_is_member (&self->cache_list, node), "Node not in cache");
00138 llist_unlink (node);
00139 --self->cached;
00140 }
00141
00142
00150 static inline void*
00151 lumiera_mrucache_pop (LumieraMruCache self)
00152 {
00153 REQUIRE (self);
00154 if (llist_is_empty (&self->cache_list))
00155 return NULL;
00156
00157 LList node = llist_tail (&self->cache_list);
00158 llist_unlink (node);
00159 --self->cached;
00160
00161 if (self->destructor_cb)
00162 return self->destructor_cb (node);
00163 else
00164 return node;
00165 }
00166
00167
00175 int
00176 lumiera_mrucache_age (LumieraMruCache self, int nelem);
00177
00178
00179 #endif