Skip to content
Permalink
Browse files
[perf dashboard] Modernize TimeSeries and TimeSeriesView
https://bugs.webkit.org/show_bug.cgi?id=222872

Reviewed by Dewei Zhu.

Declare instance fields in class declarations, use const/let instead of var, and use generators
for forward and backward iterations instead of manually implementing the iterator protocol.

This patch also splits FilteredTimeSeriesView out of TimeSeriesView.

* public/v3/models/time-series.js:
(TimeSeries): Moved the declaration of _data instance field to the class declaration.
(TimeSeries.prototype.constructor): Deleted.
(TimeSeries.prototype.extendToFuture):
(TimeSeries.prototype.valuesBetweenRange):
(TimeSeries.prototype.findById):
(TimeSeries.prototype.findPointAfterTime):
(TimeSeriesView): Declared the instance fields in the class declaration.
(TimeSeriesView.prototype.constructor): Removed filteredData from the argument since it's split
out to FilteredTimeSeriesView now.
(TimeSeriesView.prototype.get _data): Added. An abstraction needed for FilteredTimeSeriesView.
(TimeSeriesView.prototype._findIndexForPoint): Ditto. Moved out of the constructor.
(TimeSeriesView.prototype.filter): Return a FilteredTimeSeriesView.
(TimeSeriesView.prototype.viewTimeRange): Use _subRange to return either TimeSeriesView or
FilteredTimeSeriesView which ever is needed.
(TimeSeriesView.prototype._subRange): An abstraction needed for FilteredTimeSeriesView.
(TimeSeriesView.prototype.Symbol.iterator): Made this a generator instead of implementing
the iterator protocol directly.
(TimeSeriesView.prototype._reverse): Ditto.
(FilteredTimeSeriesView): Added.
(FilteredTimeSeriesView.prototype.constructor): Added. Assert that afterEndingIndex is less than
the length of the filtered data. This assertion was missing in TimeSeries prior to this patch
when filteredData is specified.
(FilteredTimeSeriesView.prototype.get _data): Added.
(FilteredTimeSeriesView.prototype._subRange): Added. Instantiate FilteredTimeSeriesView with
the same filtered data.
(FilteredTimeSeriesView.prototype._findIndexForPoint): Moved from TimeSeriesView's constructor.
(FilteredTimeSeriesView.prototype._buildPointIndexMap): Moved from TimeSeriesView.


Canonical link: https://commits.webkit.org/234983@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@274047 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
rniwa committed Mar 7, 2021
1 parent fb2e8c1 commit a47008dcd26d65dba2dabd7e4967a0a799500da9
Showing 2 changed files with 113 additions and 54 deletions.
@@ -1,3 +1,44 @@
2021-03-06 Ryosuke Niwa <rniwa@webkit.org>

[perf dashboard] Modernize TimeSeries and TimeSeriesView
https://bugs.webkit.org/show_bug.cgi?id=222872

Reviewed by Dewei Zhu.

Declare instance fields in class declarations, use const/let instead of var, and use generators
for forward and backward iterations instead of manually implementing the iterator protocol.

This patch also splits FilteredTimeSeriesView out of TimeSeriesView.

* public/v3/models/time-series.js:
(TimeSeries): Moved the declaration of _data instance field to the class declaration.
(TimeSeries.prototype.constructor): Deleted.
(TimeSeries.prototype.extendToFuture):
(TimeSeries.prototype.valuesBetweenRange):
(TimeSeries.prototype.findById):
(TimeSeries.prototype.findPointAfterTime):
(TimeSeriesView): Declared the instance fields in the class declaration.
(TimeSeriesView.prototype.constructor): Removed filteredData from the argument since it's split
out to FilteredTimeSeriesView now.
(TimeSeriesView.prototype.get _data): Added. An abstraction needed for FilteredTimeSeriesView.
(TimeSeriesView.prototype._findIndexForPoint): Ditto. Moved out of the constructor.
(TimeSeriesView.prototype.filter): Return a FilteredTimeSeriesView.
(TimeSeriesView.prototype.viewTimeRange): Use _subRange to return either TimeSeriesView or
FilteredTimeSeriesView which ever is needed.
(TimeSeriesView.prototype._subRange): An abstraction needed for FilteredTimeSeriesView.
(TimeSeriesView.prototype.Symbol.iterator): Made this a generator instead of implementing
the iterator protocol directly.
(TimeSeriesView.prototype._reverse): Ditto.
(FilteredTimeSeriesView): Added.
(FilteredTimeSeriesView.prototype.constructor): Added. Assert that afterEndingIndex is less than
the length of the filtered data. This assertion was missing in TimeSeries prior to this patch
when filteredData is specified.
(FilteredTimeSeriesView.prototype.get _data): Added.
(FilteredTimeSeriesView.prototype._subRange): Added. Instantiate FilteredTimeSeriesView with
the same filtered data.
(FilteredTimeSeriesView.prototype._findIndexForPoint): Moved from TimeSeriesView's constructor.
(FilteredTimeSeriesView.prototype._buildPointIndexMap): Moved from TimeSeriesView.

2021-03-06 Ryosuke Niwa <rniwa@webkit.org>

[perf dashboard] Some browser tests are flaky or failing
@@ -1,10 +1,7 @@
'use strict';

class TimeSeries {
constructor()
{
this._data = [];
}
_data = [];

values() { return this._data.map((point) => point.value); }
length() { return this._data.length; }
@@ -21,7 +18,7 @@ class TimeSeries {
{
if (!this._data.length)
return;
var lastPoint = this._data[this._data.length - 1];
const lastPoint = this._data[this._data.length - 1];
this._data.push({
series: this,
seriesIndex: this._data.length,
@@ -35,9 +32,9 @@ class TimeSeries {
{
startingIndex = Math.max(startingIndex, 0);
endingIndex = Math.min(endingIndex, this._data.length);
var length = endingIndex - startingIndex;
var values = new Array(length);
for (var i = 0; i < length; i++)
const length = endingIndex - startingIndex;
const values = new Array(length);
for (let i = 0; i < length; ++i)
values[i] = this._data[startingIndex + i].value;
return values;
}
@@ -68,9 +65,9 @@ class TimeSeries {
return this._data[index];
}

findById(id) { return this._data.find(function (point) { return point.id == id }); }
findById(id) { return this._data.find((point) => point.id == id); }

findPointAfterTime(time) { return this._data.find(function (point) { return point.time >= time; }); }
findPointAfterTime(time) { return this._data.find((point) => point.time >= time); }
viewBetweenTime(startTime, endTime)
{
const startPoint = this.findPointAfterTime(startTime);
@@ -94,43 +91,35 @@ class TimeSeries {
};

class TimeSeriesView {
constructor(timeSeries, startingIndex, afterEndingIndex, filteredData = null)
_timeSeries;
_values = null;
_length;
_startingIndex;
_afterEndingIndex;

constructor(timeSeries, startingIndex, afterEndingIndex)
{
console.assert(timeSeries instanceof TimeSeries);
console.assert(startingIndex <= afterEndingIndex);
console.assert(afterEndingIndex <= timeSeries._data.length);
this._timeSeries = timeSeries;
this._data = filteredData || timeSeries._data;
this._values = null;
this._length = afterEndingIndex - startingIndex;
this._startingIndex = startingIndex;
this._afterEndingIndex = afterEndingIndex;
this._pointIndexMap = null;

if (this._data != timeSeries._data) {
this._findIndexForPoint = (point) => {
if (this._pointIndexMap == null)
this._buildPointIndexMap();
return this._pointIndexMap.get(point);
}
} else
this._findIndexForPoint = (point) => { return point.seriesIndex; }
}

_buildPointIndexMap()
{
this._pointIndexMap = new Map;
const data = this._data;
const length = data.length;
for (let i = 0; i < length; i++)
this._pointIndexMap.set(data[i], i);
}
get _data() { return this._timeSeries._data; }

length() { return this._length; }

firstPoint() { return this._length ? this._data[this._startingIndex] : null; }
lastPoint() { return this._length ? this._data[this._afterEndingIndex - 1] : null; }

_findIndexForPoint(point)
{
return point.seriesIndex;
}

nextPoint(point)
{
let index = this._findIndexForPoint(point);
@@ -185,7 +174,7 @@ class TimeSeriesView {
filteredData.push(point);
i++;
}
return new TimeSeriesView(this._timeSeries, 0, filteredData.length, filteredData);
return new FilteredTimeSeriesView(this._timeSeries, 0, filteredData.length, filteredData);
}

viewTimeRange(startTime, endTime)
@@ -200,8 +189,13 @@ class TimeSeriesView {
endingIndex = i;
}
if (startingIndex == null || endingIndex == null)
return new TimeSeriesView(this._timeSeries, 0, 0, data);
return new TimeSeriesView(this._timeSeries, startingIndex, endingIndex + 1, data);
return this._subRange(0, 0);
return this._subRange(startingIndex, endingIndex + 1);
}

_subRange(startingIndex, afterEndingIndex)
{
return new TimeSeriesView(this._timeSeries, startingIndex, afterEndingIndex);
}

firstPointInTimeRange(startTime, endTime)
@@ -228,32 +222,56 @@ class TimeSeriesView {
return null;
}

[Symbol.iterator]()
*[Symbol.iterator]()
{
const data = this._data;
const end = this._afterEndingIndex;
const afterEnd = this._afterEndingIndex;
let i = this._startingIndex;
return {
next() {
return {value: data[i], done: i++ == end};
}
};
for (let i = this._startingIndex; i < afterEnd; ++i)
yield data[i];
}

_reverse()
*_reverse()
{
return {
[Symbol.iterator]: () => {
const data = this._data;
const end = this._startingIndex;
let i = this._afterEndingIndex;
return {
next() {
return {done: i-- == end, value: data[i]};
}
};
}
}
const data = this._data;
const beginning = this._startingIndex;
for (let i = this._afterEndingIndex - 1; i >= beginning; --i)
yield data[i];
}
}

class FilteredTimeSeriesView extends TimeSeriesView {
_filteredData;
_pointIndexMap;

constructor(timeSeries, startingIndex, afterEndingIndex, filteredData)
{
console.assert(afterEndingIndex <= filteredData.length);
super(timeSeries, startingIndex, afterEndingIndex);
this._filteredData = filteredData;
}

get _data() { return this._filteredData; }

_subRange(startingIndex, afterEndingIndex)
{
return new FilteredTimeSeriesView(this._timeSeries, startingIndex, afterEndingIndex, this._filteredData);
}

_findIndexForPoint(point)
{
if (!this._pointIndexMap)
this._buildPointIndexMap();
return this._pointIndexMap.get(point);
}

_buildPointIndexMap()
{
this._pointIndexMap = new Map;
const data = this._data;
const length = data.length;
for (let i = 0; i < length; i++)
this._pointIndexMap.set(data[i], i);
}
}

0 comments on commit a47008d

Please sign in to comment.