Revision 0535d452dd426ba62d6d312766906ddd1230c7eb authored by Andrey Zhavoronkov on 02 November 2023, 15:59:39 UTC, committed by GitHub on 02 November 2023, 15:59:39 UTC
This PR speeds up the preparation of chunks by: 1. loading images once instead of twice in each writer, 2. as well as by allowing simultaneous preparation of more than 1 chunk using multithreading. This allows to reduce the time for preparation of chunks for 4895 images from 0:04:36 to 0:01:20 in case of preparation of 3 chunks in parallel and 0:02:46 in case of 1 chunk in my environment. Co-authored-by: Maria Khrustaleva <maya17grd@gmail.com>
1 parent 1f8d5d3
analytics-report.ts
// Copyright (C) 2023 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT
import { ArgumentError } from './exceptions';
export interface SerializedDataEntry {
date?: string;
value?: number | Record<string, number>
}
export interface SerializedTransformBinaryOp {
left: string;
operator: string;
right: string;
}
export interface SerializedTransformationEntry {
name: string;
binary?: SerializedTransformBinaryOp;
}
export interface SerializedAnalyticsEntry {
name?: string;
title?: string;
description?: string;
granularity?: string;
default_view?: string;
data_series?: Record<string, SerializedDataEntry[]>;
transformations?: SerializedTransformationEntry[];
}
export interface SerializedAnalyticsReport {
id?: number;
target?: string;
created_date?: string;
statistics?: SerializedAnalyticsEntry[];
}
export enum AnalyticsReportTarget {
JOB = 'job',
TASK = 'task',
PROJECT = 'project',
}
export enum AnalyticsEntryViewType {
HISTOGRAM = 'histogram',
NUMERIC = 'numeric',
}
export class AnalyticsEntry {
#name: string;
#title: string;
#description: string;
#granularity: string;
#defaultView: AnalyticsEntryViewType;
#dataSeries: Record<string, SerializedDataEntry[]>;
#transformations: SerializedTransformationEntry[];
constructor(initialData: SerializedAnalyticsEntry) {
this.#name = initialData.name;
this.#title = initialData.title;
this.#description = initialData.description;
this.#granularity = initialData.granularity;
this.#defaultView = initialData.default_view as AnalyticsEntryViewType;
this.#transformations = initialData.transformations;
this.#dataSeries = this.applyTransformations(initialData.data_series);
}
get name(): string {
return this.#name;
}
get title(): string {
return this.#title;
}
get description(): string {
return this.#description;
}
// Probably need to create enum for this
get granularity(): string {
return this.#granularity;
}
get defaultView(): AnalyticsEntryViewType {
return this.#defaultView;
}
get dataSeries(): Record<string, SerializedDataEntry[]> {
return this.#dataSeries;
}
get transformations(): SerializedTransformationEntry[] {
return this.#transformations;
}
private applyTransformations(
dataSeries: Record<string, SerializedDataEntry[]>,
): Record<string, SerializedDataEntry[]> {
this.#transformations.forEach((transform) => {
if (transform.binary) {
let operator: (left: number, right: number) => number;
switch (transform.binary.operator) {
case '+': {
operator = (left: number, right: number) => left + right;
break;
}
case '-': {
operator = (left: number, right: number) => left - right;
break;
}
case '*': {
operator = (left: number, right: number) => left * right;
break;
}
case '/': {
operator = (left: number, right: number) => (right !== 0 ? left / right : 0);
break;
}
default: {
throw new ArgumentError(
`Cannot apply transformation: got unsupported operator type ${transform.binary.operator}.`,
);
}
}
const leftName = transform.binary.left;
const rightName = transform.binary.right;
dataSeries[transform.name] = dataSeries[leftName].map((left, i) => {
const right = dataSeries[rightName][i];
if (typeof left.value === 'number' && typeof right.value === 'number') {
return {
value: operator(left.value, right.value),
date: left.date,
};
}
return {
value: 0,
date: left.date,
};
});
delete dataSeries[leftName];
delete dataSeries[rightName];
}
});
return dataSeries;
}
}
export default class AnalyticsReport {
#id: number;
#target: AnalyticsReportTarget;
#createdDate: string;
#statistics: AnalyticsEntry[];
constructor(initialData: SerializedAnalyticsReport) {
this.#id = initialData.id;
this.#target = initialData.target as AnalyticsReportTarget;
this.#createdDate = initialData.created_date;
this.#statistics = [];
for (const analyticsEntry of initialData.statistics) {
this.#statistics.push(new AnalyticsEntry(analyticsEntry));
}
}
get id(): number {
return this.#id;
}
get target(): AnalyticsReportTarget {
return this.#target;
}
get createdDate(): string {
return this.#createdDate;
}
get statistics(): AnalyticsEntry[] {
return this.#statistics;
}
}
Computing file changes ...