UNPKG

@oaklean/profiler-core

Version:

Part of the @oaklean suite. It provides all basic functions to work with the `.oak` file format. It allows parsing the `.oak` file format as well as tools for analyzing the measurement values. It also provides all necessary capabilities required for prec

200 lines 13.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CallRelationTracker = void 0; class CallRelationTracker { constructor() { this._map = new Map(); this._internMap = new Map(); this._externMap = new Map(); this._langInternalMap = new Map(); this._compensationLayerSet = new Set(); } get map() { return this._map; } /** * Check if the tracker is empty * * @returns {boolean} true if the tracker is empty, false otherwise */ isEmpty() { return (this._map.size === 0 && this._internMap.size === 0 && this._externMap.size === 0 && this._langInternalMap.size === 0); } /** * Check if the tracker is currently in a headless scope. * Meaning that no intern or extern calls were made yet. */ currentlyInHeadlessScope() { return this._internMap.size === 0 && this._externMap.size === 0; } /** * Returns debug information about the tracker. * * @returns {object} debug information about the tracker */ debugInfo() { return { mapSize: this._map.size, internMapSize: this._internMap.size, externMapSize: this._externMap.size, langInternalMapSize: this._langInternalMap.size }; } /** * Remove the last child record from a call. * Is used to remove the last child from a parent call after the child has been traversed. * * @param {CallIdentifier} callIdentifier - The call identifier * @returns {boolean} true if the child was removed, false otherwise */ removeLastChildRecord(callIdentifier) { const mapEntry = this._map.get(callIdentifier.toString()); if (mapEntry === undefined || mapEntry.children.length === 0) { return false; } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const lastChildIdentifier = mapEntry.children.pop(); // remove last child from parent const numberOfLinks = mapEntry.linkCountToChild.get(lastChildIdentifier) || 0; if (numberOfLinks > 1) { // reduce the number of links between parent and child mapEntry.linkCountToChild.set(lastChildIdentifier, numberOfLinks - 1); } else { // no more links between parent and child, remove counter mapEntry.linkCountToChild.delete(lastChildIdentifier); } return true; } /** * Checks if a function call has child calls recorded (used in recursion tracking). * * @param {CallIdentifier} callIdentifier - The call identifier * @returns {boolean} true if the call identifier was already visited, false otherwise */ isCallRecorded(callIdentifier) { return this._map.has(callIdentifier.toString()); } /** * Gives the amount of recorded child calls for a function call. * * @param {CallIdentifier} callIdentifier - The call identifier * @returns {number} the number of child calls */ getNumberOfChildren(callIdentifier) { const mapEntry = this._map.get(callIdentifier.toString()); if (mapEntry === undefined) { return 0; } return mapEntry.children.length; } /** * Gives the amount of recorded links between two function calls. * * @param {CallIdentifier} parentCallIdentifier - the caller's call identifier * @param {CallIdentifier} childCallIdentifier - the callee's call identifier * @returns {number} the number of links between the two calls */ getNumberOfLinksBetweenCalls(parentCallIdentifier, childCallIdentifier) { const childCalls = this._map.get(parentCallIdentifier.toString()); if (childCalls === undefined) { return 0; } const childCallIdentifierString = childCallIdentifier.toString(); const numberOfLinks = childCalls.linkCountToChild.get(childCallIdentifierString); if (numberOfLinks === undefined) { return 0; } return numberOfLinks; } /** * Removes all references to a function call (for cleanup). * * @param {CallIdentifier} callIdentifier - The call identifier */ removeCallRecord(callIdentifier) { const callIdentifierString = callIdentifier.toString(); this._internMap.delete(callIdentifierString); this._externMap.delete(callIdentifierString); this._langInternalMap.delete(callIdentifierString); this._map.delete(callIdentifierString); } /** * Ensures that the function call is tracked in the compensation layer. * * @param {CallIdentifier} callIdentifier - The call identifier * @returns {boolean} true: first time in this compensation layer, false: already present */ initializeInCompensationLayerIfAbsent(callIdentifier) { const compensationLayerString = callIdentifier.toCompensationLayerString(); if (this._compensationLayerSet.has(compensationLayerString)) { return false; } this._compensationLayerSet.add(compensationLayerString); return true; } /** * Removes a function call from a specific compensation layer. * * @param {CallIdentifier} callIdentifier - The call identifier */ removeCompensationLayerRecord(callIdentifier) { this._compensationLayerSet.delete(callIdentifier.toCompensationLayerString()); } /** * Ensures that a function call entry exists in the tracker. * * @param {CallIdentifier} callIdentifier - The call identifier * @param {string} kind - The kind of the call (intern, extern, langInternal) * @returns {boolean} true if the call was initialized, false if it was already present */ initializeCallNodeIfAbsent(callIdentifier, kind) { if (!this.isCallRecorded(callIdentifier)) { const callIdentifierString = callIdentifier.toString(); this._map.set(callIdentifierString, { children: [], linkCountToChild: new Map() }); switch (kind) { case 'intern': this._internMap.set(callIdentifierString, true); break; case 'extern': this._externMap.set(callIdentifierString, true); break; case 'langInternal': this._langInternalMap.set(callIdentifierString, true); break; } return true; } return false; } /** * Registers a function call as a child of another call. * * @param {CallIdentifier} self - The call identifier of the child call * @param {CallIdentifier} parent - The call identifier of the parent call * @returns wether the link already existed */ linkCallToParent(self, parent) { const selfCallIdentifierString = self.toString(); const parentCallIdentifierString = parent.toString(); let previousEntry = this._map.get(parentCallIdentifierString); if (previousEntry === undefined) { previousEntry = { children: [], linkCountToChild: new Map() }; this._map.set(parentCallIdentifierString, previousEntry); } previousEntry.children.push(selfCallIdentifierString); const numberOfExistingLinks = previousEntry.linkCountToChild.get(selfCallIdentifierString) || 0; previousEntry.linkCountToChild.set(selfCallIdentifierString, numberOfExistingLinks + 1); return numberOfExistingLinks > 0; } } exports.CallRelationTracker = CallRelationTracker; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2FsbFJlbGF0aW9uVHJhY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9oZWxwZXIvSW5zZXJ0Q1BVUHJvZmlsZUhlbHBlci9DYWxsUmVsYXRpb25UcmFja2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQU9BLE1BQWEsbUJBQW1CO0lBcUIvQjtRQUNDLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUE7UUFDdkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQTtRQUM1QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksR0FBRyxFQUFtQixDQUFBO1FBQzVDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQTtRQUNsRCxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQTtJQUMvQyxDQUFDO0lBRUQsSUFBSSxHQUFHO1FBQ04sT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFBO0lBQ2pCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsT0FBTztRQUNOLE9BQU8sQ0FDTixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDO1lBQ3BCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLENBQUM7WUFDMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssQ0FBQztZQUMxQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FDaEMsQ0FBQTtJQUNGLENBQUM7SUFFRDs7O09BR0c7SUFDSCx3QkFBd0I7UUFDdkIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFBO0lBQ2hFLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsU0FBUztRQUNSLE9BQU87WUFDTixPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJO1lBQ3ZCLGFBQWEsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUk7WUFDbkMsYUFBYSxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSTtZQUNuQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSTtTQUMvQyxDQUFBO0lBQ0YsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILHFCQUFxQixDQUFDLGNBQThCO1FBQ25ELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFBO1FBQ3pELElBQUksUUFBUSxLQUFLLFNBQVMsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM5RCxPQUFPLEtBQUssQ0FBQTtRQUNiLENBQUM7UUFDRCxvRUFBb0U7UUFDcEUsTUFBTSxtQkFBbUIsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRyxDQUFBLENBQUMsZ0NBQWdDO1FBQ3JGLE1BQU0sYUFBYSxHQUNsQixRQUFRLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ3hELElBQUksYUFBYSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLHNEQUFzRDtZQUN0RCxRQUFRLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFFLGFBQWEsR0FBRyxDQUFDLENBQUMsQ0FBQTtRQUN0RSxDQUFDO2FBQU0sQ0FBQztZQUNQLHlEQUF5RDtZQUN6RCxRQUFRLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUE7UUFDdEQsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFBO0lBQ1osQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsY0FBYyxDQUFDLGNBQThCO1FBQzVDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUE7SUFDaEQsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsbUJBQW1CLENBQUMsY0FBOEI7UUFDakQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUE7UUFDekQsSUFBSSxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDNUIsT0FBTyxDQUFDLENBQUE7UUFDVCxDQUFDO1FBQ0QsT0FBTyxRQUFRLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQTtJQUNoQyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsNEJBQTRCLENBQzNCLG9CQUFvQyxFQUNwQyxtQkFBbUM7UUFFbkMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQTtRQUNqRSxJQUFJLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM5QixPQUFPLENBQUMsQ0FBQTtRQUNULENBQUM7UUFDRCxNQUFNLHlCQUF5QixHQUFHLG1CQUFtQixDQUFDLFFBQVEsRUFBRSxDQUFBO1FBQ2hFLE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQ3BELHlCQUF5QixDQUN6QixDQUFBO1FBQ0QsSUFBSSxhQUFhLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDakMsT0FBTyxDQUFDLENBQUE7UUFDVCxDQUFDO1FBQ0QsT0FBTyxhQUFhLENBQUE7SUFDckIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxnQkFBZ0IsQ0FBQyxjQUE4QjtRQUM5QyxNQUFNLG9CQUFvQixHQUFHLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQTtRQUN0RCxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFBO1FBQzVDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUE7UUFDNUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFBO1FBQ2xELElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLG9CQUFvQixDQUFDLENBQUE7SUFDdkMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gscUNBQXFDLENBQUMsY0FBOEI7UUFDbkUsTUFBTSx1QkFBdUIsR0FBRyxjQUFjLENBQUMseUJBQXlCLEVBQUUsQ0FBQTtRQUMxRSxJQUFJLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUMsRUFBRSxDQUFDO1lBQzdELE9BQU8sS0FBSyxDQUFBO1FBQ2IsQ0FBQztRQUNELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUMsQ0FBQTtRQUN2RCxPQUFPLElBQUksQ0FBQTtJQUNaLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsNkJBQTZCLENBQUMsY0FBOEI7UUFDM0QsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FDaEMsY0FBYyxDQUFDLHlCQUF5QixFQUFFLENBQzFDLENBQUE7SUFDRixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsMEJBQTBCLENBQ3pCLGNBQThCLEVBQzlCLElBQTBDO1FBRTFDLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDMUMsTUFBTSxvQkFBb0IsR0FBRyxjQUFjLENBQUMsUUFBUSxFQUFFLENBQUE7WUFDdEQsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUU7Z0JBQ25DLFFBQVEsRUFBRSxFQUFFO2dCQUNaLGdCQUFnQixFQUFFLElBQUksR0FBRyxFQUFrQjthQUMzQyxDQUFDLENBQUE7WUFDRixRQUFRLElBQUksRUFBRSxDQUFDO2dCQUNkLEtBQUssUUFBUTtvQkFDWixJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxJQUFJLENBQUMsQ0FBQTtvQkFDL0MsTUFBSztnQkFDTixLQUFLLFFBQVE7b0JBQ1osSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLENBQUE7b0JBQy9DLE1BQUs7Z0JBQ04sS0FBSyxjQUFjO29CQUNsQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLG9CQUFvQixFQUFFLElBQUksQ0FBQyxDQUFBO29CQUNyRCxNQUFLO1lBQ1AsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFBO1FBQ1osQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2IsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGdCQUFnQixDQUFDLElBQW9CLEVBQUUsTUFBc0I7UUFDNUQsTUFBTSx3QkFBd0IsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUE7UUFDaEQsTUFBTSwwQkFBMEIsR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUE7UUFFcEQsSUFBSSxhQUFhLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsMEJBQTBCLENBQUMsQ0FBQTtRQUM3RCxJQUFJLGFBQWEsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNqQyxhQUFhLEdBQUc7Z0JBQ2YsUUFBUSxFQUFFLEVBQUU7Z0JBQ1osZ0JBQWdCLEVBQUUsSUFBSSxHQUFHLEVBQWtCO2FBQzNDLENBQUE7WUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsRUFBRSxhQUFhLENBQUMsQ0FBQTtRQUN6RCxDQUFDO1FBQ0QsYUFBYSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQTtRQUNyRCxNQUFNLHFCQUFxQixHQUMxQixhQUFhLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ2xFLGFBQWEsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQ2pDLHdCQUF3QixFQUN4QixxQkFBcUIsR0FBRyxDQUFDLENBQ3pCLENBQUE7UUFDRCxPQUFPLHFCQUFxQixHQUFHLENBQUMsQ0FBQTtJQUNqQyxDQUFDO0NBQ0Q7QUFyUEQsa0RBcVBDIn0=