1 | import { ICache } from "./icache";
|
2 | import { emptyDirSync, ensureFileSync, readJsonSync, removeSync, writeJsonSync } from "fs-extra";
|
3 | import { existsSync, readdirSync, renameSync } from "fs";
|
4 | import * as _ from "lodash";
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | export class RollingCache<DataType> implements ICache<DataType>
|
11 | {
|
12 | private oldCacheRoot: string;
|
13 | private newCacheRoot: string;
|
14 |
|
15 | private rolled: boolean = false;
|
16 |
|
17 | |
18 |
|
19 |
|
20 |
|
21 | constructor(private cacheRoot: string, private checkNewCache: boolean)
|
22 | {
|
23 | this.oldCacheRoot = `${this.cacheRoot}/cache`;
|
24 | this.newCacheRoot = `${this.cacheRoot}/cache_`;
|
25 |
|
26 | emptyDirSync(this.newCacheRoot);
|
27 | }
|
28 |
|
29 | |
30 |
|
31 |
|
32 | public exists(name: string): boolean
|
33 | {
|
34 | if (this.rolled)
|
35 | return false;
|
36 |
|
37 | if (this.checkNewCache && existsSync(`${this.newCacheRoot}/${name}`))
|
38 | return true;
|
39 |
|
40 | return existsSync(`${this.oldCacheRoot}/${name}`);
|
41 | }
|
42 |
|
43 | public path(name: string): string
|
44 | {
|
45 | return `${this.oldCacheRoot}/${name}`;
|
46 | }
|
47 |
|
48 | |
49 |
|
50 |
|
51 | public match(names: string[]): boolean
|
52 | {
|
53 | if (this.rolled)
|
54 | return false;
|
55 |
|
56 | if (!existsSync(this.oldCacheRoot))
|
57 | return names.length === 0;
|
58 |
|
59 | return _.isEqual(readdirSync(this.oldCacheRoot).sort(), names.sort());
|
60 | }
|
61 |
|
62 | |
63 |
|
64 |
|
65 | public read(name: string): DataType | null | undefined
|
66 | {
|
67 | if (this.checkNewCache && existsSync(`${this.newCacheRoot}/${name}`))
|
68 | return readJsonSync(`${this.newCacheRoot}/${name}`, { encoding: "utf8", throws: false });
|
69 |
|
70 | return readJsonSync(`${this.oldCacheRoot}/${name}`, { encoding: "utf8", throws: false });
|
71 | }
|
72 |
|
73 | public write(name: string, data: DataType): void
|
74 | {
|
75 | if (this.rolled)
|
76 | return;
|
77 |
|
78 | if (data === undefined)
|
79 | return;
|
80 |
|
81 | writeJsonSync(`${this.newCacheRoot}/${name}`, data);
|
82 | }
|
83 |
|
84 | public touch(name: string)
|
85 | {
|
86 | if (this.rolled)
|
87 | return;
|
88 | ensureFileSync(`${this.newCacheRoot}/${name}`);
|
89 | }
|
90 |
|
91 | |
92 |
|
93 |
|
94 | public roll()
|
95 | {
|
96 | if (this.rolled)
|
97 | return;
|
98 |
|
99 | this.rolled = true;
|
100 | removeSync(this.oldCacheRoot);
|
101 | renameSync(this.newCacheRoot, this.oldCacheRoot);
|
102 | }
|
103 | }
|