UNPKG

@thermopylae/lib.cache

Version:
103 lines (102 loc) 4.63 kB
/// <reference types="node" /> import { MaybePromise, Undefinable } from '@thermopylae/core.declarations'; import { EventEmitter } from 'events'; import { Cache, CacheEvent, CacheEventListener } from '../contracts/cache'; import { CacheReplacementPolicy } from '../contracts/cache-replacement-policy'; import { CacheBackend } from '../contracts/cache-backend'; import { CacheEntry } from '../contracts/commons'; /** * @private */ declare const POLICIES_SYM: unique symbol; /** * @private */ interface CacheEntryEvictedBySpecialisedPolicies<Key, Value, PolicyTag> extends CacheEntry<Key, Value> { [POLICIES_SYM]: ReadonlyArray<PolicyTag>; } interface PolicyPerKeyCacheArgumentsBundle<PolicyTag> { /** * Array of policies used for a particular key. <br/> * If not given, key will be tracked by all of the available policies. */ policies?: ReadonlyArray<PolicyTag>; } /** * {@link Cache} implementation which uses {@link CacheReplacementPolicy} for keys eviction. <br/> * It can selectively use different policies for a particular key. * In order to do so, each policy is tagged for further identification. * When client inserts a new key, it can specify a list of policy tags which will track that key. * If it doesn't specify any tags, key will be tracked by all of the available policies. <br/> * Although any predefined policy can be used, there are some restrictions for multiple policies combination. <br/> * You can combine only 1 policy from each category in the {@link PolicyPerKeyCacheArgumentsBundle.policies}. * Also be careful, as when you omit {@link PolicyPerKeyCacheArgumentsBundle.policies}, cache will enforce all of the * registered policies for that key, therefore if you have registered multiple policies from same category, * this will result in **undefined behaviour**. * * Category | Policies * ---------------- | ----------------------------- * Expiration | - {@link ProactiveExpirationPolicy}<br/>- {@link ReactiveExpirationPolicy}<br/>- {@link SlidingProactiveExpirationPolicy}<br/>- {@link SlidingReactiveExpirationPolicy} * Eviction | - {@link ArcEvictionPolicy}<br/>- {@link LRUEvictionPolicy}<br/>- {@link SegmentedLRUEvictionPolicy}<br/>- {@link LFUEvictionPolicy}<br/>- {@link LFUDAEvictionPolicy}<br/>- {@link GDSFEvictionPolicy} * Priority | - {@link PriorityEvictionPolicy} * Dependencies | - {@link KeysDependenciesEvictionPolicy} * * For example, the following combination is a valid one: [{@link ProactiveExpirationPolicy}, {@link LRUEvictionPolicy}, {@link KeysDependenciesEvictionPolicy}].<br/> * While the following: [{@link ProactiveExpirationPolicy}, {@link SlidingProactiveExpirationPolicy}] isn't, because it contains 2 policies from same category. * * @template Key Type of the key. * @template Value Type of the value. * @template PolicyTag Type of the policy tag. * @template ArgumentsBundle Type of the arguments bundle. */ declare class PolicyPerKeyCache<Key, Value, PolicyTag = string, ArgumentsBundle extends PolicyPerKeyCacheArgumentsBundle<PolicyTag> = PolicyPerKeyCacheArgumentsBundle<PolicyTag>> extends EventEmitter implements Cache<Key, Value, ArgumentsBundle> { /** * @private */ private readonly backend; private readonly policies; private readonly allPoliciesTags; /** * @param backend Cache backend. * @param policies Tagged cache replacement policies. */ constructor(backend: CacheBackend<Key, Value>, policies: ReadonlyMap<PolicyTag, CacheReplacementPolicy<Key, Value, ArgumentsBundle>>); /** * @inheritDoc */ get size(): number; /** * @inheritDoc */ get(key: Key): Undefinable<Value>; /** * @inheritDoc */ set(key: Key, value: Value, argsBundle?: ArgumentsBundle): void; /** * Check whether **key** is present in the cache, without calling policies *onHit* hook. <br/> * Notice, that some policies might evict item when *onHit* hook is called (e.g. item expired), * therefore even if method returns **true**, trying to *get* item might evict him. * * @param key Name of the key. */ has(key: Key): boolean; /** * @inheritDoc */ del(key: Key): boolean; /** * @inheritDoc */ clear(): void; /** * @inheritDoc */ keys(): Array<Key>; /** * @inheritDoc */ on(event: CacheEvent, listener: CacheEventListener<Key, MaybePromise<Value, 'plain'>>): this; private internalDelete; } export { PolicyPerKeyCache, PolicyPerKeyCacheArgumentsBundle, CacheEntryEvictedBySpecialisedPolicies };