import { utf8DecodeJs } from "./utils/utf8";
interface KeyCacheRecord {
readonly bytes: Uint8Array;
readonly value: string;
}
const DEFAULT_MAX_KEY_LENGTH = 16;
const DEFAULT_MAX_LENGTH_PER_KEY = 16;
export class CachedKeyDecoder {
private readonly caches: Array;
constructor(readonly maxKeyLength = DEFAULT_MAX_KEY_LENGTH, readonly maxLengthPerKey = DEFAULT_MAX_LENGTH_PER_KEY) {
// avoid `new Array(N)` to create a non-sparse array for performance.
this.caches = [];
for (let i = 0; i < this.maxKeyLength; i++) {
this.caches.push([]);
}
}
public canBeCached(byteLength: number) {
return byteLength > 0 && byteLength = this.maxLengthPerKey) {
// `records` are full!
// Set `record` to a randomized position.
records[(Math.random() * records.length) | 0] = record;
} else {
records.push(record);
}
}
public decode(bytes: Uint8Array, inputOffset: number, byteLength: number): string {
const cachedValue = this.get(bytes, inputOffset, byteLength);
if (cachedValue) {
return cachedValue;
}
const value = utf8DecodeJs(bytes, inputOffset, byteLength);
// Ensure to copy a slice of bytes because the byte may be NodeJS Buffer and Buffer#slice() returns a reference to its internal ArrayBuffer.
const slicedCopyOfBytes = Uint8Array.prototype.slice.call(bytes, inputOffset, inputOffset + byteLength);
this.store(slicedCopyOfBytes, value);
return value;
}
}