Clean up updateDisplayPage for efficiency with lots of messages.

This commit is contained in:
Ian Gulliver
2016-01-12 20:51:03 -08:00
parent a1f732d12e
commit 356352cae4

View File

@@ -285,6 +285,11 @@ BabyStats.prototype.handleMessage_ = function(isEvent, message) {
} else { } else {
tile.lastSeen = message.created; tile.lastSeen = message.created;
tile.active = true; tile.active = true;
if (tile.messages.length) {
var lastMessage = tile.messages[tile.messages.length - 1];
tile.deltas.push(message.created - lastMessage.created);
tile.deltasDirty = true;
}
tile.messages.push(message); tile.messages.push(message);
(tile.cancels || []).forEach(function(type) { (tile.cancels || []).forEach(function(type) {
tile2 = this.tilesByType_[type]; tile2 = this.tilesByType_[type];
@@ -412,6 +417,8 @@ BabyStats.prototype.buildCells_ = function() {
this.tiles_.forEach(function(tile) { this.tiles_.forEach(function(tile) {
tile.active = false; tile.active = false;
tile.messages = []; tile.messages = [];
tile.deltas = [];
tile.deltasDirty = false;
var cell = document.createElement('babyStatsCell'); var cell = document.createElement('babyStatsCell');
this.cells_.push(cell); this.cells_.push(cell);
@@ -957,15 +964,41 @@ BabyStats.prototype.updateDisplayPage_ = function() {
this.displaySleepSummary_.style.visibility = 'hidden'; this.displaySleepSummary_.style.visibility = 'hidden';
} }
var cutoffs = [
['Past 6h', 6 * 60 * 60],
['Past 24h', 24 * 60 * 60],
['Past 7d', 7 * 24 * 60 * 60],
['Past 30d', 30 * 24 * 60 * 60],
['All time', Number.MAX_VALUE],
];
this.tiles_.forEach(function(tile) { this.tiles_.forEach(function(tile) {
var buckets = [
{
name: 'Past 6h',
cutoff: 6 * 60 * 60,
deltas: [],
count: 0,
},
{
name: 'Past 24h',
cutoff: 24 * 60 * 60,
deltas: [],
count: 0,
},
{
name: 'Past 7d',
cutoff: 7 * 24 * 60 * 60,
deltas: [],
count: 0,
},
{
name: 'Past 30d',
cutoff: 30 * 24 * 60 * 60,
deltas: [],
count: 0,
},
{
name: 'All time',
cutoff: Number.MAX_VALUE,
deltas: [],
count: 0,
},
];
var allTime = 4;
if (tile.lastSeen) { if (tile.lastSeen) {
var timeSince = now - tile.lastSeen; var timeSince = now - tile.lastSeen;
this.displayEventCountCells_[tile.type]['Most recent'].textContent = ( this.displayEventCountCells_[tile.type]['Most recent'].textContent = (
@@ -977,29 +1010,47 @@ BabyStats.prototype.updateDisplayPage_ = function() {
'never'; 'never';
} }
var timestamps = [[], [], [], [], []]; if (tile.deltasDirty) {
tile.messages.forEach(function(message) { tile.deltas.sort();
cutoffs.forEach(function(cutoff, i) { tile.deltasDirty = false;
var timeSince = now - message.created; }
if (timeSince < cutoff[1]) { buckets[allTime].deltas = tile.deltas;
// Sample belongs in this bucket buckets[allTime].count = tile.messages.length;
timestamps[i].push(message.created);
}
}.bind(this));
}.bind(this));
cutoffs.forEach(function(cutoff, i) { var startBucket = 0;
var text = timestamps[i].length.toString(); var lastTimestamp = null;
if (timestamps[i].length >= 2) { for (var i = tile.messages.length - 1; i >= 0; i--) {
var deltas = []; var message = tile.messages[i];
for (var j = 1; j < timestamps[i].length; j++) { var timeSince = now - message.created;
deltas.push(timestamps[i][j] - timestamps[i][j - 1]); while (startBucket < allTime &&
timeSince > buckets[startBucket].cutoff) {
startBucket++;
}
if (startBucket == allTime) {
// All remaining messages are outside the last bucket.
break;
}
var delta = null;
if (lastTimestamp) {
delta = lastTimestamp - message.created;
}
for (var j = startBucket; j < allTime; j++) {
buckets[j].count++;
if (delta) {
buckets[j].deltas.push(delta);
} }
deltas.sort(); }
var median = deltas[Math.floor(deltas.length / 2)]; lastTimestamp = message.created;
}
buckets.forEach(function(bucket) {
var text = bucket.count.toString();
if (bucket.deltas.length) {
bucket.deltas.sort();
var median = bucket.deltas[Math.floor(bucket.deltas.length / 2)];
text += '\n⏱ ' + this.secondsToHuman_(median, Math.round); text += '\n⏱ ' + this.secondsToHuman_(median, Math.round);
} }
this.displayEventCountCells_[tile.type][cutoff[0]].textContent = text; this.displayEventCountCells_[tile.type][bucket.name].textContent = text;
}.bind(this)); }.bind(this));
}.bind(this)); }.bind(this));