DataFrame: more thorough detection of unsorted values (#51602)

This commit is contained in:
Leon Sorokin 2022-06-29 18:08:42 -05:00 committed by GitHub
parent 739d3469bc
commit 3bd2bdcebb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 23 deletions

View File

@ -625,9 +625,6 @@ exports[`better eslint`] = {
[315, 14, 3, "Unexpected any. Specify a different type.", "193409811"],
[315, 22, 3, "Unexpected any. Specify a different type.", "193409811"]
],
"packages/grafana-data/src/transformations/transformers/joinDataFrames.ts:1554585514": [
[340, 13, 3, "Unexpected any. Specify a different type.", "193409811"]
],
"packages/grafana-data/src/transformations/transformers/labelsToFields.test.ts:1352052528": [
[393, 13, 3, "Unexpected any. Specify a different type.", "193409811"]
],

View File

@ -294,5 +294,19 @@ describe('align frames', () => {
expect(isLikelyAscendingVector(new ArrayVector([7, 6, null]))).toBeFalsy();
expect(isLikelyAscendingVector(new ArrayVector([7, 8, 6]))).toBeFalsy();
});
it('ascending first/last', () => {
expect(isLikelyAscendingVector(new ArrayVector([10, 20, 30, 5, 15, 7, 43, 29, 11]), 3)).toBeFalsy();
expect(
isLikelyAscendingVector(new ArrayVector([null, 10, 20, 30, 5, null, 15, 7, 43, 29, 11, null]), 3)
).toBeFalsy();
});
it('null stuffs', () => {
expect(isLikelyAscendingVector(new ArrayVector([null, null, 1]), 3)).toBeTruthy();
expect(isLikelyAscendingVector(new ArrayVector([1, null, null]), 3)).toBeTruthy();
expect(isLikelyAscendingVector(new ArrayVector([null, null, null]), 3)).toBeTruthy();
expect(isLikelyAscendingVector(new ArrayVector([null, 1, null]), 3)).toBeTruthy();
});
});
});

View File

@ -335,34 +335,46 @@ export function join(tables: AlignedData[], nullModes?: number[][]) {
return data;
}
// Quick test if the first and last points look to be ascending
// Test a few samples to see if the values are ascending
// Only exported for tests
export function isLikelyAscendingVector(data: Vector): boolean {
let first: any = undefined;
export function isLikelyAscendingVector(data: Vector, samples = 50) {
const len = data.length;
for (let idx = 0; idx < data.length; idx++) {
const v = data.get(idx);
if (v != null) {
if (first != null) {
if (first > v) {
return false; // descending
}
break;
}
first = v;
}
// empty or single value
if (len <= 1) {
return true;
}
let idx = data.length - 1;
while (idx >= 0) {
const v = data.get(idx--);
// skip leading & trailing nullish
let firstIdx = 0;
let lastIdx = len - 1;
while (firstIdx <= lastIdx && data.get(firstIdx) == null) {
firstIdx++;
}
while (lastIdx >= firstIdx && data.get(lastIdx) == null) {
lastIdx--;
}
// all nullish or one value surrounded by nullish
if (lastIdx <= firstIdx) {
return true;
}
const stride = Math.max(1, Math.floor((lastIdx - firstIdx + 1) / samples));
for (let prevVal = data.get(firstIdx), i = firstIdx + stride; i <= lastIdx; i += stride) {
const v = data.get(i);
if (v != null) {
if (first > v) {
if (v <= prevVal) {
return false;
}
return true;
prevVal = v;
}
}
return true; // only one non-null point
return true;
}