UNPKG

@bitbybit-dev/manifold-worker

Version:

Bit By Bit Developers Manifold Based CAD Library to Program Geometry Via WebWorker

138 lines (137 loc) 5.18 kB
export class CacheHelper { constructor() { this.hashesFromPreviousRun = {}; this.usedHashes = {}; this.argCache = {}; } cleanAllCache() { const usedHashKeys = Object.keys(this.usedHashes); usedHashKeys.forEach(hash => { if (this.argCache[hash]) { try { const manifold = this.argCache[hash]; manifold.delete(); } // eslint-disable-next-line no-empty catch (_a) { } } }); this.argCache = {}; this.usedHashes = {}; this.hashesFromPreviousRun = {}; } cleanCacheForHash(hash) { if (this.argCache[hash]) { try { const manifold = this.argCache[hash]; manifold.delete(); } // eslint-disable-next-line no-empty catch (_a) { } } delete this.argCache[hash]; delete this.usedHashes[hash]; delete this.hashesFromPreviousRun[hash]; } isManifoldObject(obj) { return obj !== undefined && obj !== null && (!Array.isArray(obj) && obj.$$ !== undefined) || (Array.isArray(obj) && obj.length > 0 && obj[0].$$ !== undefined); } cacheOp(args, cacheMiss) { let toReturn = null; const curHash = this.computeHash(args); this.usedHashes[curHash] = curHash; this.hashesFromPreviousRun[curHash] = curHash; const check = this.checkCache(curHash); if (check) { if (this.isManifoldObject(check)) { toReturn = check; toReturn.hash = check.hash; } else if (check.value) { toReturn = check.value; } } else { toReturn = cacheMiss(); if (Array.isArray(toReturn) && this.isManifoldObject(toReturn)) { toReturn.forEach((r, index) => { const itemHash = this.computeHash(Object.assign(Object.assign({}, args), { index })); r.hash = itemHash; this.addToCache(itemHash, r); }); } else { if (this.isManifoldObject(toReturn)) { this.addToCache(curHash, toReturn); } else if (toReturn.compound && toReturn.data && toReturn.manifolds && toReturn.manifolds.length > 0) { const objDef = toReturn; const compoundHash = this.computeHash(Object.assign(Object.assign({}, args), { index: "compound" })); objDef.compound.hash = compoundHash; this.addToCache(compoundHash, objDef.compound); objDef.manifolds.forEach((s, index) => { const itemHash = this.computeHash(Object.assign(Object.assign({}, args), { index })); s.manifold.hash = itemHash; this.addToCache(itemHash, s.manifold); }); this.addToCache(curHash, { value: objDef }); } else { this.addToCache(curHash, { value: toReturn }); } } } return toReturn; } /** Returns the cached object if it exists, or null otherwise. */ checkCache(hash) { return this.argCache[hash] || null; } /** Adds this `manifold` to the cache, indexable by `hash`. */ addToCache(hash, object) { const cacheShape = object; cacheShape.hash = hash; this.argCache[hash] = cacheShape; return hash; } /** This function computes a 32-bit integer hash given a set of `arguments`. * If `raw` is true, the raw set of sanitized arguments will be returned instead. */ computeHash(args, raw) { let argsString = JSON.stringify(args); argsString = argsString.replace(/(\"ptr\"\:(-?[0-9]*?)\,)/g, ""); argsString = argsString.replace(/(\"ptr\"\:(-?[0-9]*))/g, ""); if (argsString.includes("ptr")) { console.error("YOU DONE MESSED UP YOUR REGEX."); } const hashString = Math.random.toString() + argsString; if (raw) { return hashString; } return this.stringToHash(hashString); } /** This function converts a string to a 32bit integer. */ stringToHash(str) { let hash = 0; if (str.length === 0) { return hash; } for (let i = 0; i < str.length; i++) { const char = str.charCodeAt(i); // tslint:disable-next-line: no-bitwise hash = ((hash << 5) - hash) + char; // tslint:disable-next-line: no-bitwise hash = hash & hash; } return hash; } /** This function returns a version of the `inputArray` without the `objectToRemove`. */ remove(inputArray, objectToRemove) { return inputArray.filter((el) => { return el.hash !== objectToRemove.hash || el.ptr !== objectToRemove.ptr; }); } }