fix: stack error caused by spread operator with large arrays

This commit is contained in:
Nick Krecklow 2021-05-31 01:27:20 -05:00
parent 539740d38a
commit 8a4ec554e2
No known key found for this signature in database
GPG Key ID: 5F149FDE156FFA94
4 changed files with 40 additions and 12 deletions

@ -8,7 +8,7 @@ export class RelativeScale {
const scale = Math.pow(10, factor)
const scaledMin = min - (min % scale)
let scaledMax = max + (max % scale === 0 ? 0 : (scale - (max % scale)))
let scaledMax = max + (max % scale === 0 ? 0 : scale - (max % scale))
// Prevent min/max from being equal (and generating 0 ticks)
// This happens when all data points are products of scale value
@ -32,9 +32,20 @@ export class RelativeScale {
}
static scaleMatrix (data, tickCount, maxFactor) {
const max = Math.max(...data.flat().filter(val => val !== null))
const nonNullData = data.flat().filter((val) => val !== null)
return RelativeScale.scale([0, RelativeScale.isFiniteOrZero(max)], tickCount, maxFactor)
// when used with the spread operator large nonNullData/data arrays can reach the max call stack size
// use reduce calls to safely determine min/max values for any size of array
// https://stackoverflow.com/questions/63705432/maximum-call-stack-size-exceeded-when-using-the-dots-operator/63706516#63706516
const max = nonNullData.reduce((a, b) => {
return Math.max(a, b)
})
return RelativeScale.scale(
[0, RelativeScale.isFiniteOrZero(max)],
tickCount,
maxFactor
)
}
static generateTicks (min, max, step) {
@ -52,8 +63,17 @@ export class RelativeScale {
max: 0
}
} else {
const min = Math.min(...data.filter(val => val !== null))
const max = Math.max(...data.filter(val => val !== null))
const nonNullData = data.filter((val) => val !== null)
// when used with the spread operator large nonNullData/data arrays can reach the max call stack size
// use reduce calls to safely determine min/max values for any size of array
// https://stackoverflow.com/questions/63705432/maximum-call-stack-size-exceeded-when-using-the-dots-operator/63706516#63706516
const min = nonNullData.reduce((a, b) => {
return Math.min(a, b)
})
const max = nonNullData.reduce((a, b) => {
return Math.max(a, b)
})
return {
min: RelativeScale.isFiniteOrZero(min),

@ -1,3 +1,11 @@
**5.5.9** *(May 31 20201)*
- Added configuration option to enable/disable ping failure logging.
- Fixed a rendering error when the primary historical graph has too many data points.
- Fixed sqlite3 errors from being ignored (now always logged).
- Fixed Minecraft session server URL (sessionserver.mojang.com -> session.minecraft.net)
- Updated to use parcel2
- Updated various dependencies.
**5.5.8** *(August 1 2020)*
- Adds daily database copies. This is mostly for use by Minetrack Data for automated exports. By setting `createDailyDatabaseCopy: true` in `config.json`, Minetrack will lazily create a copy of `database.sql` for each day, automatically rolling over to a new file each day. The database file is named in the format of `database_copy_(day)-(month)-(year).sql`. Daily database copies do not contain indexes or previous records. Pings are inserted into the daily database copy as they occur, Minetrack will not retroactively insert previous pings from `database.sql`.
- Bump lodash from 4.17.15 to 4.17.19

4
package-lock.json generated

@ -1,12 +1,12 @@
{
"name": "minetrack",
"version": "5.5.8",
"version": "5.5.9",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "minetrack",
"version": "5.5.8",
"version": "5.5.9",
"license": "MIT",
"dependencies": {
"finalhandler": "^1.1.2",

@ -1,6 +1,6 @@
{
"name": "minetrack",
"version": "5.5.8",
"version": "5.5.9",
"description": "A Minecraft server tracker that lets you focus on the basics.",
"dependencies": {
"finalhandler": "^1.1.2",