Add generic chart data processing.
This commit is contained in:
Родитель
9d11e2ea1f
Коммит
9dbd53ffea
|
@ -6,6 +6,9 @@ const {Cu} = require("chrome");
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
function ChartDataProcessor() {
|
||||||
|
}
|
||||||
|
|
||||||
function TimelineDataProcessor() {
|
function TimelineDataProcessor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +59,128 @@ DataProcessorHelper = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChartDataProcessor.prototype = {
|
||||||
|
_arraySum: function(arr) {
|
||||||
|
sum = 0;
|
||||||
|
for (element in arr) {
|
||||||
|
sum += parseInt(arr[element]);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
},
|
||||||
|
|
||||||
|
_daysPostEpochToDate: function(dayCount) {
|
||||||
|
return parseInt(dayCount) * 24 * 60 * 60 * 1000;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setMaxWeightAndDateCount: function(storedData, interest, newDayWeight, date) {
|
||||||
|
if (!storedData["interests"][interest]["maxWeight"] ||
|
||||||
|
newDayWeight > storedData["interests"][interest]["maxWeight"]) {
|
||||||
|
storedData["interests"][interest]["maxWeight"] = newDayWeight;
|
||||||
|
storedData["interests"][interest]["maxWeightDate"] = date;
|
||||||
|
}
|
||||||
|
storedData["interests"][interest]["dayCount"] =
|
||||||
|
Object.keys(storedData["interests"][interest]["dates"]).length;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setXYMaxMin: function(storedData) {
|
||||||
|
let categories = Object.keys(storedData["interests"]);
|
||||||
|
let xVals = categories.map((category) => {
|
||||||
|
return storedData["interests"][category]["x"];
|
||||||
|
});
|
||||||
|
storedData["xMax"] = Math.max.apply(null, xVals);
|
||||||
|
storedData["xMin"] = Math.min.apply(null, xVals);
|
||||||
|
|
||||||
|
let yVals = categories.map((category) => {
|
||||||
|
return storedData["interests"][category]["y"];
|
||||||
|
});
|
||||||
|
storedData["yMax"] = Math.max.apply(null, yVals);
|
||||||
|
storedData["yMin"] = Math.min.apply(null, yVals);
|
||||||
|
},
|
||||||
|
|
||||||
|
_cartesianDistance: function(x1, y1, x2, y2) {
|
||||||
|
return Math.sqrt(Math.pow(y1 - y2, 2) + Math.pow((x1 - x2), 2));
|
||||||
|
},
|
||||||
|
|
||||||
|
consume: function(bucketData) {
|
||||||
|
DataProcessorHelper.initChartInStorage("genericChartData");
|
||||||
|
// STEP 1
|
||||||
|
for (let day in bucketData) {
|
||||||
|
DataProcessorHelper.iterateOverTypeNamespace(bucketData[day], storage.chartData.genericChartData, (bucketData, storedData) => {
|
||||||
|
if (!storedData["interests"]) {
|
||||||
|
storedData["interests"] = {};
|
||||||
|
}
|
||||||
|
for (let interest in bucketData) {
|
||||||
|
if (!storedData["interests"][interest]) {
|
||||||
|
storedData["interests"][interest] = {};
|
||||||
|
storedData["interests"][interest]["dates"] = {};
|
||||||
|
}
|
||||||
|
let domainsToCountMap = bucketData[interest];
|
||||||
|
let visitCountSum = this._arraySum(domainsToCountMap);
|
||||||
|
storedData["interests"][interest]["dates"][day] =
|
||||||
|
{x: this._daysPostEpochToDate(day), size: visitCountSum, domainList: domainsToCountMap};
|
||||||
|
this._setMaxWeightAndDateCount(storedData, interest, visitCountSum, day);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentData = storage.chartData.genericChartData;
|
||||||
|
DataProcessorHelper.iterateOverTypeNamespace(currentData, currentData, (bucketData, storedData) => {
|
||||||
|
// STEP 2
|
||||||
|
// Sort interests by maxWeight and dayCount.
|
||||||
|
let sortedByWeights = [];
|
||||||
|
let sortedByDayCount = [];
|
||||||
|
DataProcessorHelper.interestsToArray(storedData["interests"], sortedByWeights);
|
||||||
|
DataProcessorHelper.interestsToArray(storedData["interests"], sortedByDayCount);
|
||||||
|
sortedByWeights.sort(DataProcessorHelper.propertyComparator("maxWeight"));
|
||||||
|
sortedByDayCount.sort(DataProcessorHelper.propertyComparator("dayCount"));
|
||||||
|
|
||||||
|
// Rank interests.
|
||||||
|
let rankMaxWeight = 1;
|
||||||
|
let rankDayCount = 1;
|
||||||
|
for (let i = 0; i < sortedByWeights.length; i++) {
|
||||||
|
if (i > 0 && (sortedByWeights[i - 1]["maxWeight"] != sortedByWeights[i]["maxWeight"])) {
|
||||||
|
rankMaxWeight++;
|
||||||
|
}
|
||||||
|
if (i > 0 && (sortedByDayCount[i - 1]["dayCount"] != sortedByDayCount[i]["dayCount"])) {
|
||||||
|
rankDayCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
storedData["interests"][sortedByDayCount[i]["category"]]["x"] = rankDayCount;
|
||||||
|
storedData["interests"][sortedByWeights[i]["category"]]["y"] = rankMaxWeight;
|
||||||
|
storedData["interests"][sortedByWeights[i]["category"]]["maxWeightDate"] = sortedByWeights[i]["maxWeightDate"];
|
||||||
|
}
|
||||||
|
this._setXYMaxMin(storedData);
|
||||||
|
|
||||||
|
// STEP 3
|
||||||
|
let intentX = storedData["xMin"];
|
||||||
|
let intentY = storedData["yMax"];
|
||||||
|
let interestX = storedData["xMax"];
|
||||||
|
let interestY = storedData["yMax"];
|
||||||
|
|
||||||
|
let sortedInterests = [];
|
||||||
|
let sortedIntents = [];
|
||||||
|
for (let category in bucketData["interests"]) {
|
||||||
|
let categoryX = storedData["interests"][category]["x"];
|
||||||
|
let categoryY = storedData["interests"][category]["y"];
|
||||||
|
|
||||||
|
storedData["interests"][category]["intentDist"] =
|
||||||
|
this._cartesianDistance(intentX, intentY, categoryX, categoryY);
|
||||||
|
storedData["interests"][category]["interestDist"] =
|
||||||
|
this._cartesianDistance(interestX, interestY, categoryX, categoryY);
|
||||||
|
}
|
||||||
|
DataProcessorHelper.interestsToArray(storedData["interests"], sortedInterests);
|
||||||
|
DataProcessorHelper.interestsToArray(storedData["interests"], sortedIntents);
|
||||||
|
sortedInterests.sort(DataProcessorHelper.propertyComparator("interestDist"));
|
||||||
|
sortedIntents.sort(DataProcessorHelper.propertyComparator("intentDist"));
|
||||||
|
|
||||||
|
delete storedData["interests"];
|
||||||
|
storedData["sortedIntents"] = sortedIntents;
|
||||||
|
storedData["sortedInterests"] = sortedInterests;
|
||||||
|
});
|
||||||
|
return storage.chartData.genericChartData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TimelineDataProcessor.prototype = {
|
TimelineDataProcessor.prototype = {
|
||||||
_arraySum: function(arr) {
|
_arraySum: function(arr) {
|
||||||
sum = 0;
|
sum = 0;
|
||||||
|
@ -212,6 +337,7 @@ IntentInterestDataProcessor.prototype = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.ChartDataProcessor = ChartDataProcessor;
|
||||||
exports.TimelineDataProcessor = TimelineDataProcessor;
|
exports.TimelineDataProcessor = TimelineDataProcessor;
|
||||||
exports.WeightIntensityDataProcessor = WeightIntensityDataProcessor;
|
exports.WeightIntensityDataProcessor = WeightIntensityDataProcessor;
|
||||||
exports.IntentInterestDataProcessor = IntentInterestDataProcessor;
|
exports.IntentInterestDataProcessor = IntentInterestDataProcessor;
|
||||||
|
|
|
@ -17,6 +17,7 @@ const {WorkerFactory} = require("WorkerFactory");
|
||||||
const {Pipeline} = require("Pipeline");
|
const {Pipeline} = require("Pipeline");
|
||||||
const {DayCountRanker} = require("DayCountRanker");
|
const {DayCountRanker} = require("DayCountRanker");
|
||||||
const {HostnameStripper} = require("HostnameStripper");
|
const {HostnameStripper} = require("HostnameStripper");
|
||||||
|
const {ChartDataProcessor} = require("ChartDataProcessor");
|
||||||
const {TimelineDataProcessor} = require("ChartDataProcessor");
|
const {TimelineDataProcessor} = require("ChartDataProcessor");
|
||||||
const {WeightIntensityDataProcessor} = require("ChartDataProcessor");
|
const {WeightIntensityDataProcessor} = require("ChartDataProcessor");
|
||||||
const {IntentInterestDataProcessor} = require("ChartDataProcessor");
|
const {IntentInterestDataProcessor} = require("ChartDataProcessor");
|
||||||
|
@ -47,6 +48,7 @@ function Controller(options={}) {
|
||||||
this._workers = this._workerFactory.getCurrentWorkers();
|
this._workers = this._workerFactory.getCurrentWorkers();
|
||||||
this._rankers = this._makeRankers();
|
this._rankers = this._makeRankers();
|
||||||
this._hostStripper = new HostnameStripper();
|
this._hostStripper = new HostnameStripper();
|
||||||
|
this._chartDataProcessor = new ChartDataProcessor();
|
||||||
this._timelineDataProcessor = new TimelineDataProcessor();
|
this._timelineDataProcessor = new TimelineDataProcessor();
|
||||||
this._weightIntensityDataProcessor = new WeightIntensityDataProcessor();
|
this._weightIntensityDataProcessor = new WeightIntensityDataProcessor();
|
||||||
this._intentInterestDataProcessor = new IntentInterestDataProcessor();
|
this._intentInterestDataProcessor = new IntentInterestDataProcessor();
|
||||||
|
@ -56,7 +58,8 @@ function Controller(options={}) {
|
||||||
});
|
});
|
||||||
this._urlClassifier = new UrlClassifier(this._workers);
|
this._urlClassifier = new UrlClassifier(this._workers);
|
||||||
|
|
||||||
this._dayBuffer = new DayBuffer(new Pipeline(this._rankers,
|
this._dayBuffer = new DayBuffer(new Pipeline(
|
||||||
|
this._rankers, this._chartDataProcessor,
|
||||||
this._timelineDataProcessor, this._weightIntensityDataProcessor,
|
this._timelineDataProcessor, this._weightIntensityDataProcessor,
|
||||||
this._intentInterestDataProcessor, this._dispatcher));
|
this._intentInterestDataProcessor, this._dispatcher));
|
||||||
this._processingHistory = false;
|
this._processingHistory = false;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче