diff --git a/src/js/lz4.js b/src/js/lz4.js index 7cd734f6e..728b0a4b3 100644 --- a/src/js/lz4.js +++ b/src/js/lz4.js @@ -69,7 +69,12 @@ let init = function() { // time elapse without the instance being used. let destroy = function() { - console.info('uBO: freeing lz4-block-codec instance'); + if ( lz4CodecInstance !== undefined ) { + console.info( + 'uBO: freeing lz4-block-codec instance (%s KB)', + lz4CodecInstance.bytesInUse() >>> 10 + ); + } lz4CodecInstance = undefined; textEncoder = textDecoder = undefined; ttlCount = 0; @@ -118,11 +123,12 @@ let encodeValue = function(key, value) { outputArray[6] = (inputSize >>> 16) & 0xFF; outputArray[7] = (inputSize >>> 24) & 0xFF; console.info( - 'uBO: [%s] compressed %d bytes into %d bytes in %s ms', + 'uBO: [%s] compressed %d KB => %d KB (%s%%) in %s ms', key, - inputArray.byteLength, - outputArray.byteLength, - (window.performance.now() - t0).toFixed(2) + inputArray.byteLength >> 10, + outputArray.byteLength >> 10, + (outputArray.byteLength / inputArray.byteLength * 100).toFixed(0), + (window.performance.now() - t0).toFixed(1) ); return outputArray; }; @@ -145,38 +151,39 @@ let decodeValue = function(key, inputArray) { } let value = textDecoder.decode(outputArray); console.info( - 'uBO: [%s] decompressed %d bytes into %d bytes in %s ms', + 'uBO: [%s] decompressed %d KB => %d KB (%s%%) in %s ms', key, - inputArray.byteLength, - outputSize, - (window.performance.now() - t0).toFixed(2) + inputArray.byteLength >>> 10, + outputSize >>> 10, + (inputArray.byteLength / outputSize * 100).toFixed(0), + (window.performance.now() - t0).toFixed(1) ); return value; }; return { - encode: function(key, data) { - if ( typeof data !== 'string' || data.length < 4096 ) { - return Promise.resolve({ key, data }); + encode: function(key, dataIn) { + if ( typeof dataIn !== 'string' || dataIn.length < 4096 ) { + return Promise.resolve({ key, dataIn }); } ttlManage(1); return init().then(( ) => { ttlManage(-1); - let encoded = encodeValue(key, data) || data; - if ( encoded instanceof Uint8Array ) { - encoded = new Blob([ encoded ]); + let dataOut = encodeValue(key, dataIn) || dataIn; + if ( dataOut instanceof Uint8Array ) { + dataOut = new Blob([ dataOut ]); } - return { key, data: encoded }; + return { key, data: dataOut }; }); }, - decode: function(key, data) { - if ( data instanceof Blob === false ) { - return Promise.resolve({ key, data }); + decode: function(key, dataIn) { + if ( dataIn instanceof Blob === false ) { + return Promise.resolve({ key, dataIn }); } ttlManage(1); return Promise.all([ init(), - uint8ArrayFromBlob(key, data) + uint8ArrayFromBlob(key, dataIn) ]).then(results => { ttlManage(-1); let result = results[1]; diff --git a/src/lib/lz4/lz4-block-codec-js.js b/src/lib/lz4/lz4-block-codec-js.js index d0d22b64f..c2696a714 100644 --- a/src/lib/lz4/lz4-block-codec-js.js +++ b/src/lib/lz4/lz4-block-codec-js.js @@ -46,13 +46,23 @@ /******************************************************************************/ +let growOutputBuffer = function(instance, size) { + if ( + instance.outputBuffer === undefined || + instance.outputBuffer.byteLength < size + ) { + instance.outputBuffer = new ArrayBuffer(size + 0xFFFF & 0x7FFF0000); + } + return instance.outputBuffer; +}; + let encodeBound = function(size) { return size > 0x7E000000 ? 0 : size + size / 255 + 16; }; -let encodeBlock = function(instance, iBuf, outOffset) { +let encodeBlock = function(instance, iBuf, oOffset) { let iLen = iBuf.byteLength; if ( iLen >= 0x7E000000 ) { throw new TypeError(); } @@ -71,9 +81,11 @@ let encodeBlock = function(instance, iBuf, outOffset) { iBuf = new Uint8Array(iBuf); } - let oBuf = new Uint8Array(outOffset + encodeBound(iLen)); + let oBuf = new Uint8Array( + growOutputBuffer(instance, oOffset + encodeBound(iLen)) + ); let iPos = 0; - let oPos = outOffset; + let oPos = oOffset; let anchorPos = 0; // sequence-finding loop @@ -174,13 +186,7 @@ let encodeBlock = function(instance, iBuf, outOffset) { let decodeBlock = function(instance, iBuf, iOffset, oLen) { let iLen = iBuf.byteLength; - if ( - instance.outputBuffer === undefined || - instance.outputBuffer.byteLength < oLen - ) { - instance.outputBuffer = new ArrayBuffer(oLen + 0xFFFF & 0x7FFF0000); - } - let oBuf = new Uint8Array(instance.outputBuffer, 0, oLen); + let oBuf = new Uint8Array(growOutputBuffer(instance, oLen)); let iPos = iOffset, oPos = 0; while ( iPos < iLen ) { @@ -255,6 +261,17 @@ context.LZ4BlockJS.prototype = { this.outputBuffer = undefined; }, + bytesInUse: function() { + let bytesInUse = 0; + if ( this.hashTable !== undefined ) { + bytesInUse += this.hashTable.byteLength; + } + if ( this.outputBuffer !== undefined ) { + bytesInUse += this.outputBuffer.byteLength; + } + return bytesInUse; + }, + encodeBlock: function(input, outputOffset) { if ( input instanceof ArrayBuffer ) { input = new Uint8Array(input); diff --git a/src/lib/lz4/lz4-block-codec-wasm.js b/src/lib/lz4/lz4-block-codec-wasm.js index fab00eda3..a13e7e6aa 100644 --- a/src/lib/lz4/lz4-block-codec-wasm.js +++ b/src/lib/lz4/lz4-block-codec-wasm.js @@ -125,6 +125,7 @@ context.LZ4BlockWASM = function() { context.LZ4BlockWASM.prototype = { flavor: 'wasm', + init: function() { if ( this.lz4wasmInstance instanceof WebAssembly.Instance ) { return Promise.resolve(this.lz4wasmInstance); @@ -158,6 +159,12 @@ context.LZ4BlockWASM.prototype = { this.lz4wasmInstance = undefined; }, + bytesInUse: function() { + return this.lz4wasmInstance instanceof WebAssembly.Instance ? + this.lz4wasmInstance.exports.memory.buffer.byteLength : + 0; + }, + encodeBlock: function(input, outputOffset) { if ( this.lz4wasmInstance instanceof WebAssembly.Instance === false ) { throw new Error('LZ4BlockWASM: not initialized');