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 {AbsoluteFrameIndex} from './index_types'; 18import {Timestamp} from './timestamp'; 19import {Trace} from './trace'; 20import {TraceEntryTypeMap, TraceType} from './trace_type'; 21 22export class Traces { 23 private traces = new Map<TraceType, Trace<{}>>(); 24 25 setTrace<T extends TraceType>(type: T, trace: Trace<TraceEntryTypeMap[T]>) { 26 this.traces.set(type, trace); 27 } 28 29 getTrace<T extends TraceType>(type: T): Trace<TraceEntryTypeMap[T]> | undefined { 30 return this.traces.get(type) as Trace<TraceEntryTypeMap[T]> | undefined; 31 } 32 33 deleteTrace<T extends TraceType>(type: T) { 34 this.traces.delete(type); 35 } 36 37 sliceTime(start?: Timestamp, end?: Timestamp): Traces { 38 const slice = new Traces(); 39 this.traces.forEach((trace, type) => { 40 slice.setTrace(type, trace.sliceTime(start, end)); 41 }); 42 return slice; 43 } 44 45 sliceFrames(start?: AbsoluteFrameIndex, end?: AbsoluteFrameIndex): Traces { 46 const slice = new Traces(); 47 this.traces.forEach((trace, type) => { 48 slice.setTrace(type, trace.sliceFrames(start, end)); 49 }); 50 return slice; 51 } 52 53 forEachTrace(callback: (trace: Trace<{}>, type: TraceType) => void): void { 54 this.traces.forEach((trace, type) => { 55 callback(trace, type); 56 }); 57 } 58 59 mapTrace<T>(callback: (trace: Trace<{}>, type: TraceType) => T): T[] { 60 const result: T[] = []; 61 this.forEachTrace((trace, type) => { 62 result.push(callback(trace, type)); 63 }); 64 return result; 65 } 66 67 forEachFrame(callback: (traces: Traces, index: AbsoluteFrameIndex) => void): void { 68 let startFrameIndex: AbsoluteFrameIndex = Number.MAX_VALUE; 69 let endFrameIndex: AbsoluteFrameIndex = Number.MIN_VALUE; 70 71 this.traces.forEach((trace) => { 72 const framesRange = trace.getFramesRange(); 73 if (framesRange && framesRange.start < framesRange.end) { 74 startFrameIndex = Math.min(startFrameIndex, framesRange.start); 75 endFrameIndex = Math.max(endFrameIndex, framesRange.end); 76 } 77 }); 78 79 for (let i = startFrameIndex; i < endFrameIndex; ++i) { 80 callback(this.sliceFrames(i, i + 1), i); 81 } 82 } 83 84 mapFrame<T>(callback: (traces: Traces, index: AbsoluteFrameIndex) => T): T[] { 85 const result: T[] = []; 86 this.forEachFrame((traces, index) => { 87 result.push(callback(traces, index)); 88 }); 89 return result; 90 } 91 92 getSize(): number { 93 return this.traces.size; 94 } 95 96 [Symbol.iterator]() { 97 return this.traces.values(); 98 } 99} 100