@ixily/activ
Version:
Alpha Capture Trade Idea Verification. Blockchain ownership proven trade ideas and strategies.
148 lines (138 loc) • 3.32 kB
text/typescript
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,
}