ThemeCache.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. export function sameDerivativeOption(left, right) {
  2. if (left.length !== right.length) {
  3. return false;
  4. }
  5. for (let i = 0; i < left.length; i++) {
  6. if (left[i] !== right[i]) {
  7. return false;
  8. }
  9. }
  10. return true;
  11. }
  12. export default class ThemeCache {
  13. constructor() {
  14. this.cache = new Map();
  15. this.keys = [];
  16. this.cacheCallTimes = 0;
  17. }
  18. size() {
  19. return this.keys.length;
  20. }
  21. internalGet(derivativeOption) {
  22. let updateCallTimes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  23. let cache = {
  24. map: this.cache
  25. };
  26. derivativeOption.forEach(derivative => {
  27. var _a;
  28. if (!cache) {
  29. cache = undefined;
  30. } else {
  31. cache = (_a = cache === null || cache === void 0 ? void 0 : cache.map) === null || _a === void 0 ? void 0 : _a.get(derivative);
  32. }
  33. });
  34. if ((cache === null || cache === void 0 ? void 0 : cache.value) && updateCallTimes) {
  35. cache.value[1] = this.cacheCallTimes++;
  36. }
  37. return cache === null || cache === void 0 ? void 0 : cache.value;
  38. }
  39. get(derivativeOption) {
  40. var _a;
  41. return (_a = this.internalGet(derivativeOption, true)) === null || _a === void 0 ? void 0 : _a[0];
  42. }
  43. has(derivativeOption) {
  44. return !!this.internalGet(derivativeOption);
  45. }
  46. set(derivativeOption, value) {
  47. // New cache
  48. if (!this.has(derivativeOption)) {
  49. if (this.size() + 1 > ThemeCache.MAX_CACHE_SIZE + ThemeCache.MAX_CACHE_OFFSET) {
  50. const [targetKey] = this.keys.reduce((result, key) => {
  51. const [, callTimes] = result;
  52. if (this.internalGet(key)[1] < callTimes) {
  53. return [key, this.internalGet(key)[1]];
  54. }
  55. return result;
  56. }, [this.keys[0], this.cacheCallTimes]);
  57. this.delete(targetKey);
  58. }
  59. this.keys.push(derivativeOption);
  60. }
  61. let cache = this.cache;
  62. derivativeOption.forEach((derivative, index) => {
  63. if (index === derivativeOption.length - 1) {
  64. cache.set(derivative, {
  65. value: [value, this.cacheCallTimes++]
  66. });
  67. } else {
  68. const cacheValue = cache.get(derivative);
  69. if (!cacheValue) {
  70. cache.set(derivative, {
  71. map: new Map()
  72. });
  73. } else if (!cacheValue.map) {
  74. cacheValue.map = new Map();
  75. }
  76. cache = cache.get(derivative).map;
  77. }
  78. });
  79. }
  80. deleteByPath(currentCache, derivatives) {
  81. var _a;
  82. const cache = currentCache.get(derivatives[0]);
  83. if (derivatives.length === 1) {
  84. if (!cache.map) {
  85. currentCache.delete(derivatives[0]);
  86. } else {
  87. currentCache.set(derivatives[0], {
  88. map: cache.map
  89. });
  90. }
  91. return (_a = cache.value) === null || _a === void 0 ? void 0 : _a[0];
  92. }
  93. const result = this.deleteByPath(cache.map, derivatives.slice(1));
  94. if ((!cache.map || cache.map.size === 0) && !cache.value) {
  95. currentCache.delete(derivatives[0]);
  96. }
  97. return result;
  98. }
  99. delete(derivativeOption) {
  100. // If cache exists
  101. if (this.has(derivativeOption)) {
  102. this.keys = this.keys.filter(item => !sameDerivativeOption(item, derivativeOption));
  103. return this.deleteByPath(this.cache, derivativeOption);
  104. }
  105. return undefined;
  106. }
  107. }
  108. ThemeCache.MAX_CACHE_SIZE = 20;
  109. ThemeCache.MAX_CACHE_OFFSET = 5;