Use memoize one to cache transformation output
parent
5e9e859a3a
commit
fb1b460322
|
@ -56,9 +56,9 @@ const filterTables = (tables: FluxTable[]): FluxTable[] => {
|
|||
})
|
||||
}
|
||||
|
||||
const filteredTablesMemoized = memoizeOne(filterTables)
|
||||
|
||||
class TimeMachineTables extends PureComponent<Props, State> {
|
||||
private filteredTablesMemoized = memoizeOne(filterTables)
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
|
@ -183,9 +183,12 @@ class TimeMachineTables extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
private get selectedResult(): FluxTable {
|
||||
const filteredTables = filteredTablesMemoized(this.props.data)
|
||||
const filteredTables = this.filteredTablesMemoized(this.props.data)
|
||||
const table = filteredTables.find(
|
||||
d => d.name === this.state.selectedResultID
|
||||
)
|
||||
|
||||
return filteredTables.find(d => d.name === this.state.selectedResultID)
|
||||
return table
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
import _ from 'lodash'
|
||||
import memoizeOne from 'memoize-one'
|
||||
|
||||
// Components
|
||||
import Gauge from 'src/shared/components/Gauge'
|
||||
|
@ -8,7 +9,12 @@ import InvalidData from 'src/shared/components/InvalidData'
|
|||
|
||||
// Utils
|
||||
import {manager} from 'src/worker/JobManager'
|
||||
import {getDataUUID, hasDataChanged} from 'src/shared/graphs/helpers'
|
||||
import {
|
||||
getDataUUID,
|
||||
hasDataPropsChanged,
|
||||
isFluxDataEqual,
|
||||
isInluxQLDataEqual,
|
||||
} from 'src/shared/graphs/helpers'
|
||||
import getLastValues from 'src/shared/parsing/lastValues'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
|
@ -52,6 +58,14 @@ class GaugeChart extends PureComponent<Props, State> {
|
|||
|
||||
private isComponentMounted: boolean
|
||||
private lastUUID: string
|
||||
private memoizedTimeSeriesToSingleStat = memoizeOne(
|
||||
getLastValues,
|
||||
isInluxQLDataEqual
|
||||
)
|
||||
private memoizedFluxTablesToSingleStat = memoizeOne(
|
||||
manager.fluxTablesToSingleStat,
|
||||
isFluxDataEqual
|
||||
)
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props)
|
||||
|
@ -67,7 +81,7 @@ class GaugeChart extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
public async componentDidUpdate(prevProps: Props) {
|
||||
const isDataChanged = hasDataChanged(prevProps, this.props)
|
||||
const isDataChanged = hasDataPropsChanged(prevProps, this.props)
|
||||
|
||||
this.lastUUID = getDataUUID(this.props.data, this.props.dataType)
|
||||
|
||||
|
@ -139,9 +153,13 @@ class GaugeChart extends PureComponent<Props, State> {
|
|||
let isValidData = true
|
||||
try {
|
||||
if (dataType === DataType.flux) {
|
||||
lastValues = await manager.fluxTablesToSingleStat(data as FluxTable[])
|
||||
lastValues = await this.memoizedFluxTablesToSingleStat(
|
||||
data as FluxTable[]
|
||||
)
|
||||
} else if (dataType === DataType.influxQL) {
|
||||
lastValues = getLastValues(data as TimeSeriesServerResponse[])
|
||||
lastValues = this.memoizedTimeSeriesToSingleStat(
|
||||
data as TimeSeriesServerResponse[]
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
|
|
|
@ -3,6 +3,7 @@ import React, {PureComponent, CSSProperties} from 'react'
|
|||
import _ from 'lodash'
|
||||
import Dygraph from 'src/shared/components/Dygraph'
|
||||
import {withRouter, RouteComponentProps} from 'react-router'
|
||||
import memoizeOne from 'memoize-one'
|
||||
|
||||
// Components
|
||||
import SingleStat from 'src/shared/components/SingleStat'
|
||||
|
@ -16,7 +17,12 @@ import {
|
|||
} from 'src/utils/timeSeriesTransformers'
|
||||
import {manager} from 'src/worker/JobManager'
|
||||
import {fluxTablesToDygraph} from 'src/shared/parsing/flux/dygraph'
|
||||
import {getDataUUID, hasDataChanged} from 'src/shared/graphs/helpers'
|
||||
import {
|
||||
getDataUUID,
|
||||
hasDataPropsChanged,
|
||||
isFluxDataEqual,
|
||||
isInluxQLDataEqual,
|
||||
} from 'src/shared/graphs/helpers'
|
||||
|
||||
// Types
|
||||
import {ColorString} from 'src/types/colors'
|
||||
|
@ -66,6 +72,15 @@ class LineGraph extends PureComponent<LineGraphProps, State> {
|
|||
private isComponentMounted: boolean = false
|
||||
private isValidData: boolean = true
|
||||
|
||||
private memoizedTimeSeriesToDygraph = memoizeOne(
|
||||
timeSeriesToDygraph,
|
||||
isInluxQLDataEqual
|
||||
)
|
||||
private memoizedFluxTablesToDygraph = memoizeOne(
|
||||
fluxTablesToDygraph,
|
||||
isFluxDataEqual
|
||||
)
|
||||
|
||||
constructor(props: LineGraphProps) {
|
||||
super(props)
|
||||
|
||||
|
@ -108,7 +123,7 @@ class LineGraph extends PureComponent<LineGraphProps, State> {
|
|||
}
|
||||
|
||||
public componentDidUpdate(prevProps: LineGraphProps) {
|
||||
const isDataChanged = hasDataChanged(prevProps, this.props)
|
||||
const isDataChanged = hasDataPropsChanged(prevProps, this.props)
|
||||
|
||||
if (this.props.loading === RemoteDataState.Done && isDataChanged) {
|
||||
this.parseTimeSeries(this.props.data, this.props.dataType)
|
||||
|
@ -245,14 +260,14 @@ class LineGraph extends PureComponent<LineGraphProps, State> {
|
|||
|
||||
let result: TimeSeriesToDyGraphReturnType
|
||||
if (dataType === DataType.influxQL) {
|
||||
result = await timeSeriesToDygraph(
|
||||
result = await this.memoizedTimeSeriesToDygraph(
|
||||
data as TimeSeriesServerResponse[],
|
||||
location.pathname
|
||||
)
|
||||
}
|
||||
|
||||
if (dataType === DataType.flux) {
|
||||
result = await fluxTablesToDygraph(data as FluxTable[])
|
||||
result = await this.memoizedFluxTablesToDygraph(data as FluxTable[])
|
||||
}
|
||||
|
||||
return {result, uuid: getDataUUID(data, dataType)}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import React, {PureComponent, CSSProperties} from 'react'
|
||||
import classnames from 'classnames'
|
||||
import _ from 'lodash'
|
||||
import memoizeOne from 'memoize-one'
|
||||
|
||||
// Components
|
||||
import InvalidData from 'src/shared/components/InvalidData'
|
||||
|
@ -11,7 +12,9 @@ import {manager} from 'src/worker/JobManager'
|
|||
import {
|
||||
SMALL_CELL_HEIGHT,
|
||||
getDataUUID,
|
||||
hasDataChanged,
|
||||
hasDataPropsChanged,
|
||||
isFluxDataEqual,
|
||||
isInluxQLDataEqual,
|
||||
} from 'src/shared/graphs/helpers'
|
||||
import getLastValues from 'src/shared/parsing/lastValues'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
@ -60,6 +63,14 @@ class SingleStat extends PureComponent<Props, State> {
|
|||
|
||||
private isComponentMounted: boolean
|
||||
private lastUUID: string
|
||||
private memoizedTimeSeriesToSingleStat = memoizeOne(
|
||||
getLastValues,
|
||||
isInluxQLDataEqual
|
||||
)
|
||||
private memoizedFluxTablesToSingleStat = memoizeOne(
|
||||
manager.fluxTablesToSingleStat,
|
||||
isFluxDataEqual
|
||||
)
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props)
|
||||
|
@ -76,7 +87,7 @@ class SingleStat extends PureComponent<Props, State> {
|
|||
|
||||
public async componentDidUpdate(prevProps: Props) {
|
||||
this.lastUUID = getDataUUID(this.props.data, this.props.dataType)
|
||||
const isDataChanged = hasDataChanged(prevProps, this.props)
|
||||
const isDataChanged = hasDataPropsChanged(prevProps, this.props)
|
||||
|
||||
if (isDataChanged) {
|
||||
await this.dataToLastValues()
|
||||
|
@ -246,9 +257,13 @@ class SingleStat extends PureComponent<Props, State> {
|
|||
let isValidData = true
|
||||
try {
|
||||
if (dataType === DataType.flux) {
|
||||
lastValues = await manager.fluxTablesToSingleStat(data as FluxTable[])
|
||||
lastValues = await this.memoizedFluxTablesToSingleStat(
|
||||
data as FluxTable[]
|
||||
)
|
||||
} else if (dataType === DataType.influxQL) {
|
||||
lastValues = getLastValues(data as TimeSeriesServerResponse[])
|
||||
lastValues = this.memoizedTimeSeriesToSingleStat(
|
||||
data as TimeSeriesServerResponse[]
|
||||
)
|
||||
}
|
||||
|
||||
if (
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Libraries
|
||||
import React, {PureComponent} from 'react'
|
||||
import _ from 'lodash'
|
||||
import memoizeOne from 'memoize-one'
|
||||
|
||||
// Utils
|
||||
import {manager} from 'src/worker/JobManager'
|
||||
|
@ -64,8 +65,39 @@ interface State {
|
|||
invalidDataError: ErrorTypes
|
||||
}
|
||||
|
||||
interface FormatProperties {
|
||||
sort?: Sort
|
||||
fieldOptions: FieldOption[]
|
||||
tableOptions: TableOptions
|
||||
timeFormat: string
|
||||
decimalPlaces: DecimalPlaces
|
||||
uuid: string
|
||||
}
|
||||
const areFormatPropertiesEqual = (
|
||||
prevProperties: FormatProperties,
|
||||
newProperties: FormatProperties
|
||||
) => {
|
||||
const formatProps = [
|
||||
'uuid',
|
||||
'tableOptions',
|
||||
'fieldOptions',
|
||||
'timeFormat',
|
||||
'sort',
|
||||
]
|
||||
|
||||
const areEqual = formatProps.every(k =>
|
||||
_.isEqual(prevProperties[k], newProperties[k])
|
||||
)
|
||||
|
||||
return areEqual
|
||||
}
|
||||
|
||||
class TableGraphFormat extends PureComponent<Props, State> {
|
||||
private isComponentMounted: boolean
|
||||
private memoizedTableTransform = memoizeOne(
|
||||
manager.tableTransform,
|
||||
areFormatPropertiesEqual
|
||||
)
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props)
|
||||
|
@ -116,16 +148,7 @@ class TableGraphFormat extends PureComponent<Props, State> {
|
|||
}
|
||||
|
||||
public componentDidUpdate(prevProps: Props) {
|
||||
const updatedProps = _.keys(_.omit(prevProps, 'data')).filter(
|
||||
k => !_.isEqual(this.props[k], prevProps[k])
|
||||
)
|
||||
|
||||
if (
|
||||
this.props.uuid !== prevProps.uuid ||
|
||||
_.includes(updatedProps, 'tableOptions') ||
|
||||
_.includes(updatedProps, 'fieldOptions') ||
|
||||
_.includes(updatedProps, 'timeFormat')
|
||||
) {
|
||||
if (!areFormatPropertiesEqual(prevProps, this.props)) {
|
||||
this.formatData()
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +163,7 @@ class TableGraphFormat extends PureComponent<Props, State> {
|
|||
decimalPlaces,
|
||||
} = this.props
|
||||
|
||||
const {sort} = this.state
|
||||
const sort = {...this.state.sort}
|
||||
|
||||
if (sortField === sort.field) {
|
||||
sort.direction = sort.direction === ASCENDING ? DESCENDING : ASCENDING
|
||||
|
@ -159,14 +182,15 @@ class TableGraphFormat extends PureComponent<Props, State> {
|
|||
)
|
||||
|
||||
try {
|
||||
const formattedData = await manager.tableTransform(
|
||||
this.props.data.data,
|
||||
const formattedData = await this.memoizedTableTransform({
|
||||
data: this.props.data.data,
|
||||
sort,
|
||||
computedFieldOptions,
|
||||
fieldOptions: computedFieldOptions,
|
||||
tableOptions,
|
||||
timeFormat,
|
||||
decimalPlaces
|
||||
)
|
||||
decimalPlaces,
|
||||
uuid: latestUUID,
|
||||
})
|
||||
|
||||
if (!this.isComponentMounted) {
|
||||
return
|
||||
|
@ -184,6 +208,7 @@ class TableGraphFormat extends PureComponent<Props, State> {
|
|||
if (!this.isComponentMounted) {
|
||||
return
|
||||
}
|
||||
console.error(err)
|
||||
|
||||
this.setState({invalidDataError: ErrorTypes.GeneralError})
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import React, {PureComponent} from 'react'
|
||||
import _ from 'lodash'
|
||||
import uuid from 'uuid'
|
||||
import memoizeOne from 'memoize-one'
|
||||
|
||||
// Components
|
||||
import InvalidData from 'src/shared/components/InvalidData'
|
||||
|
@ -12,6 +13,7 @@ import {
|
|||
ErrorTypes,
|
||||
getInvalidDataMessage,
|
||||
} from 'src/dashboards/utils/tableGraph'
|
||||
import {isInluxQLDataEqual} from 'src/shared/graphs/helpers'
|
||||
|
||||
// Types
|
||||
import {
|
||||
|
@ -40,6 +42,10 @@ interface State {
|
|||
|
||||
class TableGraphTransform extends PureComponent<Props, State> {
|
||||
private isComponentMounted: boolean
|
||||
private memoizedTimeSeriesToTableGraph = memoizeOne(
|
||||
timeSeriesToTableGraph,
|
||||
isInluxQLDataEqual
|
||||
)
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props)
|
||||
|
@ -83,7 +89,7 @@ class TableGraphTransform extends PureComponent<Props, State> {
|
|||
|
||||
if (dataType === DataType.influxQL) {
|
||||
try {
|
||||
const influxQLData = await timeSeriesToTableGraph(
|
||||
const influxQLData = await this.memoizedTimeSeriesToTableGraph(
|
||||
data as TimeSeriesServerResponse[]
|
||||
)
|
||||
|
||||
|
|
|
@ -187,27 +187,47 @@ export const getDataUUID = (
|
|||
dataType: DataType
|
||||
): string => {
|
||||
if (dataType === DataType.influxQL) {
|
||||
return getDeep(data, '0.response.uuid', '')
|
||||
return getInfluxQLDataUUID(data as TimeSeriesServerResponse[])
|
||||
} else {
|
||||
return getDeep(data, '0.id', '')
|
||||
return getFluxDataUUID(data as FluxTable[])
|
||||
}
|
||||
}
|
||||
|
||||
const getInfluxQLDataUUID = (data: TimeSeriesServerResponse[]): string => {
|
||||
return getDeep(data, '0.response.uuid', '')
|
||||
}
|
||||
|
||||
const getFluxDataUUID = (data: FluxTable[]): string => {
|
||||
return getDeep(data, '0.id', '')
|
||||
}
|
||||
|
||||
export const isFluxDataEqual = (
|
||||
prevData: FluxTable[],
|
||||
newData: FluxTable[]
|
||||
): boolean => {
|
||||
return getFluxDataUUID(prevData) === getFluxDataUUID(newData)
|
||||
}
|
||||
|
||||
export const isInluxQLDataEqual = (
|
||||
prevData: TimeSeriesServerResponse[],
|
||||
newData: TimeSeriesServerResponse[]
|
||||
): boolean => {
|
||||
return getInfluxQLDataUUID(prevData) === getInfluxQLDataUUID(newData)
|
||||
}
|
||||
|
||||
interface DataProps {
|
||||
data: TimeSeriesServerResponse[] | FluxTable[]
|
||||
dataType: DataType
|
||||
timeRange?: TimeRange
|
||||
}
|
||||
export const hasDataChanged = (
|
||||
export const hasDataPropsChanged = (
|
||||
prevProps: DataProps,
|
||||
newProps: DataProps
|
||||
): boolean => {
|
||||
const isDataTypeChanged = prevProps.dataType !== newProps.dataType
|
||||
const isDataIDsChanged = !_.isEqual(
|
||||
getDataUUID(prevProps.data, prevProps.dataType),
|
||||
const isDataIDsChanged =
|
||||
getDataUUID(prevProps.data, prevProps.dataType) !==
|
||||
getDataUUID(newProps.data, newProps.dataType)
|
||||
)
|
||||
|
||||
const isTimeRangeChanged = !_.isEqual(
|
||||
_.get(prevProps, 'timeRange'),
|
||||
_.get(newProps, 'timeRange')
|
||||
|
|
|
@ -7,6 +7,13 @@ import {
|
|||
TimeSeriesToTableGraphReturnType,
|
||||
} from 'src/types/series'
|
||||
import {DygraphValue, FluxTable} from 'src/types'
|
||||
import {
|
||||
Sort,
|
||||
FieldOption,
|
||||
TableOptions,
|
||||
DecimalPlaces,
|
||||
TimeSeriesValue,
|
||||
} from 'src/types/dashboards'
|
||||
import {getBasepath} from 'src/utils/basepath'
|
||||
import {TimeSeriesToDyGraphReturnType} from 'src/worker/jobs/timeSeriesToDygraph'
|
||||
import {FluxTablesToDygraphResult} from 'src/worker/jobs/fluxTablesToDygraph'
|
||||
|
@ -36,23 +43,14 @@ class JobManager {
|
|||
})
|
||||
}
|
||||
|
||||
public async tableTransform(
|
||||
data,
|
||||
sort,
|
||||
fieldOptions,
|
||||
tableOptions,
|
||||
timeFormat,
|
||||
decimalPlaces
|
||||
): Promise<any> {
|
||||
const payload = {
|
||||
data,
|
||||
sort,
|
||||
fieldOptions,
|
||||
tableOptions,
|
||||
timeFormat,
|
||||
decimalPlaces,
|
||||
}
|
||||
|
||||
public tableTransform = async (payload: {
|
||||
data: TimeSeriesValue[][]
|
||||
sort: Sort
|
||||
fieldOptions: FieldOption[]
|
||||
tableOptions: TableOptions
|
||||
timeFormat: string
|
||||
decimalPlaces: DecimalPlaces
|
||||
}): Promise<any> => {
|
||||
return this.publishDBJob('TABLETRANSFORM', payload)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue