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

409 lines 41.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SensorValues = exports.LANG_INTERNAL_SENSOR_VALUE_NAMES = exports.EXTERN_SENSOR_VALUE_NAMES = exports.INTERN_SENSOR_VALUE_NAMES = exports.AGGREGATED_SENSOR_VALUE_NAMES = exports.SENSOR_VALUES_BYTE_SIZE_MAP = void 0; const BaseModel_1 = require("./BaseModel"); const BufferHelper_1 = require("../helper/BufferHelper"); // Types const types_1 = require("../types"); const UnitHelper_1 = require("../helper/UnitHelper"); exports.SENSOR_VALUES_BYTE_SIZE_MAP = { profilerHits: types_1.PrimitiveBufferTypes.UInt, selfCPUTime: types_1.PrimitiveBufferTypes.UInt, aggregatedCPUTime: types_1.PrimitiveBufferTypes.UInt, internCPUTime: types_1.PrimitiveBufferTypes.UInt, externCPUTime: types_1.PrimitiveBufferTypes.UInt, langInternalCPUTime: types_1.PrimitiveBufferTypes.UInt, selfCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double, aggregatedCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double, internCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double, externCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double, langInternalCPUEnergyConsumption: types_1.PrimitiveBufferTypes.Double, selfRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double, aggregatedRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double, internRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double, externRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double, langInternalRAMEnergyConsumption: types_1.PrimitiveBufferTypes.Double, }; exports.AGGREGATED_SENSOR_VALUE_NAMES = [ 'aggregatedCPUTime', 'aggregatedCPUEnergyConsumption', 'aggregatedRAMEnergyConsumption' ]; exports.INTERN_SENSOR_VALUE_NAMES = [ 'internCPUTime', 'internCPUEnergyConsumption', 'internRAMEnergyConsumption' ]; exports.EXTERN_SENSOR_VALUE_NAMES = [ 'externCPUTime', 'externCPUEnergyConsumption', 'externRAMEnergyConsumption' ]; exports.LANG_INTERNAL_SENSOR_VALUE_NAMES = [ 'langInternalCPUTime', 'langInternalCPUEnergyConsumption', 'langInternalRAMEnergyConsumption' ]; class SensorValues extends BaseModel_1.BaseModel { constructor({ profilerHits, selfCPUTime, aggregatedCPUTime, internCPUTime, externCPUTime, langInternalCPUTime, selfCPUEnergyConsumption, aggregatedCPUEnergyConsumption, internCPUEnergyConsumption, externCPUEnergyConsumption, langInternalCPUEnergyConsumption, selfRAMEnergyConsumption, aggregatedRAMEnergyConsumption, internRAMEnergyConsumption, externRAMEnergyConsumption, langInternalRAMEnergyConsumption }) { super(); this._profilerHits = profilerHits; this._selfCPUTime = selfCPUTime; this._aggregatedCPUTime = aggregatedCPUTime; this._internCPUTime = internCPUTime; this._externCPUTime = externCPUTime; this._langInternalCPUTime = langInternalCPUTime; this._selfCPUEnergyConsumption = selfCPUEnergyConsumption; this._aggregatedCPUEnergyConsumption = aggregatedCPUEnergyConsumption; this._internCPUEnergyConsumption = internCPUEnergyConsumption; this._externCPUEnergyConsumption = externCPUEnergyConsumption; this._langInternalCPUEnergyConsumption = langInternalCPUEnergyConsumption; this._selfRAMEnergyConsumption = selfRAMEnergyConsumption; this._aggregatedRAMEnergyConsumption = aggregatedRAMEnergyConsumption; this._internRAMEnergyConsumption = internRAMEnergyConsumption; this._externRAMEnergyConsumption = externRAMEnergyConsumption; this._langInternalRAMEnergyConsumption = langInternalRAMEnergyConsumption; } set profilerHits(v) { this._profilerHits = v; } get profilerHits() { return this._profilerHits || 0; } // CPU Time set selfCPUTime(v) { this._selfCPUTime = v; } get selfCPUTime() { return this._selfCPUTime || 0; } set aggregatedCPUTime(v) { this._aggregatedCPUTime = v; } get aggregatedCPUTime() { return this._aggregatedCPUTime || 0; } set internCPUTime(v) { this._internCPUTime = v; } get internCPUTime() { return this._internCPUTime || 0; } set externCPUTime(v) { this._externCPUTime = v; } get externCPUTime() { return this._externCPUTime || 0; } set langInternalCPUTime(v) { this._langInternalCPUTime = v; } get langInternalCPUTime() { return this._langInternalCPUTime || 0; } // CPU Energy set selfCPUEnergyConsumption(v) { this._selfCPUEnergyConsumption = v; } get selfCPUEnergyConsumption() { return this._selfCPUEnergyConsumption || 0; } set aggregatedCPUEnergyConsumption(v) { this._aggregatedCPUEnergyConsumption = v; } get aggregatedCPUEnergyConsumption() { return this._aggregatedCPUEnergyConsumption || 0; } set internCPUEnergyConsumption(v) { this._internCPUEnergyConsumption = v; } get internCPUEnergyConsumption() { return this._internCPUEnergyConsumption || 0; } set externCPUEnergyConsumption(v) { this._externCPUEnergyConsumption = v; } get externCPUEnergyConsumption() { return this._externCPUEnergyConsumption || 0; } set langInternalCPUEnergyConsumption(v) { this._langInternalCPUEnergyConsumption = v; } get langInternalCPUEnergyConsumption() { return this._langInternalCPUEnergyConsumption || 0; } // RAM Energy set selfRAMEnergyConsumption(v) { this._selfRAMEnergyConsumption = v; } get selfRAMEnergyConsumption() { return this._selfRAMEnergyConsumption || 0; } set aggregatedRAMEnergyConsumption(v) { this._aggregatedRAMEnergyConsumption = v; } get aggregatedRAMEnergyConsumption() { return this._aggregatedRAMEnergyConsumption || 0; } set internRAMEnergyConsumption(v) { this._internRAMEnergyConsumption = v; } get internRAMEnergyConsumption() { return this._internRAMEnergyConsumption || 0; } set externRAMEnergyConsumption(v) { this._externRAMEnergyConsumption = v; } get externRAMEnergyConsumption() { return this._externRAMEnergyConsumption || 0; } set langInternalRAMEnergyConsumption(v) { this._langInternalRAMEnergyConsumption = v; } get langInternalRAMEnergyConsumption() { return this._langInternalRAMEnergyConsumption || 0; } validate(path, identifier) { const valid = (this.profilerHits >= 0 && this.selfCPUTime >= 0 && this.aggregatedCPUTime >= 0 && this.internCPUTime >= 0 && this.externCPUTime >= 0 && this.langInternalCPUTime >= 0 && this.selfCPUEnergyConsumption >= 0 && this.aggregatedCPUEnergyConsumption >= 0 && this.internCPUEnergyConsumption >= 0 && this.externCPUEnergyConsumption >= 0 && this.langInternalCPUEnergyConsumption >= 0, this.selfRAMEnergyConsumption >= 0 && this.aggregatedRAMEnergyConsumption >= 0 && this.internRAMEnergyConsumption >= 0 && this.externRAMEnergyConsumption >= 0 && this.langInternalRAMEnergyConsumption >= 0); if (!valid) { throw new Error(`SourceNodeMetaData.validate: Assertion error (SourceNode validation) ${path}:${identifier} \n` + JSON.stringify(this, null, 2) + '\n'); } } static sum(...args) { const result = new SensorValues({}); for (const sensorValues of args) { result.profilerHits += sensorValues.profilerHits; result.selfCPUTime = result.selfCPUTime + sensorValues.selfCPUTime; result.aggregatedCPUTime = result.aggregatedCPUTime + sensorValues.aggregatedCPUTime; result.internCPUTime = result.internCPUTime + sensorValues.internCPUTime; result.externCPUTime = result.externCPUTime + sensorValues.externCPUTime; result.langInternalCPUTime = result.langInternalCPUTime + sensorValues.langInternalCPUTime; result.selfCPUEnergyConsumption = result.selfCPUEnergyConsumption + sensorValues.selfCPUEnergyConsumption; result.aggregatedCPUEnergyConsumption = result.aggregatedCPUEnergyConsumption + sensorValues.aggregatedCPUEnergyConsumption; result.internCPUEnergyConsumption = result.internCPUEnergyConsumption + sensorValues.internCPUEnergyConsumption; result.externCPUEnergyConsumption = result.externCPUEnergyConsumption + sensorValues.externCPUEnergyConsumption; result.langInternalCPUEnergyConsumption = result.langInternalCPUEnergyConsumption + sensorValues.langInternalCPUEnergyConsumption; result.selfRAMEnergyConsumption = result.selfRAMEnergyConsumption + sensorValues.selfRAMEnergyConsumption; result.aggregatedRAMEnergyConsumption = result.aggregatedRAMEnergyConsumption + sensorValues.aggregatedRAMEnergyConsumption; result.internRAMEnergyConsumption = result.internRAMEnergyConsumption + sensorValues.internRAMEnergyConsumption; result.externRAMEnergyConsumption = result.externRAMEnergyConsumption + sensorValues.externRAMEnergyConsumption; result.langInternalRAMEnergyConsumption = result.langInternalRAMEnergyConsumption + sensorValues.langInternalRAMEnergyConsumption; } return result; } static max(...args) { const result = new SensorValues({}); for (const sensorValues of args) { result.profilerHits = Math.max(result.profilerHits, sensorValues.profilerHits); result.selfCPUTime = Math.max(result.selfCPUTime, sensorValues.selfCPUTime); result.aggregatedCPUTime = Math.max(result.aggregatedCPUTime, sensorValues.aggregatedCPUTime); result.internCPUTime = Math.max(result.internCPUTime, sensorValues.internCPUTime); result.externCPUTime = Math.max(result.externCPUTime, sensorValues.externCPUTime); result.langInternalCPUTime = Math.max(result.langInternalCPUTime, sensorValues.langInternalCPUTime); result.selfCPUEnergyConsumption = Math.max(result.selfCPUEnergyConsumption, sensorValues.selfCPUEnergyConsumption); result.aggregatedCPUEnergyConsumption = Math.max(result.aggregatedCPUEnergyConsumption, sensorValues.aggregatedCPUEnergyConsumption); result.internCPUEnergyConsumption = Math.max(result.internCPUEnergyConsumption, sensorValues.internCPUEnergyConsumption); result.externCPUEnergyConsumption = Math.max(result.externCPUEnergyConsumption, sensorValues.externCPUEnergyConsumption); result.langInternalCPUEnergyConsumption = Math.max(result.langInternalCPUEnergyConsumption, sensorValues.langInternalCPUEnergyConsumption); result.selfRAMEnergyConsumption = Math.max(result.selfRAMEnergyConsumption, sensorValues.selfRAMEnergyConsumption); result.aggregatedRAMEnergyConsumption = Math.max(result.aggregatedRAMEnergyConsumption, sensorValues.aggregatedRAMEnergyConsumption); result.internRAMEnergyConsumption = Math.max(result.internRAMEnergyConsumption, sensorValues.internRAMEnergyConsumption); result.externRAMEnergyConsumption = Math.max(result.externRAMEnergyConsumption, sensorValues.externRAMEnergyConsumption); result.langInternalRAMEnergyConsumption = Math.max(result.langInternalRAMEnergyConsumption, sensorValues.langInternalRAMEnergyConsumption); } return result; } static equals(...args) { if (args.length === 0) { return true; } const compare = args[0]; for (let i = 1; i < args.length; i++) { const a = args[i]; if (a.profilerHits !== compare.profilerHits || a.selfCPUTime !== compare.selfCPUTime || a.aggregatedCPUTime !== compare.aggregatedCPUTime || a.internCPUTime !== compare.internCPUTime || a.externCPUTime !== compare.externCPUTime || a.langInternalCPUTime !== compare.langInternalCPUTime || a.selfCPUEnergyConsumption !== compare.selfCPUEnergyConsumption || a.aggregatedCPUEnergyConsumption !== compare.aggregatedCPUEnergyConsumption || a.internCPUEnergyConsumption !== compare.internCPUEnergyConsumption || a.externCPUEnergyConsumption !== compare.externCPUEnergyConsumption || a.langInternalCPUEnergyConsumption !== compare.langInternalCPUEnergyConsumption || a.selfRAMEnergyConsumption !== compare.selfRAMEnergyConsumption || a.aggregatedRAMEnergyConsumption !== compare.aggregatedRAMEnergyConsumption || a.internRAMEnergyConsumption !== compare.internRAMEnergyConsumption || a.externRAMEnergyConsumption !== compare.externRAMEnergyConsumption || a.langInternalRAMEnergyConsumption !== compare.langInternalRAMEnergyConsumption) { return false; } } return true; } undefinedIfZero(value) { if (value === 0) { return undefined; } return value; } toJSON() { return { profilerHits: this.undefinedIfZero(this.profilerHits), selfCPUTime: this.undefinedIfZero(this.selfCPUTime), aggregatedCPUTime: this.undefinedIfZero(this.aggregatedCPUTime), internCPUTime: this.undefinedIfZero(this.internCPUTime), externCPUTime: this.undefinedIfZero(this.externCPUTime), langInternalCPUTime: this.undefinedIfZero(this.langInternalCPUTime), selfCPUEnergyConsumption: this.undefinedIfZero(this.selfCPUEnergyConsumption), aggregatedCPUEnergyConsumption: this.undefinedIfZero(this.aggregatedCPUEnergyConsumption), internCPUEnergyConsumption: this.undefinedIfZero(this.internCPUEnergyConsumption), externCPUEnergyConsumption: this.undefinedIfZero(this.externCPUEnergyConsumption), langInternalCPUEnergyConsumption: this.undefinedIfZero(this.langInternalCPUEnergyConsumption), selfRAMEnergyConsumption: this.undefinedIfZero(this.selfRAMEnergyConsumption), aggregatedRAMEnergyConsumption: this.undefinedIfZero(this.aggregatedRAMEnergyConsumption), internRAMEnergyConsumption: this.undefinedIfZero(this.internRAMEnergyConsumption), externRAMEnergyConsumption: this.undefinedIfZero(this.externRAMEnergyConsumption), langInternalRAMEnergyConsumption: this.undefinedIfZero(this.langInternalRAMEnergyConsumption), }; } static fromJSON(json) { let data; if (typeof json === 'string') { data = JSON.parse(json); } else { data = json; } const result = new SensorValues({ profilerHits: data.profilerHits || 0, selfCPUTime: data.selfCPUTime || 0, aggregatedCPUTime: data.aggregatedCPUTime || 0, internCPUTime: data.internCPUTime || 0, externCPUTime: data.externCPUTime || 0, langInternalCPUTime: data.langInternalCPUTime || 0, selfCPUEnergyConsumption: data.selfCPUEnergyConsumption || 0, aggregatedCPUEnergyConsumption: data.aggregatedCPUEnergyConsumption || 0, internCPUEnergyConsumption: data.internCPUEnergyConsumption || 0, externCPUEnergyConsumption: data.externCPUEnergyConsumption || 0, langInternalCPUEnergyConsumption: data.langInternalCPUEnergyConsumption || 0, selfRAMEnergyConsumption: data.selfRAMEnergyConsumption || 0, aggregatedRAMEnergyConsumption: data.aggregatedRAMEnergyConsumption || 0, internRAMEnergyConsumption: data.internRAMEnergyConsumption || 0, externRAMEnergyConsumption: data.externRAMEnergyConsumption || 0, langInternalRAMEnergyConsumption: data.langInternalRAMEnergyConsumption || 0 }); return result; } toBuffer() { return BufferHelper_1.BufferHelper.numberMapToBuffer(exports.SENSOR_VALUES_BYTE_SIZE_MAP, this // eslint-disable-line @typescript-eslint/no-explicit-any ); } static consumeFromBuffer(buffer) { const { instance, remainingBuffer } = BufferHelper_1.BufferHelper.numberMapFromBuffer(exports.SENSOR_VALUES_BYTE_SIZE_MAP, buffer); return { instance: new SensorValues(instance), remainingBuffer }; } // IMPORTANT to change when new measurement type gets added addToSelf(other, sign = 1) { this.selfCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.selfCPUTime, other.selfCPUTime, sign); this.selfCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.selfCPUEnergyConsumption, other.selfCPUEnergyConsumption, sign); this.selfRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.selfRAMEnergyConsumption, other.selfRAMEnergyConsumption, sign); } // IMPORTANT to change when new measurement type gets added addToAggregated(other, sign = 1) { this.aggregatedCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.aggregatedCPUTime, other.aggregatedCPUTime, sign); this.aggregatedCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.aggregatedCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign); this.aggregatedRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.aggregatedRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign); } // IMPORTANT to change when new measurement type gets added addToIntern(other, sign = 1) { this.internCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.internCPUTime, other.aggregatedCPUTime, sign); this.internCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.internCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign); this.internRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.internRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign); } // IMPORTANT to change when new measurement type gets added addToExtern(other, sign = 1) { this.externCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.externCPUTime, other.aggregatedCPUTime, sign); this.externCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.externCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign); this.externRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.externRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign); } // IMPORTANT to change when new measurement type gets added addToLangInternal(other, sign = 1) { this.langInternalCPUTime = UnitHelper_1.UnitHelper.sumMicroSeconds(this.langInternalCPUTime, other.aggregatedCPUTime, sign); this.langInternalCPUEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.langInternalCPUEnergyConsumption, other.aggregatedCPUEnergyConsumption, sign); this.langInternalRAMEnergyConsumption = UnitHelper_1.UnitHelper.sumMilliJoule(this.langInternalRAMEnergyConsumption, other.aggregatedRAMEnergyConsumption, sign); } add({ internSensorValues, externSensorValues, langInternalSensorValues, }) { const result = SensorValues.fromJSON(this.toJSON()); if (internSensorValues) { result.addToAggregated(internSensorValues); result.addToIntern(internSensorValues); } if (externSensorValues) { result.addToAggregated(externSensorValues); result.addToExtern(externSensorValues); } if (langInternalSensorValues) { result.addToAggregated(langInternalSensorValues); result.addToLangInternal(langInternalSensorValues); } return result; } clone() { return new SensorValues(this.toJSON()); } // clones the object but removes all reference values to other objects // the aggregated values equal the self values cloneAsIsolated() { // IMPORTANT to change when new measurement type gets added return new SensorValues({ profilerHits: this.profilerHits, selfCPUTime: this.selfCPUTime, aggregatedCPUTime: this.selfCPUTime, selfCPUEnergyConsumption: this.selfCPUEnergyConsumption, aggregatedCPUEnergyConsumption: this.selfCPUEnergyConsumption, selfRAMEnergyConsumption: this.selfRAMEnergyConsumption, aggregatedRAMEnergyConsumption: this.selfRAMEnergyConsumption }); } // clones the object but only the aggregated values cloneAsAggregated() { const result = new SensorValues({}); result.addToAggregated(this); return result; } } exports.SensorValues = SensorValues; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2Vuc29yVmFsdWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21vZGVsL1NlbnNvclZhbHVlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBdUM7QUFFdkMseURBQXFEO0FBQ3JELFFBQVE7QUFDUixvQ0FTaUI7QUFDakIscURBQWlEO0FBRXBDLFFBQUEsMkJBQTJCLEdBQTZCO0lBQ3BFLFlBQVksRUFBRSw0QkFBb0IsQ0FBQyxJQUFJO0lBRXZDLFdBQVcsRUFBRSw0QkFBb0IsQ0FBQyxJQUFJO0lBQ3RDLGlCQUFpQixFQUFFLDRCQUFvQixDQUFDLElBQUk7SUFDNUMsYUFBYSxFQUFFLDRCQUFvQixDQUFDLElBQUk7SUFDeEMsYUFBYSxFQUFFLDRCQUFvQixDQUFDLElBQUk7SUFDeEMsbUJBQW1CLEVBQUUsNEJBQW9CLENBQUMsSUFBSTtJQUU5Qyx3QkFBd0IsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0lBQ3JELDhCQUE4QixFQUFFLDRCQUFvQixDQUFDLE1BQU07SUFDM0QsMEJBQTBCLEVBQUUsNEJBQW9CLENBQUMsTUFBTTtJQUN2RCwwQkFBMEIsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0lBQ3ZELGdDQUFnQyxFQUFFLDRCQUFvQixDQUFDLE1BQU07SUFFN0Qsd0JBQXdCLEVBQUUsNEJBQW9CLENBQUMsTUFBTTtJQUNyRCw4QkFBOEIsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0lBQzNELDBCQUEwQixFQUFFLDRCQUFvQixDQUFDLE1BQU07SUFDdkQsMEJBQTBCLEVBQUUsNEJBQW9CLENBQUMsTUFBTTtJQUN2RCxnQ0FBZ0MsRUFBRSw0QkFBb0IsQ0FBQyxNQUFNO0NBQzdELENBQUE7QUFFWSxRQUFBLDZCQUE2QixHQUE0QjtJQUNyRSxtQkFBbUI7SUFDbkIsZ0NBQWdDO0lBQ2hDLGdDQUFnQztDQUNoQyxDQUFBO0FBRVksUUFBQSx5QkFBeUIsR0FBNEI7SUFDakUsZUFBZTtJQUNmLDRCQUE0QjtJQUM1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