Transformations: Take nanos into account for Sort by (#108564)
* chore(sortDataFrame): sort by nanos
This commit is contained in:
@@ -388,6 +388,59 @@ describe('sorted DataFrame', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('sorted DataFrame by nanos', () => {
|
||||
it('Should sort nanos with numeric timestamp', () => {
|
||||
const frame = toDataFrame({
|
||||
fields: [
|
||||
{ name: 'first', type: FieldType.time, values: [1, 1, 2, 2, 3, 3], nanos: [100, 102, 1, 2, 1000, 999] },
|
||||
{ name: 'second', type: FieldType.string, values: ['a', 'b', 'c', 'd', 'e', 'f'] },
|
||||
],
|
||||
});
|
||||
|
||||
const sorted = sortDataFrame(frame, 0, true);
|
||||
expect(sorted.length).toEqual(6);
|
||||
expect(sorted.fields[0].values).toEqual([3, 3, 2, 2, 1, 1]);
|
||||
expect(sorted.fields[1].values).toEqual(['e', 'f', 'd', 'c', 'b', 'a']);
|
||||
});
|
||||
|
||||
it('Should sort by nanos with dateTime timestamp', () => {
|
||||
const frame = toDataFrame({
|
||||
fields: [
|
||||
{
|
||||
name: 'first',
|
||||
type: FieldType.time,
|
||||
values: [dateTime(50), dateTime(50), dateTime(100)],
|
||||
nanos: [1, 0, 100],
|
||||
},
|
||||
{ name: 'second', type: FieldType.string, values: ['a', 'b', 'c'] },
|
||||
],
|
||||
});
|
||||
|
||||
const sorted = sortDataFrame(frame, 0);
|
||||
expect(sorted.length).toEqual(3);
|
||||
expect(sorted.fields[0].values).toEqual([dateTime(50), dateTime(50), dateTime(100)]);
|
||||
expect(sorted.fields[1].values).toEqual(['b', 'a', 'c']);
|
||||
});
|
||||
|
||||
// Not sure if we expect nanos to exist on any field type besides time fields, but the schema allows it.
|
||||
// Keep in mind if sorting by a non time field, the nanos is expected to present on the field that is being sorted
|
||||
it('Should sort by nanos with string timestamp', () => {
|
||||
const frame = toDataFrame({
|
||||
fields: [
|
||||
{ name: 'fist', type: FieldType.time, values: [1, 2, 3, 3] },
|
||||
{ name: 'second', type: FieldType.string, values: ['a', 'b', 'b', 'c'], nanos: [100, 0, 1, 0] },
|
||||
{ name: 'third', type: FieldType.number, values: [2000, 3000, 1000] },
|
||||
],
|
||||
});
|
||||
|
||||
const sorted = sortDataFrame(frame, 1, true);
|
||||
expect(sorted.length).toEqual(4);
|
||||
expect(sorted.fields[0].values).toEqual([3, 2, 3, 1]);
|
||||
expect(sorted.fields[0].nanos).toBeUndefined();
|
||||
expect(sorted.fields[1].values).toEqual(['c', 'b', 'b', 'a']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('reverse DataFrame', () => {
|
||||
const frame = toDataFrame({
|
||||
fields: [
|
||||
|
||||
@@ -17,9 +17,9 @@ export const fieldIndexComparer = (field: Field, reverse = false): IndexComparer
|
||||
return booleanIndexComparer(values, reverse);
|
||||
case FieldType.time:
|
||||
if (typeof field.values[0] === 'number') {
|
||||
return timestampIndexComparer(values, reverse);
|
||||
return timestampIndexComparer(values, reverse, field.nanos);
|
||||
}
|
||||
return timeIndexComparer(values, reverse);
|
||||
return timeIndexComparer(values, reverse, field.nanos);
|
||||
default:
|
||||
return naturalIndexComparer(reverse);
|
||||
}
|
||||
@@ -79,17 +79,24 @@ const falsyComparer = (a: unknown, b: unknown): number => {
|
||||
return 0;
|
||||
};
|
||||
|
||||
const timestampIndexComparer = (values: number[], reverse: boolean): IndexComparer => {
|
||||
const timestampIndexComparer = (values: number[], reverse: boolean, nanos?: number[]): IndexComparer => {
|
||||
let mult = reverse ? -1 : 1;
|
||||
|
||||
if (nanos !== undefined) {
|
||||
return (a: number, b: number): number => mult * (values[a] - values[b] || nanos[a] - nanos[b]);
|
||||
}
|
||||
|
||||
return (a: number, b: number): number => mult * (values[a] - values[b]);
|
||||
};
|
||||
|
||||
const timeIndexComparer = (values: unknown[], reverse: boolean): IndexComparer => {
|
||||
return (a: number, b: number): number => {
|
||||
const vA = values[a];
|
||||
const vB = values[b];
|
||||
return reverse ? timeComparer(vB, vA) : timeComparer(vA, vB);
|
||||
};
|
||||
const timeIndexComparer = (values: unknown[], reverse: boolean, nanos?: number[]): IndexComparer => {
|
||||
const mult = reverse ? -1 : 1;
|
||||
|
||||
if (nanos !== undefined) {
|
||||
return (a: number, b: number): number => mult * (timeComparer(values[a], values[b]) || nanos[a] - nanos[b]);
|
||||
}
|
||||
|
||||
return (a: number, b: number): number => mult * timeComparer(values[a], values[b]);
|
||||
};
|
||||
|
||||
const booleanIndexComparer = (values: boolean[], reverse: boolean): IndexComparer => {
|
||||
|
||||
Reference in New Issue
Block a user