UNPKG

@ixily/activ

Version:

Alpha Capture Trade Idea Verification. Blockchain ownership proven trade ideas and strategies.

148 lines (138 loc) 3.32 kB
interface SlotsCache { slots: number storage: Map<string, any> orderedIndex: string[] } interface ExpiringSlotsCache extends SlotsCache { expiration: number createdAtStorage: Map<string, number> } interface Slots { cache: SlotsCache setSlots: (slots: number) => void add: <T>(key: string, data: T) => void get: <T>(key: string) => T | undefined flushCache: () => void } interface ExpiringSlots extends Slots { cache: ExpiringSlotsCache setExpiration: (expiration: number) => void } const state = { slots: new Map<string, Slots>(), expiringSlots: new Map<string, ExpiringSlots>(), } const getSlots = (name: string, howMany: number = 20): Slots => { if (!state.slots.has(name)) { const cache: SlotsCache = { slots: howMany, storage: new Map<string, any>(), orderedIndex: [] as string[], } const flushCache = () => { if (cache.orderedIndex.length > cache.slots) { const toDelete = cache.orderedIndex.splice( 0, cache.orderedIndex.length - cache.slots, ) toDelete.forEach((key) => { cache.storage.delete(key) }) } } const setSlots = (slots: number) => { cache.slots = slots flushCache() } const add = <T>(key: string, data: T) => { cache.storage.set(key, data) cache.orderedIndex.push(key) flushCache() } const get = <T>(key: string): T | undefined => { return cache.storage.get(key) } const slots: Slots = { cache, setSlots, add, get, flushCache, } state.slots.set(name, slots) } return state.slots.get(name)! } const getExpiringSlots = ( name: string, howMany: number = 20, expiration: number = 10000, ): ExpiringSlots => { if (!state.expiringSlots.has(name)) { const cache: ExpiringSlotsCache = { slots: howMany, storage: new Map<string, any>(), createdAtStorage: new Map<string, number>(), orderedIndex: [] as string[], expiration, } const flushCache = () => { for (const key of cache.orderedIndex) { const exp = cache.createdAtStorage.get(key)! if (Date.now() - exp > cache.expiration) { cache.storage.delete(key) cache.createdAtStorage.delete(key) } } if (cache.orderedIndex.length > cache.slots) { const toDelete = cache.orderedIndex.splice( 0, cache.orderedIndex.length - cache.slots, ) toDelete.forEach((key) => { cache.storage.delete(key) }) } } const setSlots = (slots: number) => { cache.slots = slots flushCache() } const add = <T>(key: string, data: T) => { cache.storage.set(key, data) cache.orderedIndex.push(key) cache.createdAtStorage.set(key, Date.now()) flushCache() } const get = <T>(key: string): T | undefined => { const dt = cache.storage.get(key) if (dt === undefined) { return undefined } const exp = cache.createdAtStorage.get(key)! if (Date.now() - exp > cache.expiration) { cache.storage.delete(key) cache.createdAtStorage.delete(key) return undefined } return dt } const setExpiration = (expiration: number) => { cache.expiration = expiration } const slots: ExpiringSlots = { cache, setSlots, add, get, flushCache, setExpiration, } state.expiringSlots.set(name, slots) } return state.expiringSlots.get(name)! } export const PreCacheModule = { getSlots, getExpiringSlots, }