cordis/client/webapp/resource-ram-cache.ts

37 lines
1.6 KiB
TypeScript

import Globals from './globals';
import { ShouldNeverHappenError } from './data-types';
export default class ResourceRAMCache {
static data = new Map<string, { resource: Buffer, lastUsed: Date }>(); // (serverId, resourceId) -> { resource, lastUsed }
static size = 0;
static putResource(serverId: string, resourceId: string, resourceBuff: Buffer): void {
if (resourceBuff.length > Globals.MAX_RESOURCE_SIZE) { // skip resources if they would flood the cache
return;
}
let id = `s#${serverId}/r#${resourceId}`;
ResourceRAMCache.data.set(id, { resource: resourceBuff, lastUsed: new Date() });
ResourceRAMCache.size += resourceBuff.length;
if (ResourceRAMCache.size > Globals.MAX_SERVER_RESOURCE_CACHE_SIZE) { // TODO: this feature needs to be tested
let entries = Array.from(ResourceRAMCache.data.entries())
.map(([ key, value ]) => { return { id: key, value: value }; })
.sort((a, b) => b.value.lastUsed.getTime() - a.value.lastUsed.getTime()); // oldest last (for pop)
while (ResourceRAMCache.size > Globals.MAX_SERVER_RESOURCE_CACHE_SIZE) {
let entry = entries.pop();
if (entry === undefined) throw new ShouldNeverHappenError('No entry in the array but the ram cache still has a size...');
ResourceRAMCache.data.delete(entry.id);
ResourceRAMCache.size -= entry.value.resource.length;
}
}
}
static getResource(serverId: string, resourceId: string): Buffer | null {
let id = `s#${serverId}/r#${resourceId}`;
let v = ResourceRAMCache.data.get(id);
if (!v) return null;
v.lastUsed = new Date();
return v.resource;
}
}