FieldValues: Use plain arrays instead of Vector (part 2 of 2) (#66224)

Co-authored-by: Leon Sorokin <leeoniya@gmail.com>
This commit is contained in:
Ryan McKinley
2023-04-14 09:03:45 -05:00
committed by GitHub
co-authored by Leon Sorokin
parent 6d53c87862
commit e65163ba4e
57 changed files with 374 additions and 448 deletions
@@ -1,4 +1,3 @@
import { ArrayVector } from '..';
import { DataFrame, FieldType } from '../types/dataFrame';
import { DataFrameJSON, dataFrameFromJSON, dataFrameToJSON } from './DataFrameJSON';
@@ -203,13 +202,13 @@ describe('DataFrame JSON', () => {
name: 'time1',
type: FieldType.time,
config: {},
values: new ArrayVector([11, 12, 13]),
values: [11, 12, 13],
},
{
name: 'time2',
type: FieldType.time,
config: {},
values: new ArrayVector([14, 15, 16]),
values: [14, 15, 16],
nanos: [17, 18, 19],
},
],
@@ -1,5 +1,4 @@
import { DataFrame, FieldType, FieldConfig, Labels, QueryResultMeta, Field } from '../types';
import { ArrayVector } from '../vector';
import { guessFieldTypeFromNameAndValue } from './processDataFrame';
@@ -203,7 +202,7 @@ export function dataFrameFromJSON(dto: DataFrameJSON): DataFrame {
...f,
type: type ?? guessFieldType(f.name, buffer),
config: f.config ?? {},
values: new ArrayVector(buffer),
values: buffer,
// the presence of this prop is an optimization signal & lookup for consumers
entities: entities ?? {},
};
@@ -242,7 +241,7 @@ export function dataFrameToJSON(frame: DataFrame): DataFrameJSON {
fields: frame.fields.map((f) => {
const { values, nanos, state, display, ...sfield } = f;
delete (sfield as any).entities;
data.values.push(values.toArray());
data.values.push(values);
if (nanos != null) {
allNanos.push(nanos);
@@ -15,15 +15,15 @@ describe('Reversing DataFrame', () => {
const helper = new MutableDataFrame(frame);
expect(helper.fields[0].values.toArray()).toEqual([100, 200, 300]);
expect(helper.fields[1].values.toArray()).toEqual(['a', 'b', 'c']);
expect(helper.fields[2].values.toArray()).toEqual([1, 2, 3]);
expect(helper.fields[0].values).toEqual([100, 200, 300]);
expect(helper.fields[1].values).toEqual(['a', 'b', 'c']);
expect(helper.fields[2].values).toEqual([1, 2, 3]);
helper.reverse();
expect(helper.fields[0].values.toArray()).toEqual([300, 200, 100]);
expect(helper.fields[1].values.toArray()).toEqual(['c', 'b', 'a']);
expect(helper.fields[2].values.toArray()).toEqual([3, 2, 1]);
expect(helper.fields[0].values).toEqual([300, 200, 100]);
expect(helper.fields[1].values).toEqual(['c', 'b', 'a']);
expect(helper.fields[2].values).toEqual([3, 2, 1]);
});
});
});
@@ -39,7 +39,7 @@ describe('Apending DataFrame', () => {
};
const frame = new MutableDataFrame(dto);
expect(frame.fields[0].values.toArray()).toEqual([100, undefined, undefined]);
expect(frame.fields[0].values).toEqual([100, undefined, undefined]);
// Set a value on the second row
frame.set(1, { time: 200, name: 'BB', value: 20 });
@@ -2,16 +2,14 @@ import { isString } from 'lodash';
import { QueryResultMeta } from '../types/data';
import { Field, DataFrame, DataFrameDTO, FieldDTO, FieldType } from '../types/dataFrame';
import { Vector } from '../types/vector';
import { makeFieldParser } from '../utils/fieldParser';
import { ArrayVector } from '../vector/ArrayVector';
import { FunctionalVector } from '../vector/FunctionalVector';
import { guessFieldTypeFromValue, guessFieldTypeForField, toDataFrameDTO } from './processDataFrame';
export type MutableField<T = any> = Field<T>;
type MutableVectorCreator = (buffer?: any[]) => Vector;
type MutableVectorCreator = (buffer?: any[]) => any[];
export const MISSING_VALUE = undefined; // Treated as connected in new graph panel
@@ -21,7 +19,7 @@ export class MutableDataFrame<T = any> extends FunctionalVector<T> implements Da
meta?: QueryResultMeta;
fields: MutableField[] = [];
private first: Vector = new ArrayVector();
private first: any[] = [];
private creator: MutableVectorCreator;
constructor(source?: DataFrame | DataFrameDTO, creator?: MutableVectorCreator) {
@@ -31,7 +29,7 @@ export class MutableDataFrame<T = any> extends FunctionalVector<T> implements Da
this.creator = creator
? creator
: (buffer?: any[]) => {
return new ArrayVector(buffer);
return buffer ?? [];
};
// Copy values from
@@ -78,11 +76,7 @@ export class MutableDataFrame<T = any> extends FunctionalVector<T> implements Da
let buffer: any[] | undefined = undefined;
if (f.values) {
if (Array.isArray(f.values)) {
buffer = f.values;
} else {
buffer = (f.values as Vector).toArray();
}
buffer = f.values;
}
let type = f.type;
@@ -22,10 +22,8 @@ import {
DataQueryResponseData,
PanelData,
LoadingState,
GraphSeriesValue,
} from '../types/index';
import { ArrayVector } from '../vector/ArrayVector';
import { SortedVector } from '../vector/SortedVector';
import { vectorToArray } from '../vector/vectorToArray';
import { ArrayDataFrame } from './ArrayDataFrame';
import { dataFrameFromJSON } from './DataFrameJSON';
@@ -38,7 +36,7 @@ function convertTableToDataFrame(table: TableData): DataFrame {
return {
name: text?.length ? text : c, // rename 'text' to the 'name' field
config: (disp || {}) as FieldConfig,
values: new ArrayVector(),
values: [] as any[],
type: type && Object.values(FieldType).includes(type as FieldType) ? (type as FieldType) : FieldType.other,
};
});
@@ -49,7 +47,7 @@ function convertTableToDataFrame(table: TableData): DataFrame {
for (const row of table.rows) {
for (let i = 0; i < fields.length; i++) {
fields[i].values.buffer.push(row[i]);
fields[i].values.push(row[i]);
}
}
@@ -87,7 +85,7 @@ function convertTimeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame {
name: TIME_SERIES_TIME_FIELD_NAME,
type: FieldType.time,
config: {},
values: new ArrayVector<number>(times),
values: times,
},
{
name: TIME_SERIES_VALUE_FIELD_NAME,
@@ -95,7 +93,7 @@ function convertTimeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame {
config: {
unit: timeSeries.unit,
},
values: new ArrayVector<TimeSeriesValue>(values),
values: values,
labels: timeSeries.tags,
},
];
@@ -118,13 +116,13 @@ function convertTimeSeriesToDataFrame(timeSeries: TimeSeries): DataFrame {
* to DataFrame. See: https://github.com/grafana/grafana/issues/18528
*/
function convertGraphSeriesToDataFrame(graphSeries: GraphSeriesXY): DataFrame {
const x = new ArrayVector();
const y = new ArrayVector();
const x: GraphSeriesValue[] = [];
const y: GraphSeriesValue[] = [];
for (let i = 0; i < graphSeries.data.length; i++) {
const row = graphSeries.data[i];
x.buffer.push(row[1]);
y.buffer.push(row[0]);
x.push(row[1]);
y.push(row[0]);
}
return {
@@ -145,7 +143,7 @@ function convertGraphSeriesToDataFrame(graphSeries: GraphSeriesXY): DataFrame {
values: y,
},
],
length: x.buffer.length,
length: x.length,
};
}
@@ -159,12 +157,12 @@ function convertJSONDocumentDataToDataFrame(timeSeries: TimeSeries): DataFrame {
unit: timeSeries.unit,
filterable: (timeSeries as any).filterable,
},
values: new ArrayVector(),
values: [] as TimeSeriesValue[][],
},
];
for (const point of timeSeries.datapoints) {
fields[0].values.buffer.push(point);
fields[0].values.push(point);
}
return {
@@ -392,7 +390,7 @@ export const toLegacyResponseData = (frame: DataFrame): TimeSeries | TableData =
return {
alias: fields[0].name || frame.name,
target: fields[0].name || frame.name,
datapoints: fields[0].values.toArray(),
datapoints: fields[0].values,
filterable: fields[0].config ? fields[0].config.filterable : undefined,
type: 'docs',
} as TimeSeries;
@@ -436,7 +434,7 @@ export function sortDataFrame(data: DataFrame, sortIndex?: number, reverse = fal
fields: data.fields.map((f) => {
return {
...f,
values: new SortedVector(f.values, index),
values: f.values.map((v, i) => f.values[index[i]]),
};
}),
};
@@ -449,11 +447,11 @@ export function reverseDataFrame(data: DataFrame): DataFrame {
return {
...data,
fields: data.fields.map((f) => {
const copy = [...f.values.toArray()];
copy.reverse();
const values = [...f.values];
values.reverse();
return {
...f,
values: new ArrayVector(copy),
values,
};
}),
};
@@ -480,11 +478,7 @@ export function toDataFrameDTO(data: DataFrame): DataFrameDTO {
export function toFilteredDataFrameDTO(data: DataFrame, fieldPredicate?: (f: Field) => boolean): DataFrameDTO {
const filteredFields = fieldPredicate ? data.fields.filter(fieldPredicate) : data.fields;
const fields: FieldDTO[] = filteredFields.map((f) => {
let values = f.values.toArray();
// The byte buffers serialize like objects
if (values instanceof Float64Array) {
values = vectorToArray(f.values);
}
let values = f.values;
return {
name: f.name,
type: f.type,