Cache overview
This module implements a cache with a fixed capacity and time-to-live. The contents of the cache is populated by a lookup function which may be recursive. The cache capacity may temporarily be exceeded if the lookup function is recursive (because the cache is also used to determine circularity). Keys are compared using Equal.equals.
Table of contents
Constructors
make
Creates a new cache. The lookup function is used to populate the cache. If the capacity is undefined, the cache is unbounded. If the lifespan is undefined, the values never expire. Keys are compared using Equal.equals.
Signature
export declare const make: <A, B>({
lookUp,
capacity,
lifeSpan
}: {
readonly lookUp: LookUp<A, B>
readonly capacity?: number
readonly lifeSpan?: number
}) => Type<A, B>
Example
import { MCache, MTypes } from "@parischap/effect-lib"
import { Record, Tuple, pipe } from "effect"
export const nonRecursiveCache = MCache.make({
lookUp: ({ key }: { readonly key: number }) => Tuple.make(key * 2, true)
})
interface RecursiveStructure {
// eslint-disable-next-line functional/prefer-readonly-type
[key: string]: string | RecursiveStructure
}
export const recursiveCache = MCache.make<RecursiveStructure, string>({
lookUp: ({ key, memoized, isCircular }) =>
isCircular
? Tuple.make(`Circular`, false)
: Tuple.make(
pipe(
key,
Record.reduce("", (acc, value) => (MTypes.isString(value) ? acc + value : acc + memoized(value)))
),
true
),
capacity: 2
})
Destructors
get
Gets a value from the cache. If the value is not in the cache (value comparison is based on Equal.equals), the lookup function is called to populate the cache. If it is in the cache but is too old,the lookup function is called to refresh it.
Signature
export declare const get: <A>(a: A) => <B>(self: Type<A, B>) => B
Example
import { MCache } from "@parischap/effect-lib"
import { Tuple } from "effect"
const testCache = MCache.make({
lookUp: ({ key }: { readonly key: number }) => Tuple.make(key * 2, true)
})
assert.deepStrictEqual(MCache.get(3)(testCache), 6)
keysInStore
Returns an array of the keys whose value is currently stored in the cache
Signature
export declare const keysInStore: <A, B>(self: Type<A, B>) => Array<A>
toGetter
Returns a function that gets a value from the self
Signature
export declare const toGetter: <A, B>(self: Type<A, B>) => MTypes.OneArgFunction<A, B>
Guards
has
Type guard
Signature
export declare const has: (u: unknown) => u is Type<unknown, unknown>
Models
LookUp (type alias)
Type that represents the lookup function. In addition to the key, the lookup function receives a memoized version of itself if it needs to perform recursion. It also receives a flag indicating whether circularity was detected. In that case, the memoized version of the function is not passed as recursion should be stopped to avoid an infinite loop. The output of the function must contain the result of the lookup and a boolean indicating whether the result should be stored in the cache. Note that when isCircular is true, the result is not stored in the cache even if the result of the function indicates it should.
Signature
export type LookUp<A, B> = ({
key,
memoized,
isCircular
}:
| { readonly key: A; readonly memoized: undefined; readonly isCircular: true }
| { readonly key: A; readonly memoized: (a: A) => B; readonly isCircular: false }) => MTypes.Pair<B, boolean>
Type (interface)
Type that represents a Cache
Signature
export interface Type<in out A, in out B> extends Inspectable.Inspectable, Pipeable.Pipeable {
/**
* The key/value cache. A None value means the value is currently under calculation. A circular
* flag will be sent if the value needs to be retreived while it is being calculated.
*/
readonly store: MutableHashMap.MutableHashMap<A, Option.Option<ValueContainer.Type<B>>>
/**
* A queue used to track the order in which keys were inserted so as to remove the oldest keys
* first in case the cache has bounded capacity
*/
readonly keyOrder: MutableQueue.MutableQueue<A>
/** The lookup function used to populate the cache */
readonly lookUp: LookUp<A, B>
/** The capicity of the cache. If undefined, the cache is unbounded */
readonly capacity: number | undefined
/** The lifespan of the values in the cache. If undefined, the values never expire */
readonly lifeSpan: number | undefined
/** @internal */
readonly [_TypeId]: {
readonly _A: Types.Invariant<A>
readonly _B: Types.Invariant<B>
}
}
moduleTag
Module tag
Signature
export declare const moduleTag: "@parischap/effect-lib/Cache/"