Chore: Remove the deprecated Vector type (#83469)
This commit is contained in:
@@ -1,27 +0,0 @@
|
||||
import { AppendedVectors } from './AppendedVectors';
|
||||
import { ArrayVector } from './ArrayVector';
|
||||
|
||||
describe('Check Appending Vector', () => {
|
||||
it('should transparently join them', () => {
|
||||
jest.spyOn(console, 'warn').mockImplementation();
|
||||
const appended = new AppendedVectors();
|
||||
appended.append(new ArrayVector([1, 2, 3]));
|
||||
appended.append(new ArrayVector([4, 5, 6]));
|
||||
appended.append(new ArrayVector([7, 8, 9]));
|
||||
expect(appended.length).toEqual(9);
|
||||
expect(appended[0]).toEqual(1);
|
||||
expect(appended[1]).toEqual(2);
|
||||
expect(appended[100]).toEqual(undefined);
|
||||
|
||||
appended.setLength(5);
|
||||
expect(appended.length).toEqual(5);
|
||||
appended.append(new ArrayVector(['a', 'b', 'c']));
|
||||
expect(appended.length).toEqual(8);
|
||||
expect(appended.toArray()).toEqual([1, 2, 3, 4, 5, 'a', 'b', 'c']);
|
||||
|
||||
appended.setLength(2);
|
||||
appended.setLength(6);
|
||||
appended.append(new ArrayVector(['x', 'y', 'z']));
|
||||
expect(appended.toArray()).toEqual([1, 2, undefined, undefined, undefined, undefined, 'x', 'y', 'z']);
|
||||
});
|
||||
});
|
||||
@@ -1,79 +0,0 @@
|
||||
import { Vector, makeArrayIndexableVector } from '../types/vector';
|
||||
|
||||
import { FunctionalVector } from './FunctionalVector';
|
||||
import { vectorToArray } from './vectorToArray';
|
||||
|
||||
interface AppendedVectorInfo<T> {
|
||||
start: number;
|
||||
end: number;
|
||||
values: Vector<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* This may be more trouble than it is worth. This trades some computation time for
|
||||
* RAM -- rather than allocate a new array the size of all previous arrays, this just
|
||||
* points the correct index to their original array values
|
||||
*
|
||||
* @deprecated use a simple Arrays. NOTE this is not used in grafana core
|
||||
*/
|
||||
export class AppendedVectors<T = any> extends FunctionalVector<T> {
|
||||
length = 0;
|
||||
source: Array<AppendedVectorInfo<T>> = [];
|
||||
|
||||
constructor(startAt = 0) {
|
||||
super();
|
||||
this.length = startAt;
|
||||
return makeArrayIndexableVector(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make the vector look like it is this long
|
||||
*/
|
||||
setLength(length: number) {
|
||||
if (length > this.length) {
|
||||
// make the vector longer (filling with undefined)
|
||||
this.length = length;
|
||||
} else if (length < this.length) {
|
||||
// make the array shorter
|
||||
const sources: Array<AppendedVectorInfo<T>> = [];
|
||||
for (const src of this.source) {
|
||||
sources.push(src);
|
||||
if (src.end > length) {
|
||||
src.end = length;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.source = sources;
|
||||
this.length = length;
|
||||
}
|
||||
}
|
||||
|
||||
append(v: Vector<T>): AppendedVectorInfo<T> {
|
||||
const info = {
|
||||
start: this.length,
|
||||
end: this.length + v.length,
|
||||
values: v,
|
||||
};
|
||||
this.length = info.end;
|
||||
this.source.push(info);
|
||||
return info;
|
||||
}
|
||||
|
||||
get(index: number): T {
|
||||
for (let i = 0; i < this.source.length; i++) {
|
||||
const src = this.source[i];
|
||||
if (index >= src.start && index < src.end) {
|
||||
return src.values[index - src.start];
|
||||
}
|
||||
}
|
||||
return undefined as unknown as T;
|
||||
}
|
||||
|
||||
toArray(): T[] {
|
||||
return vectorToArray(this);
|
||||
}
|
||||
|
||||
toJSON(): T[] {
|
||||
return vectorToArray(this);
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import { Field, FieldType } from '../types';
|
||||
|
||||
import { ArrayVector } from './ArrayVector';
|
||||
|
||||
describe('ArrayVector', () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(console, 'warn').mockImplementation();
|
||||
});
|
||||
|
||||
it('should init 150k with 65k Array.push() chonking', () => {
|
||||
const arr = Array.from({ length: 150e3 }, (v, i) => i);
|
||||
const av = new ArrayVector(arr);
|
||||
|
||||
expect(av.toArray()).toEqual(arr);
|
||||
});
|
||||
|
||||
it('should support add and push', () => {
|
||||
const av = new ArrayVector<number>();
|
||||
av.add(1);
|
||||
av.push(2);
|
||||
av.push(3, 4);
|
||||
|
||||
expect(av.toArray()).toEqual([1, 2, 3, 4]);
|
||||
});
|
||||
|
||||
it('typescript should not re-define the ArrayVector<T> based on input to the constructor', () => {
|
||||
const field: Field<number> = {
|
||||
name: 'test',
|
||||
config: {},
|
||||
type: FieldType.number,
|
||||
values: new ArrayVector(), // this defaults to `new ArrayVector<any>()`
|
||||
};
|
||||
expect(field).toBeDefined();
|
||||
|
||||
// Before collapsing Vector, ReadWriteVector, and MutableVector these all worked fine
|
||||
field.values = new ArrayVector();
|
||||
field.values = new ArrayVector(undefined);
|
||||
field.values = new ArrayVector([1, 2, 3]);
|
||||
field.values = new ArrayVector([]);
|
||||
field.values = new ArrayVector([1, undefined]);
|
||||
field.values = new ArrayVector([null]);
|
||||
field.values = new ArrayVector(['a', 'b', 'c']);
|
||||
expect(field.values.length).toBe(3);
|
||||
});
|
||||
});
|
||||
@@ -1,46 +0,0 @@
|
||||
const notice = 'ArrayVector is deprecated and will be removed in Grafana 11. Please use plain arrays for field.values.';
|
||||
let notified = false;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*
|
||||
* @deprecated use a simple Array<T>
|
||||
*/
|
||||
export class ArrayVector<T = any> extends Array<T> {
|
||||
get buffer() {
|
||||
return this;
|
||||
}
|
||||
|
||||
set buffer(values: any[]) {
|
||||
this.length = 0;
|
||||
|
||||
const len = values?.length;
|
||||
|
||||
if (len) {
|
||||
let chonkSize = 65e3;
|
||||
let numChonks = Math.ceil(len / chonkSize);
|
||||
|
||||
for (let chonkIdx = 0; chonkIdx < numChonks; chonkIdx++) {
|
||||
this.push.apply(this, values.slice(chonkIdx * chonkSize, (chonkIdx + 1) * chonkSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This any type is here to make the change type changes in v10 non breaking for plugins.
|
||||
* Before you could technically assign field.values any typed ArrayVector no matter what the Field<T> T type was.
|
||||
*/
|
||||
constructor(buffer?: any[]) {
|
||||
super();
|
||||
this.buffer = buffer ?? [];
|
||||
|
||||
if (!notified) {
|
||||
console.warn(notice);
|
||||
notified = true;
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(): T[] {
|
||||
return [...this]; // copy to avoid circular reference (only for jest)
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { Vector } from '../types';
|
||||
|
||||
/**
|
||||
* This will force all values to be numbers
|
||||
*
|
||||
* @public
|
||||
* @deprecated use a simple Arrays. NOTE: Not used in grafana core
|
||||
*/
|
||||
export class AsNumberVector extends Array<number> {
|
||||
constructor(field: Vector) {
|
||||
super();
|
||||
return field.map((v) => +v);
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import { binaryOperators, BinaryOperationID } from '../utils/binaryOperators';
|
||||
|
||||
import { ArrayVector } from './ArrayVector';
|
||||
import { BinaryOperationVector } from './BinaryOperationVector';
|
||||
import { ConstantVector } from './ConstantVector';
|
||||
|
||||
describe('ScaledVector', () => {
|
||||
it('should support multiply operations', () => {
|
||||
jest.spyOn(console, 'warn').mockImplementation();
|
||||
const source = new ArrayVector([1, 2, 3, 4]);
|
||||
const scale = 2.456;
|
||||
const operation = binaryOperators.get(BinaryOperationID.Multiply).operation;
|
||||
const v = new BinaryOperationVector(source, new ConstantVector(scale, source.length), operation);
|
||||
expect(v.length).toEqual(source.length);
|
||||
// Accessed with getters
|
||||
for (let i = 0; i < 4; i++) {
|
||||
expect(v.get(i)).toEqual(source.get(i) * scale);
|
||||
}
|
||||
// Accessed with array index
|
||||
for (let i = 0; i < 4; i++) {
|
||||
expect(v[i]).toEqual(source[i] * scale);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Vector } from '../types/vector';
|
||||
import { BinaryOperation } from '../utils/binaryOperators';
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated use a simple Arrays. NOTE: Not used in grafana core
|
||||
*/
|
||||
export class BinaryOperationVector extends Array<number> {
|
||||
constructor(left: Vector<number>, right: Vector<number>, operation: BinaryOperation) {
|
||||
super();
|
||||
|
||||
const arr = new Array(left.length);
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
arr[i] = operation(left[i], right[i]);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
import { makeArrayIndexableVector } from '../types';
|
||||
|
||||
import { FunctionalVector } from './FunctionalVector';
|
||||
|
||||
interface CircularOptions<T> {
|
||||
@@ -36,7 +34,27 @@ export class CircularVector<T = any> extends FunctionalVector<T> {
|
||||
if (options.capacity) {
|
||||
this.setCapacity(options.capacity);
|
||||
}
|
||||
return makeArrayIndexableVector(this);
|
||||
return new Proxy(this, {
|
||||
get(target: CircularVector<T>, property: string, receiver: CircularVector<T>) {
|
||||
if (typeof property !== 'symbol') {
|
||||
const idx = +property;
|
||||
if (String(idx) === property) {
|
||||
return target.get(idx);
|
||||
}
|
||||
}
|
||||
return Reflect.get(target, property, receiver);
|
||||
},
|
||||
set(target: CircularVector<T>, property: string, value: T, receiver: CircularVector<T>) {
|
||||
if (typeof property !== 'symbol') {
|
||||
const idx = +property;
|
||||
if (String(idx) === property) {
|
||||
target.set(idx, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Reflect.set(target, property, value, receiver);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { ConstantVector } from './ConstantVector';
|
||||
|
||||
describe('ConstantVector', () => {
|
||||
it('should support constant values', () => {
|
||||
const value = 3.5;
|
||||
const v = new ConstantVector(value, 7);
|
||||
expect(v.length).toEqual(7);
|
||||
|
||||
expect(v.get(0)).toEqual(value);
|
||||
expect(v.get(1)).toEqual(value);
|
||||
|
||||
// Now check all of them
|
||||
for (let i = 0; i < 7; i++) {
|
||||
expect(v.get(i)).toEqual(value);
|
||||
expect(v[i]).toEqual(value);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
/**
|
||||
* @public
|
||||
* @deprecated use a simple Arrays. NOTE: Not used in grafana core.
|
||||
*/
|
||||
export class ConstantVector<T = any> extends Array<T> {
|
||||
constructor(value: T, len: number) {
|
||||
super();
|
||||
return new Array<T>(len).fill(value);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { DisplayProcessor } from '../types';
|
||||
import { Vector } from '../types/vector';
|
||||
import { formattedValueToString } from '../valueFormats';
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated use a simple Arrays. NOTE: not used in grafana core.
|
||||
*/
|
||||
export class FormattedVector<T = any> extends Array<string> {
|
||||
constructor(source: Vector<T>, formatter: DisplayProcessor) {
|
||||
super();
|
||||
return source.map((v) => formattedValueToString(formatter(v)));
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
import { Vector } from '../types';
|
||||
|
||||
import { vectorToArray } from './vectorToArray';
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export abstract class FunctionalVector<T = any> implements Vector<T> {
|
||||
export abstract class FunctionalVector<T = unknown> {
|
||||
abstract get length(): number;
|
||||
|
||||
abstract get(index: number): T;
|
||||
@@ -55,7 +51,11 @@ export abstract class FunctionalVector<T = any> implements Vector<T> {
|
||||
}
|
||||
|
||||
toArray(): T[] {
|
||||
return vectorToArray(this);
|
||||
const arr = new Array<T>(this.length);
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
arr[i] = this.get(i);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
join(separator?: string | undefined): string {
|
||||
@@ -183,7 +183,7 @@ const emptyarray: any[] = [];
|
||||
*
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export function vectorator<T>(vector: Vector<T>) {
|
||||
function vectorator<T>(vector: FunctionalVector<T>) {
|
||||
return {
|
||||
*[Symbol.iterator]() {
|
||||
for (let i = 0; i < vector.length; i++) {
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import { Field, FieldType } from '../types';
|
||||
|
||||
/**
|
||||
* IndexVector is a simple vector implementation that returns the index value
|
||||
* for each element in the vector. It is functionally equivolant a vector backed
|
||||
* by an array with values: `[0,1,2,...,length-1]`
|
||||
*
|
||||
* @deprecated use a simple Arrays. NOTE: not used in grafana core
|
||||
*/
|
||||
export class IndexVector extends Array<number> {
|
||||
constructor(len: number) {
|
||||
super();
|
||||
const arr = new Array(len);
|
||||
for (let i = 0; i < len; i++) {
|
||||
arr[i] = i;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a field representing the range [0 ... length-1]
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
static newField(len: number): Field<number> {
|
||||
return {
|
||||
name: '',
|
||||
values: new IndexVector(len),
|
||||
type: FieldType.number,
|
||||
config: {
|
||||
min: 0,
|
||||
max: len - 1,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { ArrayVector } from './ArrayVector';
|
||||
import { SortedVector } from './SortedVector';
|
||||
|
||||
describe('SortedVector', () => {
|
||||
it('Should support sorting', () => {
|
||||
jest.spyOn(console, 'warn').mockImplementation();
|
||||
const values = new ArrayVector([1, 5, 2, 4]);
|
||||
const sorted = new SortedVector(values, [0, 2, 3, 1]);
|
||||
expect(sorted.toArray()).toEqual([1, 2, 4, 5]);
|
||||
|
||||
// The proxy should still be an instance of SortedVector (used in timeseries)
|
||||
expect(sorted instanceof SortedVector).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,39 +0,0 @@
|
||||
import { makeArrayIndexableVector, Vector } from '../types/vector';
|
||||
|
||||
import { FunctionalVector } from './FunctionalVector';
|
||||
import { vectorToArray } from './vectorToArray';
|
||||
|
||||
/**
|
||||
* Values are returned in the order defined by the input parameter
|
||||
*
|
||||
* @deprecated use a simple Arrays
|
||||
*/
|
||||
export class SortedVector<T = any> extends FunctionalVector<T> {
|
||||
constructor(
|
||||
private source: Vector<T>,
|
||||
private order: number[]
|
||||
) {
|
||||
super();
|
||||
return makeArrayIndexableVector(this);
|
||||
}
|
||||
|
||||
get length(): number {
|
||||
return this.source.length;
|
||||
}
|
||||
|
||||
get(index: number): T {
|
||||
return this.source.get(this.order[index]);
|
||||
}
|
||||
|
||||
toArray(): T[] {
|
||||
return vectorToArray(this);
|
||||
}
|
||||
|
||||
toJSON(): T[] {
|
||||
return vectorToArray(this);
|
||||
}
|
||||
|
||||
getOrderArray(): number[] {
|
||||
return this.order;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
export * from './AppendedVectors';
|
||||
export * from './ArrayVector';
|
||||
export * from './CircularVector';
|
||||
export * from './ConstantVector';
|
||||
export * from './BinaryOperationVector';
|
||||
export * from './SortedVector';
|
||||
export * from './FormattedVector';
|
||||
export * from './IndexVector';
|
||||
export * from './AsNumberVector';
|
||||
|
||||
export { vectorator } from './FunctionalVector';
|
||||
@@ -1,10 +0,0 @@
|
||||
import { Vector } from '../types/vector';
|
||||
|
||||
/** @deprecated use a simple Arrays */
|
||||
export function vectorToArray<T>(v: Vector<T>): T[] {
|
||||
const arr: T[] = Array(v.length);
|
||||
for (let i = 0; i < v.length; i++) {
|
||||
arr[i] = v.get(i);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
Reference in New Issue
Block a user