1/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import {assertTrue} from 'common/assert_utils';
18import {AbsoluteEntryIndex, EntriesRange} from 'trace/trace';
19import {WasmEngineProxy} from 'trace_processor/wasm_engine_proxy';
20import {FakeProto, FakeProtoBuilder} from './fake_proto_builder';
21
22export class Utils {
23  static async queryEntry(
24    traceProcessor: WasmEngineProxy,
25    tableName: string,
26    entryIndexToRowIdMap: number[],
27    entryIndex: AbsoluteEntryIndex,
28  ): Promise<FakeProto> {
29    const rowId = entryIndexToRowIdMap[entryIndex];
30    const sql = `
31      SELECT
32          tbl.id,
33          args.key,
34          args.value_type,
35          args.int_value,
36          args.string_value,
37          args.real_value
38      FROM ${tableName} AS tbl
39      INNER JOIN args ON tbl.arg_set_id = args.arg_set_id
40      WHERE tbl.id = ${rowId};
41    `;
42    const result = await traceProcessor.query(sql).waitAllRows();
43
44    const builder = new FakeProtoBuilder();
45    for (const it = result.iter({}); it.valid(); it.next()) {
46      builder.addArg(
47        it.get('key') as string,
48        it.get('value_type') as string,
49        it.get('int_value') as bigint | undefined,
50        it.get('real_value') as number | undefined,
51        it.get('string_value') as string | undefined,
52      );
53    }
54    return builder.build();
55  }
56
57  static async queryVsyncId(
58    traceProcessor: WasmEngineProxy,
59    tableName: string,
60    entryIndexToRowIdMap: number[],
61    entriesRange: EntriesRange,
62  ): Promise<Array<bigint>> {
63    let minRowId = Number.MAX_VALUE;
64    let maxRowId = Number.MIN_VALUE;
65    for (
66      let entryIndex = entriesRange.start;
67      entryIndex < entriesRange.end;
68      ++entryIndex
69    ) {
70      const rowId = entryIndexToRowIdMap[entryIndex];
71      minRowId = Math.min(minRowId, rowId);
72      maxRowId = Math.max(maxRowId, rowId);
73    }
74
75    const sql = `
76      SELECT
77        tbl.id,
78        args.key,
79        args.value_type,
80        args.int_value
81      FROM ${tableName} AS tbl
82      INNER JOIN args ON tbl.arg_set_id = args.arg_set_id
83      WHERE
84        tbl.id BETWEEN ${minRowId} AND ${maxRowId}
85        AND args.key = 'vsync_id'
86        ORDER BY tbl.id;
87    `;
88
89    const result = await traceProcessor.query(sql).waitAllRows();
90
91    const vsyncIdOrderedByRow: Array<bigint> = [];
92    for (const it = result.iter({}); it.valid(); it.next()) {
93      const value = it.get('int_value') as bigint | undefined;
94      const valueType = it.get('value_type') as string;
95      assertTrue(
96        valueType === 'uint' || valueType === 'int',
97        () => 'expected vsyncid to have integer type',
98      );
99      vsyncIdOrderedByRow.push(value ?? -1n);
100    }
101
102    const vsyncIdOrderedByEntry: Array<bigint> = [];
103    for (
104      let entryIndex = entriesRange.start;
105      entryIndex < entriesRange.end;
106      ++entryIndex
107    ) {
108      const rowId = entryIndexToRowIdMap[entryIndex];
109      const vsyncId = vsyncIdOrderedByRow[rowId - minRowId];
110      vsyncIdOrderedByEntry.push(vsyncId);
111    }
112
113    return vsyncIdOrderedByEntry;
114  }
115}
116