Cache.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.Cache = void 0;
  4. const tslib_1 = require("tslib");
  5. const noop = () => { };
  6. class Cache {
  7. constructor(method = noop) {
  8. this.method = method;
  9. this.ttl = 10000; // Time how long item is kept in cache without refreshing.
  10. this.evictionTime = 20000; // After this time item is evicted from cache.
  11. this.gcPeriod = 30000; // How often to run GC.
  12. this.maxEntries = 100000;
  13. this.entries = 0; // Number of values in cache.
  14. this.map = new Map();
  15. this.runGC = () => {
  16. const now = Date.now();
  17. for (const key of this.map.keys()) {
  18. const entry = this.map.get(key);
  19. if (entry && now - entry.t >= this.evictionTime) {
  20. this.map.delete(key);
  21. this.entries--;
  22. }
  23. }
  24. this.scheduleGC();
  25. };
  26. this.stopGC = () => {
  27. clearTimeout(this.timer);
  28. };
  29. }
  30. put(key, value) {
  31. const entry = {
  32. t: Date.now(),
  33. value,
  34. };
  35. if (this.map.get(key)) {
  36. this.map.set(key, entry);
  37. }
  38. else {
  39. this.map.set(key, entry);
  40. this.entries++;
  41. }
  42. if (this.entries > this.maxEntries) {
  43. for (const iterationKey of this.map.keys()) {
  44. if (key !== iterationKey) {
  45. this.map.delete(iterationKey);
  46. this.entries--;
  47. break;
  48. }
  49. }
  50. }
  51. }
  52. getFromSource(key) {
  53. return tslib_1.__awaiter(this, void 0, void 0, function* () {
  54. const value = yield this.method(key);
  55. this.put(key, value);
  56. return value;
  57. });
  58. }
  59. get(key) {
  60. return tslib_1.__awaiter(this, void 0, void 0, function* () {
  61. const entry = this.map.get(key);
  62. if (entry) {
  63. const now = Date.now();
  64. if (now - entry.t <= this.ttl) {
  65. return entry.value;
  66. }
  67. else if (now - entry.t <= this.evictionTime) {
  68. this.getFromSource(key).catch(noop);
  69. return entry.value;
  70. }
  71. else {
  72. this.map.delete(key);
  73. this.entries--;
  74. return yield this.getFromSource(key);
  75. }
  76. }
  77. else {
  78. return yield this.getFromSource(key);
  79. }
  80. });
  81. }
  82. getSync(key) {
  83. const entry = this.map.get(key);
  84. if (!entry)
  85. return null;
  86. const now = Date.now();
  87. if (now - entry.t <= this.ttl) {
  88. return entry.value;
  89. }
  90. else if (now - entry.t <= this.evictionTime) {
  91. this.getFromSource(key).catch(noop);
  92. return entry.value;
  93. }
  94. return null;
  95. }
  96. exists(key) {
  97. const entry = this.map.get(key);
  98. if (!entry)
  99. return false;
  100. const now = Date.now();
  101. return now - entry.t <= this.evictionTime;
  102. }
  103. scheduleGC() {
  104. this.timer = setTimeout(this.runGC, this.gcPeriod);
  105. this.timer.unref();
  106. }
  107. startGC() {
  108. this.scheduleGC();
  109. }
  110. retire(key, newTime = 0) {
  111. const entry = this.map.get(key);
  112. if (!entry)
  113. return false;
  114. entry.t = newTime;
  115. return true;
  116. }
  117. remove(key) {
  118. const success = this.map.delete(key);
  119. if (success)
  120. this.entries--;
  121. return success;
  122. }
  123. }
  124. exports.Cache = Cache;