1
Fork 0

partial rework/rewrite

This commit is contained in:
Conduitry 2020-10-25 13:17:17 -04:00
parent 2f0f871342
commit e4f730d622

View file

@ -4,50 +4,45 @@ import { resolve } from 'path';
import { serialize, deserialize } from 'v8';
type Mode = string | number | boolean | null | undefined;
type Cache = Map<string, [any, Set<Mode>]>;
export const autocache = (path: string, mode: Mode) => {
path = resolve(path);
let cache = <Cache>new Map();
const removing = new Set<string>();
const pending = new Map<string, any>();
let cache = new Map<Mode, Map<string, any>>();
const all_entries = new Map<string, any>();
const used_entries = new Map<string, any>();
const pending_entries = new Map<string, Promise<any>>();
try {
const data = deserialize(readFileSync(path));
if (data && typeof data === 'object' && data.schema === 1 && data.cache instanceof Map) {
if (data && typeof data === 'object' && data.schema === 2 && data.cache instanceof Map) {
cache = data.cache;
for (const [key, [, modes]] of cache) {
modes.delete(mode);
if (modes.size === 0) {
removing.add(key);
for (const values of cache.values()) {
for (const [key, value] of values) {
all_entries.set(key, value);
}
}
}
} catch {}
cache.set(mode, used_entries);
return {
async cache(key: string, compute_value: () => Promise<any>) {
const key_hashed = createHash('sha1').update(key).digest('hex');
let value: any, modes: Set<Mode>;
if (cache.has(key_hashed)) {
[value, modes] = cache.get(key_hashed);
} else if (pending.has(key_hashed)) {
return pending.get(key_hashed);
let value: any;
if (all_entries.has(key_hashed)) {
value = all_entries.get(key_hashed);
} else if (pending_entries.has(key_hashed)) {
return pending_entries.get(key_hashed);
} else {
const promise = compute_value();
pending.set(key_hashed, promise);
pending_entries.set(key_hashed, promise);
value = await promise;
modes = new Set();
cache.set(key_hashed, [value, modes]);
pending.delete(key_hashed);
pending_entries.delete(key_hashed);
all_entries.set(key_hashed, value);
}
removing.delete(key_hashed);
modes.add(mode);
used_entries.set(key_hashed, value);
return value;
},
close() {
for (const key of removing) {
cache.delete(key);
}
writeFileSync(path, serialize({ schema: 1, cache }));
writeFileSync(path, serialize({ schema: 2, cache }));
},
};
};