109 lines
3.3 KiB
JavaScript
109 lines
3.3 KiB
JavaScript
export function sameDerivativeOption(left, right) {
|
|
if (left.length !== right.length) {
|
|
return false;
|
|
}
|
|
for (let i = 0; i < left.length; i++) {
|
|
if (left[i] !== right[i]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
export default class ThemeCache {
|
|
constructor() {
|
|
this.cache = new Map();
|
|
this.keys = [];
|
|
this.cacheCallTimes = 0;
|
|
}
|
|
size() {
|
|
return this.keys.length;
|
|
}
|
|
internalGet(derivativeOption) {
|
|
let updateCallTimes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
let cache = {
|
|
map: this.cache
|
|
};
|
|
derivativeOption.forEach(derivative => {
|
|
var _a;
|
|
if (!cache) {
|
|
cache = undefined;
|
|
} else {
|
|
cache = (_a = cache === null || cache === void 0 ? void 0 : cache.map) === null || _a === void 0 ? void 0 : _a.get(derivative);
|
|
}
|
|
});
|
|
if ((cache === null || cache === void 0 ? void 0 : cache.value) && updateCallTimes) {
|
|
cache.value[1] = this.cacheCallTimes++;
|
|
}
|
|
return cache === null || cache === void 0 ? void 0 : cache.value;
|
|
}
|
|
get(derivativeOption) {
|
|
var _a;
|
|
return (_a = this.internalGet(derivativeOption, true)) === null || _a === void 0 ? void 0 : _a[0];
|
|
}
|
|
has(derivativeOption) {
|
|
return !!this.internalGet(derivativeOption);
|
|
}
|
|
set(derivativeOption, value) {
|
|
// New cache
|
|
if (!this.has(derivativeOption)) {
|
|
if (this.size() + 1 > ThemeCache.MAX_CACHE_SIZE + ThemeCache.MAX_CACHE_OFFSET) {
|
|
const [targetKey] = this.keys.reduce((result, key) => {
|
|
const [, callTimes] = result;
|
|
if (this.internalGet(key)[1] < callTimes) {
|
|
return [key, this.internalGet(key)[1]];
|
|
}
|
|
return result;
|
|
}, [this.keys[0], this.cacheCallTimes]);
|
|
this.delete(targetKey);
|
|
}
|
|
this.keys.push(derivativeOption);
|
|
}
|
|
let cache = this.cache;
|
|
derivativeOption.forEach((derivative, index) => {
|
|
if (index === derivativeOption.length - 1) {
|
|
cache.set(derivative, {
|
|
value: [value, this.cacheCallTimes++]
|
|
});
|
|
} else {
|
|
const cacheValue = cache.get(derivative);
|
|
if (!cacheValue) {
|
|
cache.set(derivative, {
|
|
map: new Map()
|
|
});
|
|
} else if (!cacheValue.map) {
|
|
cacheValue.map = new Map();
|
|
}
|
|
cache = cache.get(derivative).map;
|
|
}
|
|
});
|
|
}
|
|
deleteByPath(currentCache, derivatives) {
|
|
var _a;
|
|
const cache = currentCache.get(derivatives[0]);
|
|
if (derivatives.length === 1) {
|
|
if (!cache.map) {
|
|
currentCache.delete(derivatives[0]);
|
|
} else {
|
|
currentCache.set(derivatives[0], {
|
|
map: cache.map
|
|
});
|
|
}
|
|
return (_a = cache.value) === null || _a === void 0 ? void 0 : _a[0];
|
|
}
|
|
const result = this.deleteByPath(cache.map, derivatives.slice(1));
|
|
if ((!cache.map || cache.map.size === 0) && !cache.value) {
|
|
currentCache.delete(derivatives[0]);
|
|
}
|
|
return result;
|
|
}
|
|
delete(derivativeOption) {
|
|
// If cache exists
|
|
if (this.has(derivativeOption)) {
|
|
this.keys = this.keys.filter(item => !sameDerivativeOption(item, derivativeOption));
|
|
return this.deleteByPath(this.cache, derivativeOption);
|
|
}
|
|
return undefined;
|
|
}
|
|
}
|
|
ThemeCache.MAX_CACHE_SIZE = 20;
|
|
ThemeCache.MAX_CACHE_OFFSET = 5; |