cscg24-guacamole

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

lws-diskcache.h (8570B)


      1/*
      2 * libwebsockets - small server side websockets and web server implementation
      3 *
      4 * Copyright (C) 2010 - 2019 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 diskcache LWS disk cache
     26 * ## Disk cache API
     27 *
     28 * Lws provides helper apis useful if you need a disk cache containing hashed
     29 * files and need to delete files from it on an LRU basis to keep it below some
     30 * size limit.
     31 *
     32 * The API `lws_diskcache_prepare()` deals with creating the cache dir and
     33 * 256 subdirs, which are used according to the first two chars of the hex
     34 * hash of the cache file.
     35 *
     36 * `lws_diskcache_create()` and `lws_diskcache_destroy()` allocate and free
     37 * an opaque struct that represents the disk cache.
     38 *
     39 * `lws_diskcache_trim()` should be called at eg, 1s intervals to perform the
     40 * cache dir monitoring and LRU autodelete in the background lazily.  It can
     41 * be done in its own thread or on a timer... it monitors the directories in a
     42 * stateful way that stats one or more file in the cache per call, and keeps
     43 * a list of the oldest files as it goes.  When it completes a scan, if the
     44 * aggregate size is over the limit, it will delete oldest files first to try
     45 * to keep it under the limit.
     46 *
     47 * The cache size monitoring is extremely efficient in time and memory even when
     48 * the cache directory becomes huge.
     49 *
     50 * `lws_diskcache_query()` is used to determine if the file already exists in
     51 * the cache, or if it must be created.  If it must be created, then the file
     52 * is opened using a temp name that must be converted to a findable name with
     53 * `lws_diskcache_finalize_name()` when the generation of the file contents are
     54 * complete.  Aborted cached files that did not complete generation will be
     55 * flushed by the LRU eventually.  If the file already exists, it is 'touched'
     56 * to make it new again and the fd returned.
     57 *
     58 */
     59///@{
     60
     61struct lws_diskcache_scan;
     62
     63/**
     64 * lws_diskcache_create() - creates an opaque struct representing the disk cache
     65 *
     66 * \param cache_dir_base: The cache dir path, eg `/var/cache/mycache`
     67 * \param cache_size_limit: maximum size on disk the cache is allowed to use
     68 *
     69 * This returns an opaque `struct lws_diskcache_scan *` which represents the
     70 * disk cache, the trim scanning state and so on.  You should use
     71 * `lws_diskcache_destroy()` to free it to destroy it.
     72 */
     73LWS_VISIBLE LWS_EXTERN struct lws_diskcache_scan *
     74lws_diskcache_create(const char *cache_dir_base, uint64_t cache_size_limit);
     75
     76/**
     77 * lws_diskcache_destroy() - destroys the pointer returned by ...create()
     78 *
     79 * \param lds: pointer to the pointer returned by lws_diskcache_create()
     80 *
     81 * Frees *lds and any allocations it did, and then sets *lds to NULL and
     82 * returns.
     83 */
     84LWS_VISIBLE LWS_EXTERN void
     85lws_diskcache_destroy(struct lws_diskcache_scan **lds);
     86
     87/**
     88 * lws_diskcache_prepare() - ensures the cache dir structure exists on disk
     89 *
     90 * \param cache_base_dir: The cache dir path, eg `/var/cache/mycache`
     91 * \param mode: octal dir mode to enforce, like 0700
     92 * \param uid: uid the cache dir should belong to
     93 *
     94 * This should be called while your app is still privileged.  It will create
     95 * the cache directory structure on disk as necessary, enforce the given access
     96 * mode on it and set the given uid as the owner.  It won't make any trouble
     97 * if the cache already exists.
     98 *
     99 * Typically the mode is 0700 and the owner is the user that your application
    100 * will transition to use when it drops root privileges.
    101 */
    102LWS_VISIBLE LWS_EXTERN int
    103lws_diskcache_prepare(const char *cache_base_dir, int mode, uid_t uid);
    104
    105#define LWS_DISKCACHE_QUERY_NO_CACHE	0
    106#define LWS_DISKCACHE_QUERY_EXISTS	1
    107#define LWS_DISKCACHE_QUERY_CREATING	2
    108#define LWS_DISKCACHE_QUERY_ONGOING	3 /* something else is creating it */
    109
    110/**
    111 * lws_diskcache_query() - ensures the cache dir structure exists on disk
    112 *
    113 * \param lds: The opaque struct representing the disk cache
    114 * \param is_bot: nonzero means the request is from a bot.  Don't create new cache contents if so.
    115 * \param hash_hex: hex string representation of the cache object hash
    116 * \param _fd: pointer to the fd to be set
    117 * \param cache: destination string to take the cache filepath
    118 * \param cache_len: length of the buffer at `cache`
    119 * \param extant_cache_len: pointer to a size_t to take any extant cached file size
    120 *
    121 * This function is called when you want to find if the hashed name already
    122 * exists in the cache.  The possibilities for the return value are
    123 *
    124 *  - LWS_DISKCACHE_QUERY_NO_CACHE: It's not in the cache and you can't create
    125 *    it in the cache for whatever reason.
    126 *  - LWS_DISKCACHE_QUERY_EXISTS: It exists in the cache.  It's open RDONLY and
    127 *    *_fd has been set to the file descriptor.  *extant_cache_len has been set
    128 *    to the size of the cached file in bytes.  cache has been set to the
    129 *    full filepath of the cached file.  Closing _fd is your responsibility.
    130 *  - LWS_DISKCACHE_QUERY_CREATING: It didn't exist, but a temp file has been
    131 *    created in the cache and *_fd set to a file descriptor opened on it RDWR.
    132 *    You should create the contents, and call `lws_diskcache_finalize_name()`
    133 *    when it is done.  Closing _fd is your responsibility.
    134 *  - LWS_DISKCACHE_QUERY_ONGOING: not returned by this api, but you may find it
    135 *    desirable to make a wrapper function which can handle another asynchronous
    136 *    process that is already creating the cached file.  This can be used to
    137 *    indicate that situation externally... how to determine the same thing is
    138 *    already being generated is out of scope of this api.
    139 */
    140LWS_VISIBLE LWS_EXTERN int
    141lws_diskcache_query(struct lws_diskcache_scan *lds, int is_bot,
    142		    const char *hash_hex, int *_fd, char *cache, int cache_len,
    143		    size_t *extant_cache_len);
    144
    145/**
    146 * lws_diskcache_query() - ensures the cache dir structure exists on disk
    147 *
    148 * \param cache: The cache file temp name returned with LWS_DISKCACHE_QUERY_CREATING
    149 *
    150 * This renames the cache file you are creating to its final name.  It should
    151 * be called on the temp name returned by `lws_diskcache_query()` if it gave a
    152 * LWS_DISKCACHE_QUERY_CREATING return, after you have filled the cache file and
    153 * closed it.
    154 */
    155LWS_VISIBLE LWS_EXTERN int
    156lws_diskcache_finalize_name(char *cache);
    157
    158/**
    159 * lws_diskcache_trim() - performs one or more file checks in the cache for size management
    160 *
    161 * \param lds: The opaque object representing the cache
    162 *
    163 * This should be called periodically to statefully walk the cache on disk
    164 * collecting the oldest files.  When it has visited every file, if the cache
    165 * is oversize it will delete the oldest files until it's back under size again.
    166 *
    167 * Each time it's called, it will look at one or more dir in the cache.  If
    168 * called when the cache is oversize, it increases the amount of work done each
    169 * call until it is reduced again.  Typically it will take 256 calls before it
    170 * deletes anything, so if called once per second, it will delete files once
    171 * every 4 minutes.  Each call is very inexpensive both in memory and time.
    172 */
    173LWS_VISIBLE LWS_EXTERN int
    174lws_diskcache_trim(struct lws_diskcache_scan *lds);
    175
    176
    177/**
    178 * lws_diskcache_secs_to_idle() - see how long to idle before calling trim
    179 *
    180 * \param lds: The opaque object representing the cache
    181 *
    182 * If the cache is undersize, there's no need to monitor it immediately.  This
    183 * suggests how long to "sleep" before calling `lws_diskcache_trim()` again.
    184 */
    185LWS_VISIBLE LWS_EXTERN int
    186lws_diskcache_secs_to_idle(struct lws_diskcache_scan *lds);
    187///@}