@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
JavaScript
"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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2FsbFJlbGF0aW9uVHJhY2tlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9oZWxwZXIvSW5zZXJ0Q1BVUHJvZmlsZUhlbHBlci9DYWxsUmVsYXRpb25UcmFja2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQU9BLE1BQWEsbUJBQW1CO0lBcUIvQjtRQUNDLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQW9CLENBQUE7UUFDdkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQTtRQUM1QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksR0FBRyxFQUFtQixDQUFBO1FBQzVDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQTtRQUNsRCxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQTtJQUMvQyxDQUFDO0lBRUQsSUFBSSxHQUFHO1FBQ04sT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFBO0lBQ2pCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsT0FBTztRQUNOLE9BQU8sQ0FDTixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxDQUFDO1lBQ3BCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxLQUFLLENBQUM7WUFDMUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssQ0FBQztZQUMxQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FDaEMsQ0FBQTtJQUNGLENBQUM7SUFFRDs7O09BR0c7SUFDSCx3QkFBd0I7UUFDdkIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFBO0lBQ2hFLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsU0FBUztRQUNSLE9BQU87WUFDTixPQUFPLEVBQUUsSUFBSSxDQUFD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