From 7233f34e25735a7ab66d4d8271701f96e64dc5b0 Mon Sep 17 00:00:00 2001 From: Jon Mease Date: Sat, 28 Nov 2020 14:35:14 -0500 Subject: [PATCH] Cache base64 decoded ArrayBuffers and keep decoding in coerce / supplyDefaults --- src/lib/array.js | 2 +- src/lib/coerce.js | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/lib/array.js b/src/lib/array.js index 0eb0cd65289..bdd5bcf5f64 100644 --- a/src/lib/array.js +++ b/src/lib/array.js @@ -83,7 +83,7 @@ exports.typedArrays = typedArrays; exports.decodeTypedArraySpec = function(v) { // Assume processed by coerceTypedArraySpec - v = coerceTypedArraySpec(v) + v = coerceTypedArraySpec(v); var T = typedArrays[v.dtype]; var buffer; if(v.bvals.constructor === ArrayBuffer) { diff --git a/src/lib/coerce.js b/src/lib/coerce.js index b137e1cad30..c2d931f7b3a 100644 --- a/src/lib/coerce.js +++ b/src/lib/coerce.js @@ -21,6 +21,7 @@ var modHalf = require('./mod').modHalf; var isArrayOrTypedArray = require('./array').isArrayOrTypedArray; var isTypedArraySpec = require('./array').isTypedArraySpec; var decodeTypedArraySpec = require('./array').decodeTypedArraySpec; +var coerceTypedArraySpec = require('./array').coerceTypedArraySpec; exports.valObjectMeta = { @@ -42,7 +43,43 @@ exports.valObjectMeta = { propOut.set(v); wasSet = true; } else if(isTypedArraySpec(v)) { - propOut.set(decodeTypedArraySpec(v)); + // Copy and coerce spec + v = coerceTypedArraySpec(v); + + // See if caching location is available + var uid = propOut.obj.uid; + var module = propOut.obj._module; + + if(v.bvals.constructor === ArrayBuffer || !uid || !module) { + // Already an ArrayBuffer + // decoding is cheap + propOut.set(decodeTypedArraySpec(v)); + } else { + var prop = propOut.astr; + var cache = module._b64BufferCache || {}; + + // Check cache + var cachedBuffer = ((cache[uid] || {})[prop] || {})[v.bvals]; + if(cachedBuffer !== undefined) { + // Use cached array buffer instead of base64 encoded + // string + v.bvals = cachedBuffer; + propOut.set(decodeTypedArraySpec(v)); + } else { + // Not in so cache decode + var decoded = decodeTypedArraySpec(v); + propOut.set(decoded); + + // Update cache for next time + cache[uid] = (cache[uid] || {}); + + // Clear any prior cache value (only store one per + // trace property + cache[uid][prop] = {}; + cache[uid][prop][v.bvals] = decoded.buffer; + module._b64BufferCache = cache; + } + } wasSet = true; } if(!wasSet && dflt !== undefined) propOut.set(dflt);