1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*--------------------------------------------------------------------------------------------*/
import { TextDocument } from 'vscode-css-languageservice'
export interface LanguageModelCache<T> {
get(document: TextDocument): T
onDocumentRemoved(document: TextDocument): void
dispose(): void
}
export function getLanguageModelCache<T>(
maxEntries: number,
cleanupIntervalTimeInSec: number,
parse: (document: TextDocument) => T
): LanguageModelCache<T> {
let languageModels: {
[uri: string]: { version: number; languageId: string; cTime: number; languageModel: T }
} = {}
let nModels = 0
let cleanupInterval: NodeJS.Timer | undefined = undefined
if (cleanupIntervalTimeInSec > 0) {
cleanupInterval = setInterval(() => {
let cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000
let uris = Object.keys(languageModels)
for (let uri of uris) {
let languageModelInfo = languageModels[uri]
if (languageModelInfo.cTime < cutoffTime) {
delete languageModels[uri]
nModels--
}
}
}, cleanupIntervalTimeInSec * 1000)
}
return {
get(document: TextDocument): T {
let version = document.version
let languageId = document.languageId
let languageModelInfo = languageModels[document.uri]
if (
languageModelInfo &&
languageModelInfo.version === version &&
languageModelInfo.languageId === languageId
) {
languageModelInfo.cTime = Date.now()
return languageModelInfo.languageModel
}
let languageModel = parse(document)
languageModels[document.uri] = { languageModel, version, languageId, cTime: Date.now() }
if (!languageModelInfo) {
nModels++
}
if (nModels === maxEntries) {
let oldestTime = Number.MAX_VALUE
let oldestUri = null
for (let uri in languageModels) {
let languageModelInfo = languageModels[uri]
if (languageModelInfo.cTime < oldestTime) {
oldestUri = uri
oldestTime = languageModelInfo.cTime
}
}
if (oldestUri) {
delete languageModels[oldestUri]
nModels--
}
}
return languageModel
},
onDocumentRemoved(document: TextDocument) {
let uri = document.uri
if (languageModels[uri]) {
delete languageModels[uri]
nModels--
}
},
dispose() {
if (typeof cleanupInterval !== 'undefined') {
clearInterval(cleanupInterval)
cleanupInterval = undefined
languageModels = {}
nModels = 0
}
},
}
}
|