Skip to content

Commit

Permalink
Support statistics for group caches (#307)
Browse files Browse the repository at this point in the history
  • Loading branch information
kibertoad committed Jan 7, 2024
1 parent eb6f0fa commit 7203a0b
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 3 deletions.
12 changes: 10 additions & 2 deletions lib/memory/InMemoryGroupCache.ts
Expand Up @@ -10,6 +10,7 @@ export interface InMemoryGroupCacheConfiguration extends CommonCacheConfiguratio
globalStatisticsRecord?: HitStatisticsRecord
cacheType?: CacheTypeId
groupCacheType?: CacheTypeId
groupTtlInMsecs?: number
maxGroups?: number
maxItemsPerGroup?: number
}
Expand All @@ -19,6 +20,7 @@ const DEFAULT_GROUP_CONFIGURATION = {
groupCacheType: 'lru-object',
maxGroups: 1000,
maxItemsPerGroup: 500,
groupTtlInMsecs: 0, // does not expire
} satisfies Omit<InMemoryGroupCacheConfiguration, 'ttlInMsecs'>

export class InMemoryGroupCache<T> implements SynchronousGroupCache<T> {
Expand All @@ -40,7 +42,13 @@ export class InMemoryGroupCache<T> implements SynchronousGroupCache<T> {
config.groupCacheType ?? DEFAULT_GROUP_CONFIGURATION.groupCacheType,
)

this.groups = new this.groupCacheConstructor(config.maxGroups ?? DEFAULT_GROUP_CONFIGURATION.maxGroups)
this.groups = new this.groupCacheConstructor(
config.maxGroups ?? DEFAULT_GROUP_CONFIGURATION.maxGroups,
config.groupTtlInMsecs ?? DEFAULT_GROUP_CONFIGURATION.groupTtlInMsecs,
config.cacheId ? `${config.cacheId} (groups)` : config.cacheId,
// @ts-ignore
config.globalStatisticsRecord,
)
this.maxItemsPerGroup = config.maxItemsPerGroup ?? DEFAULT_GROUP_CONFIGURATION.maxItemsPerGroup
this.ttlInMsecs = config.ttlInMsecs
this.ttlLeftBeforeRefreshInMsecs = config.ttlLeftBeforeRefreshInMsecs
Expand All @@ -57,7 +65,7 @@ export class InMemoryGroupCache<T> implements SynchronousGroupCache<T> {
const newGroupCache = new this.cacheConstructor(
this.maxItemsPerGroup,
this.ttlInMsecs,
this.cacheId,
this.cacheId ? `${this.cacheId} (group ${groupId})` : this.cacheId,
// @ts-ignore
this.globalStatisticsRecord,
)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -50,7 +50,7 @@
],
"homepage": "https://github.com/kibertoad/layered-loader",
"dependencies": {
"toad-cache": "^3.3.1"
"toad-cache": "^3.4.1"
},
"devDependencies": {
"@types/node": "^20.10.2",
Expand Down
55 changes: 55 additions & 0 deletions test/memory/InMemoryGroupCache.spec.ts
@@ -1,6 +1,8 @@
import type { InMemoryCacheConfiguration } from '../../lib/memory/InMemoryCache'
import { setTimeout } from 'timers/promises'
import { InMemoryGroupCache } from '../../lib/memory/InMemoryGroupCache'
import { describe } from 'vitest'
import { HitStatisticsRecord } from 'toad-cache'

const IN_MEMORY_CACHE_CONFIG = { ttlInMsecs: 999 } satisfies InMemoryCacheConfiguration

Expand All @@ -23,6 +25,59 @@ describe('InMemoryCache', () => {
})
})

describe('getFromGroup', () => {
beforeEach(() => {
vitest.useFakeTimers()
vitest.setSystemTime(new Date('2024-01-02'))
})

afterEach(() => {
vitest.useRealTimers()
})

it('Updates statistics if set', () => {
const statistics = new HitStatisticsRecord()
const cache = new InMemoryGroupCache({
cacheId: 'MyCache',
globalStatisticsRecord: statistics,
cacheType: 'lru-object-statistics',
groupCacheType: 'lru-object-statistics',
maxGroups: 2,
ttlInMsecs: 1,
})
cache.setForGroup('key', 'value', 'group')
cache.setForGroup('key', 'value', 'group2')

cache.getFromGroup('key', 'group')
cache.setForGroup('key', 'value2', 'group')
cache.getFromGroup('key', 'group')

expect(statistics.records).toEqual({
'MyCache (group group)': {
'2024-01-02': {
expirations: 0,
hits: 2,
misses: 0,
},
},
'MyCache (group group2)': {
'2024-01-02': {
expirations: 0,
hits: 0,
misses: 0,
},
},
'MyCache (groups)': {
'2024-01-02': {
expirations: 0,
hits: 3,
misses: 2,
},
},
})
})
})

describe('getManyFromGroup', () => {
it('returns unresolved keys', () => {
const cache = new InMemoryGroupCache({
Expand Down

0 comments on commit 7203a0b

Please sign in to comment.