Add generic chart data processing.

This commit is contained in:
Marina Samuel 2014-05-27 17:39:28 -04:00
Родитель 9d11e2ea1f
Коммит 9dbd53ffea
2 изменённых файлов: 130 добавлений и 1 удалений

Просмотреть файл

@ -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;