1*1c60b9acSAndroid Build Coastguard Worker# lws_cache: Flexible single and multilevel caching 2*1c60b9acSAndroid Build Coastguard Worker 3*1c60b9acSAndroid Build Coastguard Workerlws_cache implements a single- or multi-level cache for generic payload items 4*1c60b9acSAndroid Build Coastguard Workerthat are **keyed by a unique string**. 5*1c60b9acSAndroid Build Coastguard Worker 6*1c60b9acSAndroid Build Coastguard Worker 7*1c60b9acSAndroid Build Coastguard Worker 8*1c60b9acSAndroid Build Coastguard WorkerL1 cache is always stored on heap, but it may be hooked up to additional levels 9*1c60b9acSAndroid Build Coastguard Workerof cache objects with different backing storage. The last level always contains 10*1c60b9acSAndroid Build Coastguard Workera complete set of cached items, earlier levels may be empty or contain a partial 11*1c60b9acSAndroid Build Coastguard Workerset of objects. 12*1c60b9acSAndroid Build Coastguard Worker 13*1c60b9acSAndroid Build Coastguard WorkerUser code can define its own subclassed lws_cache objects with custom storage 14*1c60b9acSAndroid Build Coastguard Workerformats and media, while being able to take advantage of a suitably-sized L1 15*1c60b9acSAndroid Build Coastguard Workerheap cache to minimize the cost of repeated access. 16*1c60b9acSAndroid Build Coastguard Worker 17*1c60b9acSAndroid Build Coastguard Worker 18*1c60b9acSAndroid Build Coastguard Worker 19*1c60b9acSAndroid Build Coastguard WorkerYou can find examples of how to create, use and destroy single and multilevel 20*1c60b9acSAndroid Build Coastguard Workercaches in `minimal-examples/api-tests/api-test-lws_cache` 21*1c60b9acSAndroid Build Coastguard Worker 22*1c60b9acSAndroid Build Coastguard Worker## Cache size restriction, LRU and TTL 23*1c60b9acSAndroid Build Coastguard Worker 24*1c60b9acSAndroid Build Coastguard WorkerThe max heap footprint of its items and max number of items can be capped. LRU 25*1c60b9acSAndroid Build Coastguard Workertracking is performed so the least recently relevant items are evicted first. 26*1c60b9acSAndroid Build Coastguard WorkerIt's also possible to limit the maximum size of any single payload. 27*1c60b9acSAndroid Build Coastguard Worker 28*1c60b9acSAndroid Build Coastguard WorkerTime To Live (TTL) tracking is also performed automatically, so cached items 29*1c60b9acSAndroid Build Coastguard Workerauto-expire if a non-zero TTL is provided when the object is created. A user 30*1c60b9acSAndroid Build Coastguard Workercallback can be defined to get called when an item is about to be removed from 31*1c60b9acSAndroid Build Coastguard Workera particular cache level, in case any housekeeping needed. 32*1c60b9acSAndroid Build Coastguard Worker 33*1c60b9acSAndroid Build Coastguard Worker## Atomicity 34*1c60b9acSAndroid Build Coastguard Worker 35*1c60b9acSAndroid Build Coastguard WorkerItems in L1 can be accessed in heap casually and reliably if the following is 36*1c60b9acSAndroid Build Coastguard Workerborne in mind: 37*1c60b9acSAndroid Build Coastguard Worker 38*1c60b9acSAndroid Build Coastguard Worker - Any return to the event loop may perform removal of cache items due to TTL 39*1c60b9acSAndroid Build Coastguard Workerexpiry 40*1c60b9acSAndroid Build Coastguard Worker 41*1c60b9acSAndroid Build Coastguard Worker - Any operation that writes new items may evict items from non-last 42*1c60b9acSAndroid Build Coastguard Workercache levels which have limits to the footprint or item count to make room for 43*1c60b9acSAndroid Build Coastguard Workerit, using LRU ordering. 44*1c60b9acSAndroid Build Coastguard Worker 45*1c60b9acSAndroid Build Coastguard WorkerIn short process cache results before returning to the event loop or writing 46*1c60b9acSAndroid Build Coastguard Workeror removing items in the cache. 47*1c60b9acSAndroid Build Coastguard Worker 48*1c60b9acSAndroid Build Coastguard Worker## Cache creation 49*1c60b9acSAndroid Build Coastguard Worker 50*1c60b9acSAndroid Build Coastguard WorkerCaches are created using an info struct `struct lws_cache_creation_info` 51*1c60b9acSAndroid Build Coastguard Workerthat should be zeroed down. Most members are optional and can be left at zero, 52*1c60b9acSAndroid Build Coastguard Workera pointer to the lws_context and a short cache name are mandatory. 53*1c60b9acSAndroid Build Coastguard Worker 54*1c60b9acSAndroid Build Coastguard Worker``` 55*1c60b9acSAndroid Build Coastguard Workerstruct lws_cache_ttl_lru * 56*1c60b9acSAndroid Build Coastguard Workerlws_cache_create(const struct lws_cache_creation_info *info); 57*1c60b9acSAndroid Build Coastguard Worker``` 58*1c60b9acSAndroid Build Coastguard Worker 59*1c60b9acSAndroid Build Coastguard WorkerHow caches work is defined by an "ops struct" that the cache is bound to at 60*1c60b9acSAndroid Build Coastguard Workercreation time. `lws_cache_ops_heap` ops struct is provided by lws, you can 61*1c60b9acSAndroid Build Coastguard Workerdefine your own to implement your own specialized cache level. See 62*1c60b9acSAndroid Build Coastguard Worker`./include/libwebsockets/lws-cache-ttl.h` for the definition. 63*1c60b9acSAndroid Build Coastguard Worker 64*1c60b9acSAndroid Build Coastguard Worker## Cache destruction 65*1c60b9acSAndroid Build Coastguard Worker 66*1c60b9acSAndroid Build Coastguard WorkerCreated cache levels should be destroyed when you are finished with them. 67*1c60b9acSAndroid Build Coastguard Worker 68*1c60b9acSAndroid Build Coastguard Worker``` 69*1c60b9acSAndroid Build Coastguard Workervoid 70*1c60b9acSAndroid Build Coastguard Workerlws_cache_destroy(struct lws_cache_ttl_lru **cache); 71*1c60b9acSAndroid Build Coastguard Worker``` 72*1c60b9acSAndroid Build Coastguard Worker 73*1c60b9acSAndroid Build Coastguard WorkerFor L1, in heap, this frees any allocations. For other levels, eg, with file 74*1c60b9acSAndroid Build Coastguard Workerstorage for the items, this would close the file and leave any entries as they 75*1c60b9acSAndroid Build Coastguard Workerare. 76*1c60b9acSAndroid Build Coastguard Worker 77*1c60b9acSAndroid Build Coastguard Worker## Writethrough 78*1c60b9acSAndroid Build Coastguard Worker 79*1c60b9acSAndroid Build Coastguard Worker``` 80*1c60b9acSAndroid Build Coastguard Workerint 81*1c60b9acSAndroid Build Coastguard Workerlws_cache_write_through(struct lws_cache_ttl_lru *cache, 82*1c60b9acSAndroid Build Coastguard Worker const char *specific_key, const uint8_t *source, 83*1c60b9acSAndroid Build Coastguard Worker size_t size, lws_usec_t expiry, void **ppay); 84*1c60b9acSAndroid Build Coastguard Worker``` 85*1c60b9acSAndroid Build Coastguard Worker 86*1c60b9acSAndroid Build Coastguard WorkerThe combined caches are always accessed via the L1 cache, writing new items is 87*1c60b9acSAndroid Build Coastguard Workerdone at L1 and writes through to each cache layer immediately, so new items go 88*1c60b9acSAndroid Build Coastguard Workerinto the backing store without delay, but are available from heap for read. 89*1c60b9acSAndroid Build Coastguard Worker 90*1c60b9acSAndroid Build Coastguard WorkerIf existing keys are rewritten, the previous item of the same key is deleted 91*1c60b9acSAndroid Build Coastguard Workerfrom all levels of the cache before writing the new one. 92*1c60b9acSAndroid Build Coastguard Worker 93*1c60b9acSAndroid Build Coastguard Worker## Removal 94*1c60b9acSAndroid Build Coastguard Worker 95*1c60b9acSAndroid Build Coastguard WorkerRemoval also is performed at all cache levels at once. 96*1c60b9acSAndroid Build Coastguard Worker 97*1c60b9acSAndroid Build Coastguard Worker``` 98*1c60b9acSAndroid Build Coastguard Workerint 99*1c60b9acSAndroid Build Coastguard Workerlws_cache_item_remove(struct lws_cache_ttl_lru *cache, const char *wildcard_key); 100*1c60b9acSAndroid Build Coastguard Worker``` 101*1c60b9acSAndroid Build Coastguard Worker 102*1c60b9acSAndroid Build Coastguard Workerinternally earlier cache levels can evict cached items just at their level, but 103*1c60b9acSAndroid Build Coastguard Workerthis is triggered automatically and not by api. 104*1c60b9acSAndroid Build Coastguard Worker 105*1c60b9acSAndroid Build Coastguard WorkerA wildcard key is supported, removing all items matching, eg "myitem*". 106*1c60b9acSAndroid Build Coastguard Worker 107*1c60b9acSAndroid Build Coastguard Worker## Get by key 108*1c60b9acSAndroid Build Coastguard Worker 109*1c60b9acSAndroid Build Coastguard Worker``` 110*1c60b9acSAndroid Build Coastguard Workerint 111*1c60b9acSAndroid Build Coastguard Workerlws_cache_item_get(struct lws_cache_ttl_lru *cache, const char *specific_key, 112*1c60b9acSAndroid Build Coastguard Worker const void **pdata, size_t *psize); 113*1c60b9acSAndroid Build Coastguard Worker``` 114*1c60b9acSAndroid Build Coastguard Worker 115*1c60b9acSAndroid Build Coastguard WorkerApis are provided to get the blob related to a specific key, if it exists at 116*1c60b9acSAndroid Build Coastguard Workerany cache layer. Again this should use L1, it will bring a copy of the item 117*1c60b9acSAndroid Build Coastguard Workerinto L1 if one is not already there, so it can be accessed from heap. 118*1c60b9acSAndroid Build Coastguard Worker 119*1c60b9acSAndroid Build Coastguard Worker## Lookup with wildcards 120*1c60b9acSAndroid Build Coastguard Worker 121*1c60b9acSAndroid Build Coastguard Worker``` 122*1c60b9acSAndroid Build Coastguard Workerint 123*1c60b9acSAndroid Build Coastguard Workerlws_cache_lookup(struct lws_cache_ttl_lru *cache, const char *wildcard_key, 124*1c60b9acSAndroid Build Coastguard Worker const void **pdata, size_t *psize); 125*1c60b9acSAndroid Build Coastguard Worker``` 126*1c60b9acSAndroid Build Coastguard Worker 127*1c60b9acSAndroid Build Coastguard Workerlws_cache also supports **lookup** queries that contain wildcards or otherwise match 128*1c60b9acSAndroid Build Coastguard Workeron multiple keys according to cache-specific rules. These queries do not return 129*1c60b9acSAndroid Build Coastguard Workera single item, instead they return lists of keys that match, in a blob of its 130*1c60b9acSAndroid Build Coastguard Workerown that is also cached in L1. 131*1c60b9acSAndroid Build Coastguard Worker 132*1c60b9acSAndroid Build Coastguard WorkerThe user can walk the lookup results blob using a provided helper api 133*1c60b9acSAndroid Build Coastguard Worker 134*1c60b9acSAndroid Build Coastguard Worker``` 135*1c60b9acSAndroid Build Coastguard Workerint 136*1c60b9acSAndroid Build Coastguard Workerlws_cache_results_walk(lws_cache_results_t *walk_ctx); 137*1c60b9acSAndroid Build Coastguard Worker``` 138*1c60b9acSAndroid Build Coastguard Worker 139*1c60b9acSAndroid Build Coastguard WorkerAfter recovering each result key this way, the user code can use the _get api 140*1c60b9acSAndroid Build Coastguard Workerto access the blob for each indiviudally. 141*1c60b9acSAndroid Build Coastguard Worker 142*1c60b9acSAndroid Build Coastguard WorkerThe lookup results themselves are cached in L1, any new key that matches the 143*1c60b9acSAndroid Build Coastguard Workerwildcard lookup in any cached results, or any deletion of items with keys 144*1c60b9acSAndroid Build Coastguard Workermatching the cached wildcard lookup invalidate the affected cached lookup 145*1c60b9acSAndroid Build Coastguard Workerresults so they will be regenerated next time. 146*1c60b9acSAndroid Build Coastguard Worker 147*1c60b9acSAndroid Build Coastguard WorkerIn the typical case after a lookup, at least for a while the lookup results blob 148*1c60b9acSAndroid Build Coastguard Workerand all items mentioned in the lookup results will already be in L1 and cheaply 149*1c60b9acSAndroid Build Coastguard Workeraccessible. 150*1c60b9acSAndroid Build Coastguard Worker 151*1c60b9acSAndroid Build Coastguard Worker## Expunging 152*1c60b9acSAndroid Build Coastguard Worker 153*1c60b9acSAndroid Build Coastguard WorkerAn api is also provided to "expunge" or completely empty all cache levels and 154*1c60b9acSAndroid Build Coastguard Workercorresponding backing stores. 155*1c60b9acSAndroid Build Coastguard Worker 156*1c60b9acSAndroid Build Coastguard Worker``` 157*1c60b9acSAndroid Build Coastguard Workerint 158*1c60b9acSAndroid Build Coastguard Workerlws_cache_expunge(struct lws_cache_ttl_lru *cache); 159*1c60b9acSAndroid Build Coastguard Worker``` 160*1c60b9acSAndroid Build Coastguard Worker 161