CachedUtf8Decoder.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.CachedUtf8Decoder = void 0;
  4. const tslib_1 = require("tslib");
  5. const v10_1 = tslib_1.__importDefault(require("./decodeUtf8/v10"));
  6. let x = 1 + Math.round(Math.random() * ((-1 >>> 0) - 1));
  7. /** Generate a random 32-bit unsigned integer in the specified [min, max] range. */
  8. function randomU32(min, max) {
  9. x ^= x << 13;
  10. x ^= x >>> 17;
  11. x ^= x << 5;
  12. return ((x >>> 0) % (max - min + 1)) + min;
  13. }
  14. class CacheItem {
  15. constructor(bytes, value) {
  16. this.bytes = bytes;
  17. this.value = value;
  18. }
  19. }
  20. class CachedUtf8Decoder {
  21. constructor() {
  22. this.caches = [];
  23. for (let i = 0; i < 31 /* CONST.MAX_CACHED_STR_LEN */; i++)
  24. this.caches.push([]);
  25. }
  26. get(bytes, offset, size) {
  27. const records = this.caches[size - 1];
  28. const len = records.length;
  29. FIND_CHUNK: for (let i = 0; i < len; i++) {
  30. const record = records[i];
  31. const recordBytes = record.bytes;
  32. for (let j = 0; j < size; j++)
  33. if (recordBytes[j] !== bytes[offset + j])
  34. continue FIND_CHUNK;
  35. return record.value;
  36. }
  37. return null;
  38. }
  39. store(bytes, value) {
  40. const records = this.caches[bytes.length - 1];
  41. const record = new CacheItem(bytes, value);
  42. const length = records.length;
  43. if (length >= 16 /* CONST.MAX_RECORDS_PER_SIZE */)
  44. records[randomU32(0, 16 /* CONST.MAX_RECORDS_PER_SIZE */ - 1)] = record;
  45. else
  46. records.push(record);
  47. }
  48. decode(bytes, offset, size) {
  49. if (!size)
  50. return '';
  51. const cachedValue = this.get(bytes, offset, size);
  52. if (cachedValue !== null)
  53. return cachedValue;
  54. const value = (0, v10_1.default)(bytes, offset, size);
  55. // Ensure to copy a slice of bytes because the byte may be NodeJS Buffer and Buffer#slice() returns a reference to its internal ArrayBuffer.
  56. const copy = Uint8Array.prototype.slice.call(bytes, offset, offset + size);
  57. this.store(copy, value);
  58. return value;
  59. }
  60. }
  61. exports.CachedUtf8Decoder = CachedUtf8Decoder;
  62. //# sourceMappingURL=CachedUtf8Decoder.js.map