@b08/cache
v2.0.0
Published
cache and memoize implementation
Downloads
45
Readme
@b08/cache, seeded from @b08/library-seed, library type: feature
This is implementation of cache, allowing to use flat object as a key.
Also, it has approximate 6 times performance improvement over "js-cache" npm package. To handle item expiration js-cache library fires a new timer for each item, which is expensive.
In this library there is only one timer at a time. Items are put in the timebox. When timer fires, it evicts all items accumulated in that slot from the cache. Timer is handled with throttling mechanism with configurable precision.
For example, with default precision, if there are 4 items put in the cache with timeouts of 200, 400, 600 and 800 milliseconds, then first 2 items will be evicted from the cache after 500ms, last 2 after 1 second.
CacheSettings
Each instrument in this library can be configured with following settings:\
- timeoutPrecision - time between expirations in milliseconds. Item that does not get into the time slot will be expired in the next one. Default value is 500.
- timeboxSize - number of time slots. If item expiration is later than timebox span, item expiration is put into the stack-tree, slower mechanism of handling expirations. Only about 2-2.5 times faster than "js-cache".
- DefaultTimeout. If timeout is not specified in set method, it falls back to this value. Default value is 500ms.
- DisableTickOptimization. There is an optimization implemented - current time is only taken once during the tick of JS event loop. All subsequent items placed into cache will calculate their timeout off the same time, even though current time may already change if tick was long.
CacheProvider
Cache provider is made with the similar interface as usual caching implementations.
var cache = new CacheProvider(settings);
const key = 1, value = 2;
cache.set(key, value, 100); // this sets item to the cache, and expires it after 100ms
cache.set(key, value); // this overwrites the item and sets it to expire after 500ms
const has = cache.has(1); // this method tells if there is value by that key in the cache
const result = cache.get(1); // this gets item from the cache by specified key
cache.delete(1); // force deletion of item from the cache.
Cache
This is pass-through cache implementation. So far only implemented with synchronous interface
const cache = new Cache(settings);
// this is an example of flat object that can be used as a key
const key = { a: "flat", b: "object", c: "key" };
const value = cache.getSync(key, (k) => calculateTheValueOffKey(k));
memoize
This an implementation of memoization pattern. It uses arguments as a cache key. So next time the function is called with the same parameters, value will be taken from cache, unless expired.
const calculateItems = memoize(function(arg1: string, arg2: number): number {
// heavy calculations go here
}, settings);
// to reset the cache
calculateItems.reset();
There are 2 restrictions:
- Can't have variable number of parameters, i.e. no optional or default parameters allowed.
- Object parameters should never be mutated by any other code, since reference comparison will be run against parameters.
memoized
This has the same functionality as memoize, but uses serialization of arguments instead of direct comparison.
So in case of large immutable objects used as function parameters the performance is significantly worse
Plans for future versions
- getAsync method for Cache: along with caching value, will cache the promise. So 2 consumers asking for the item will spawn only one promise
- getAsync. So far can just cache the promise itself, checked to be working. Will need to work with async cache provider, like redis.
- getArrayAsync method: provide a list of keys and a method to get a list of values by list of keys. Cache will get part of items from the cache and request only new items.
- Automatically renewable cache for frequently requested data.