Adding web worker support for the BI provider

This commit is contained in:
Stuart Lynn 2015-11-11 13:30:47 +00:00
parent 1ec2324b83
commit 7a1f206d5e

View File

@ -52,6 +52,39 @@ var Profiler = require('../profiler');
filterableJson.prototype = {
/**
* Creates a worker to process the tile
*/
createProccessTileWorker:function(){
var workerFunction = "var proccessTile ="+ this.proccessTileSerial.toString()
var wrapper = "; self.onmessage = function(e){var data = JSON.parse(e.data); JSON.stringify(self.postMessage(proccessTile(data.rows,data.coord, data.zoom, data.options)))}"
var script = workerFunction + wrapper;
var blob = new Blob([script], {type: "text/javascript"})
var worker = new Worker(window.URL.createObjectURL(blob))
return worker
},
proccessTile:function(rows,coord,zoom,callback){
if(typeof(Worker) === "undefined"){
callback(this.proccessTileSerial(rows,coord,zoom, this.options))
}
else{
var worker = this.createProccessTileWorker()
worker.onmessage = function(e){
callback(e.data)
worker.terminate()
}
var workerSafeOptions= {
x : new Uint8Array(rows.length),
y : new Uint8Array(rows.length),
resolution: this.options.resolution,
fields: this.options.fields
}
worker.postMessage(JSON.stringify({rows: rows, coord: {x:coord.x,y:coord.y}, zoom:zoom, options: workerSafeOptions}))
}
},
/**
* return the torque tile encoded in an efficient javascript
* structure:
@ -61,14 +94,16 @@ var Profiler = require('../profiler');
* Index: Array index to the properties
* }
*/
proccessTile: function(rows, coord, zoom) {
proccessTileSerial: function(rows, coord, zoom, options) {
var r;
var x = new Uint8Array(rows.length);
var y = new Uint8Array(rows.length);
var prof_mem = Profiler.metric('ProviderJSON:mem');
var prof_point_count = Profiler.metric('ProviderJSON:point_count');
var prof_process_time = Profiler.metric('ProviderJSON:process_time').start()
if(typeof(Profiler) != 'undefined') {
var prof_mem = Profiler.metric('ProviderJSON:mem');
var prof_point_count = Profiler.metric('ProviderJSON:point_count');
var prof_process_time = Profiler.metric('ProviderJSON:process_time').start()
}
// count number of steps
var maxDateSlots = Object.keys(rows[0].d).length;
@ -81,28 +116,35 @@ var Profiler = require('../profiler');
var renderData = new Float32Array(rows.length * steps); //(this.options.valueDataType || type)(steps);
var renderDataPos = new Uint32Array(rows.length * steps);
prof_mem.inc(
4 * maxDateSlots + // timeIndex
4 * maxDateSlots + // timeCount
steps + //renderData
steps * 4
); //renderDataPos
if(typeof(Profiler) !='undefined'){
prof_mem.inc(
4 * maxDateSlots + // timeIndex
4 * maxDateSlots + // timeCount
steps + //renderData
steps * 4
); //renderDataPos
prof_point_count.inc(rows.length);
prof_point_count.inc(rows.length);
}
var rowsPerSlot = {};
var steps = _.range(maxDateSlots);
// var steps = _.range(maxDateSlots);
var steps = []
for(var i=0 ; i< maxDateSlots; i++){
steps.push(i)
}
// precache pixel positions
for (var r = 0; r < rows.length; ++r) {
var row = rows[r];
x[r] = row.x * this.options.resolution;
x[r] = row.x * options.resolution;
// fix value when it's in the tile EDGE
// TODO: this should be fixed in SQL query
if (row.y === -1) {
y[r] = 0;
} else {
y[r] = row.y * this.options.resolution;
y[r] = row.y * options.resolution;
}
var vals = row.d;
@ -111,13 +153,13 @@ var Profiler = require('../profiler');
var rr = rowsPerSlot[steps[j]] || (rowsPerSlot[steps[j]] = []);
var k = 'f' + (j + 1)
var v = vals[k];
if (this.options.fields[j].type === 'cat') {
var mapping = this.categoryMapping[this.options.fields[j].name];
if (options.fields[j].type === 'cat') {
var mapping = this.categoryMapping[options.fields[j].name];
var m = mapping[v]
if (!m) {
var count = this.categoryMappingSize[this.options.fields[j].name];
var count = this.categoryMappingSize[options.fields[j].name];
if (count < 100) {
++this.categoryMappingSize[this.options.fields[j].name];
++this.categoryMappingSize[options.fields[j].name];
v = mapping[v] = count;
} else {
v = 0;
@ -152,7 +194,9 @@ var Profiler = require('../profiler');
timeSlotIndex += c;
}
prof_process_time.end();
if(typeof(Profiler) !='undefined'){
prof_process_time.end();
}
return {
x: x,
@ -359,7 +403,7 @@ var Profiler = require('../profiler');
if (data) {
var rows = JSON.parse(data.responseText).rows;
if (rows.length !== 0) {
callback(self.proccessTile(rows, coord, zoom));
self.proccessTile(rows, coord, zoom,callback);
} else {
callback(null);
}