cscg24-guacamole

CSCG 2024 Challenge 'Guacamole Mashup'
git clone https://git.sinitax.com/sinitax/cscg24-guacamole
Log | Files | Refs | sfeed.txt

lws-cache-ttl.h (13342B)


      1/*
      2 * libwebsockets - small server side websockets and web server implementation
      3 *
      4 * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
      5 *
      6 * Permission is hereby granted, free of charge, to any person obtaining a copy
      7 * of this software and associated documentation files (the "Software"), to
      8 * deal in the Software without restriction, including without limitation the
      9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     10 * sell copies of the Software, and to permit persons to whom the Software is
     11 * furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     22 * IN THE SOFTWARE.
     23 */
     24
     25/** \defgroup lws_cache_ttl Cache supporting expiry
     26 * ##Cache supporting expiry
     27 *
     28 * These apis let you quickly and reliably implement caches of named objects,
     29 * that have a "destroy-by date" and cache limits that will be observed.
     30 *
     31 * You can instantiate as many caches as you need.  The first one must be an
     32 * L1 / heap cache type, it can have parents and grandparents of other types
     33 * which are accessible why writing / looking up and getting from the L1 cache.
     34 * The outer "cache" layer may persistently store items to a backing store.
     35 *
     36 * Allocated object memory is entirely for the use of user code, up to the
     37 * requested size.
     38 *
     39 * The key name for the listed objects may be any string chosen by the user,
     40 * there is no special length limit as it is also allocated.
     41 *
     42 * Both expiry and LRU orderings are kept so it is easy to find out usage
     43 * ordering and when the next object that will expire.
     44 *
     45 * Cached objects may be destroyed any time you go around the event loop, when
     46 * you allocate new objects (to keep the whole cache under the specified limit),
     47 * or when their expiry time arrives.  So you shouldn't keep copies of pointers
     48 * to cached objects after returning to the event loop.
     49 */
     50///@{
     51
     52
     53struct lws_cache_ttl_lru;
     54
     55/**
     56 * lws_cache_write_through() - add a new cache item object in all layers
     57 *
     58 * \param cache: the existing cache to allocate the object in
     59 * \param specific_key: a key string that identifies the item in the cache
     60 * \param source: optional payload for the cached item, NULL means caller will
     61 *		  write the payload
     62 * \param size: the size of the object to allocate
     63 * \param expiry: the usec time that the object will autodestroy
     64 * \param ppay: NULL, or a pointer to a void * to be set to the L1 payload
     65 *
     66 * If an item with the key already exists, it is destroyed before allocating a
     67 * new one.
     68 *
     69 * Returns 0 if successful.  The written entry will be scheduled to be auto-
     70 * destroyed when \p expiry occurs.
     71 *
     72 * Adding or removing cache items may cause invalidation of cached queries.
     73 */
     74LWS_VISIBLE LWS_EXTERN int /* only valid until return to event loop */
     75lws_cache_write_through(struct lws_cache_ttl_lru *cache,
     76			const char *specific_key, const uint8_t *source,
     77			size_t size, lws_usec_t expiry, void **ppay);
     78
     79typedef struct lws_cache_match {
     80	lws_dll2_t			list;
     81	lws_usec_t			expiry;
     82	/* earliest expiry amongst results */
     83	size_t				payload_size;
     84	/**< the payload is not attached here.  This is a hint about what
     85	 * (*get)() will return for this tag name.
     86	 */
     87	size_t				tag_size;
     88
     89	/* tag name + NUL is overcommitted */
     90} lws_cache_match_t;
     91
     92/**
     93 * lws_cache_heap_lookup() - get a list of matching items
     94 *
     95 * \param cache: the cache to search for the key
     96 * \param wildcard_key: the item key string, may contain wildcards
     97 * \param pdata: pointer to pointer to be set to the serialized result list
     98 * \param psize: pointer to size_t to receive length of serialized result list
     99 *
    100 * This finds all unique items in the final cache that match search_key, which
    101 * may contain wildcards.  It does not return the payloads for matching items,
    102 * just a list of specific tags in the that match.
    103 *
    104 * If successful, results are provided in a serialized list format, in no
    105 * particular order, each result has the following fields
    106 *
    107 * - BE32: payload size in bytes (payload itself is not included)
    108 * - BE32: specific tag name length in bytes
    109 * - chars: tag name with terminating NUL
    110 *
    111 * These serialized results are themselves cached in L1 cache (only) and the
    112 * result pointers are set pointing into that.  If the results are still in L1
    113 * cache next time this api is called, the results will be returned directly
    114 * from that without repeating the expensive lookup on the backup store.  That
    115 * is why the results are provided in serialized form.
    116 *
    117 * The cached results list expiry is set to the earliest expiry of any listed
    118 * item.  Additionally any cached results are invalidated on addition or
    119 * deletion (update is done as addition + deletion) of any item that would
    120 * match the results' original wildcard_key.  For the typical case new items
    121 * are rare compared to lookups, this is efficient.
    122 *
    123 * Lookup matching does not itself affect LRU or cache status of the result
    124 * itsems.  Typically user code will get the lookup results, and then perform
    125 * get operations on each item in its desired order, that will bring the items
    126 * to the head of the LRU list and occupy L1 cache.
    127 *
    128 * Returns 0 if proceeded alright, or nonzero if error.  If there was an error,
    129 * any partial results set has been deallocated cleanly before returning.
    130 */
    131LWS_VISIBLE LWS_EXTERN int
    132lws_cache_lookup(struct lws_cache_ttl_lru *cache, const char *wildcard_key,
    133		 const void **pdata, size_t *psize);
    134
    135/**
    136 * lws_cache_item_get() - bring a specific item into L1 and get payload info
    137 *
    138 * \param cache: the cache to search for the key
    139 * \param specific_key: the key string of the item to get
    140 * \param pdata: pointer to a void * to be set to the payload in L1 cache
    141 * \param psize: pointer to a size_t to be set to the payload size
    142 *
    143 * If the cache still has an item matching the key string, it will be destroyed.
    144 *
    145 * Adding or removing cache items may cause invalidation of cached queries.
    146 *
    147 * Notice the cache payload is a blob of the given size.  If you are storing
    148 * strings, there is no NUL termination unless you stored them with it.
    149 *
    150 * Returns 0 if successful.
    151 */
    152LWS_VISIBLE LWS_EXTERN int
    153lws_cache_item_get(struct lws_cache_ttl_lru *cache, const char *specific_key,
    154		   const void **pdata, size_t *psize);
    155
    156/**
    157 * lws_cache_item_remove() - remove item from all cache levels
    158 *
    159 * \param cache: the cache to search for the key
    160 * \param wildcard_key: the item key string
    161 *
    162 * Removes any copy of any item matching the \p wildcard_key from any cache
    163 * level in one step.
    164 *
    165 * Adding or removing cache items may cause invalidation of cached queries
    166 * that could refer to the removed item.
    167 */
    168LWS_VISIBLE LWS_EXTERN int
    169lws_cache_item_remove(struct lws_cache_ttl_lru *cache, const char *wildcard_key);
    170
    171/**
    172 * lws_cache_footprint() - query the amount of storage used by the cache layer
    173 *
    174 * \param cache: cache to query
    175 *
    176 * Returns number of payload bytes stored in cache currently
    177 */
    178LWS_VISIBLE LWS_EXTERN uint64_t
    179lws_cache_footprint(struct lws_cache_ttl_lru *cache);
    180
    181/**
    182 * lws_cache_debug_dump() - if built in debug mode dump cache contents to log
    183 *
    184 * \param cache: cache to dump
    185 *
    186 * If lws was built in debug mode, dump cache to log, otherwise a NOP.
    187 */
    188LWS_VISIBLE LWS_EXTERN void
    189lws_cache_debug_dump(struct lws_cache_ttl_lru *cache);
    190
    191typedef struct lws_cache_results {
    192	const uint8_t		*ptr; /* set before using walk api */
    193	size_t			size; /* set before using walk api */
    194
    195	size_t			payload_len;
    196	size_t			tag_len;
    197	const uint8_t		*tag;
    198} lws_cache_results_t;
    199
    200/**
    201 * lws_cache_results_walk() - parse next result
    202 *
    203 * \param walk_ctx: the context of the results blob to walk
    204 *
    205 * Caller must initialize \p walk_ctx.ptr and \p walk_ctx.size before calling.
    206 * These are set to the results returned from a _lookup api call.
    207 *
    208 * The call returns 0 if the struct elements have been set to a result, or 1
    209 * if there where no more results in the blob to walk.
    210 *
    211 * If successful, after the call \p payload_len is set to the length of the
    212 * payload related to this result key (the payload itself is not present),
    213 * \p tag_len is set to the length of the result key name, and \p tag is set
    214 * to the result tag name, with a terminating NUL.
    215 */
    216LWS_VISIBLE LWS_EXTERN int
    217lws_cache_results_walk(lws_cache_results_t *walk_ctx);
    218
    219typedef void (*lws_cache_item_destroy_cb)(void *item, size_t size);
    220struct lws_cache_creation_info {
    221	struct lws_context		*cx;
    222	/**< Mandatory: the lws_context */
    223	const char			*name;
    224	/**< Mandatory: short cache name */
    225	lws_cache_item_destroy_cb	cb;
    226	/**< NULL, or a callback that can hook cache item destory */
    227	struct lws_cache_ttl_lru	*parent;
    228	/**< NULL, or next cache level */
    229	const struct lws_cache_ops	*ops;
    230	/**< NULL for default, heap-based ops, else custom cache storage and
    231	 * query implementation */
    232
    233	union {
    234		struct {
    235			const char 	*filepath;
    236			/**< the filepath to store items in */
    237		} nscookiejar;
    238	} u;
    239	/**< these are extra configuration for specific cache types */
    240
    241	size_t				max_footprint;
    242	/**< 0, or the max heap allocation allowed before destroying
    243	 *   lru items to keep it under the limit */
    244	size_t				max_items;
    245	/**< 0, or the max number of items allowed in the cache before
    246	 *   destroying lru items to keep it under the limit */
    247	size_t				max_payload;
    248	/**< 0, or the max allowed payload size for one item */
    249	int				tsi;
    250	/**< 0 unless using SMP, then tsi to bind sul to */
    251};
    252
    253struct lws_cache_ops {
    254	struct lws_cache_ttl_lru *
    255	(*create)(const struct lws_cache_creation_info *info);
    256	/**< create an instance of the cache type specified in info */
    257
    258	void
    259	(*destroy)(struct lws_cache_ttl_lru **_cache);
    260	/**< destroy the logical cache instance pointed to by *_cache, doesn't
    261	 * affect any NV backing storage */
    262
    263	int
    264	(*expunge)(struct lws_cache_ttl_lru *cache);
    265	/**< completely delete any backing storage related to the cache
    266	 * instance, eg, delete the backing file */
    267
    268	int
    269	(*write)(struct lws_cache_ttl_lru *cache, const char *specific_key,
    270		 const uint8_t *source, size_t size, lws_usec_t expiry,
    271		 void **ppvoid);
    272	/**< create an entry in the cache level according to the given info */
    273	int
    274	(*tag_match)(struct lws_cache_ttl_lru *cache, const char *wc,
    275		     const char *tag, char lookup_rules);
    276	/**< Just tell us if tag would match wildcard, using whatever special
    277	 * rules the backing store might use for tag matching.  0 indicates
    278	 * it is a match on wildcard, nonzero means does not match.
    279	 */
    280	int
    281	(*lookup)(struct lws_cache_ttl_lru *cache, const char *wildcard_key,
    282		      lws_dll2_owner_t *results_owner);
    283	/**+ add keys for search_key matches not already listed in the results
    284	 * owner */
    285	int
    286	(*invalidate)(struct lws_cache_ttl_lru *cache, const char *wildcard_key);
    287	/**< remove matching item(s) from cache level */
    288
    289	int
    290	(*get)(struct lws_cache_ttl_lru *cache, const char *specific_key,
    291	       const void **pdata, size_t *psize);
    292	/**< if it has the item, fills L1 with item. updates LRU, and returns
    293	 * pointer to payload in L1 */
    294
    295	void
    296	(*debug_dump)(struct lws_cache_ttl_lru *cache);
    297	/**< Helper to dump the whole cache contents to log, useful for debug */
    298};
    299
    300/**
    301 * lws_cache_create() - create an empty cache you can allocate items in
    302 *
    303 * \param info: a struct describing the cache to create
    304 *
    305 * Create an empty cache you can allocate items in.  The cache will be kept
    306 * below the max_footprint and max_items limits if they are nonzero, by
    307 * destroying least-recently-used items until it remains below the limits.
    308 *
    309 * Items will auto-destroy when their expiry time is reached.
    310 *
    311 * When items are destroyed from the cache, if \p cb is non-NULL, it will be
    312 * called back with the item pointer after it has been removed from the cache,
    313 * but before it is deallocated and destroyed.
    314 *
    315 * context and tsi are used when scheduling expiry callbacks
    316 */
    317LWS_VISIBLE LWS_EXTERN struct lws_cache_ttl_lru *
    318lws_cache_create(const struct lws_cache_creation_info *info);
    319
    320/**
    321 * lws_cache_destroy() - destroy a previously created cache
    322 *
    323 * \param cache: pointer to the cache
    324 *
    325 * Everything in the cache is destroyed, then the cache itself is destroyed,
    326 * and *cache set to NULL.
    327 */
    328LWS_VISIBLE LWS_EXTERN void
    329lws_cache_destroy(struct lws_cache_ttl_lru **cache);
    330
    331/**
    332 * lws_cache_expunge() - destroy all items in cache and parents
    333 *
    334 * \param cache: pointer to the cache
    335 *
    336 * Everything in the cache and parents is destroyed, leaving it empty.
    337 * If the cache has a backing store, it is deleted.
    338 *
    339 * Returns 0 if no problems reported at any cache layer, else nonzero.
    340 */
    341LWS_VISIBLE LWS_EXTERN int
    342lws_cache_expunge(struct lws_cache_ttl_lru *cache);
    343
    344LWS_VISIBLE extern const struct lws_cache_ops lws_cache_ops_heap,
    345					      lws_cache_ops_nscookiejar;
    346
    347///@}
    348