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

627 lines 71.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SourceNodeMetaData = exports.validateSourceNodeIdentifier = void 0; const BaseModel_1 = require("./BaseModel"); const ModelMap_1 = require("./ModelMap"); const SensorValues_1 = require("./SensorValues"); const GlobalIdentifier_1 = require("../system/GlobalIdentifier"); const BufferHelper_1 = require("../helper/BufferHelper"); const SourceNodeRegex_1 = require("../constants/SourceNodeRegex"); // Types const types_1 = require("../types"); function validateSourceNodeIdentifier(identifier) { return (SourceNodeRegex_1.RootRegex.test(identifier) || SourceNodeRegex_1.SourceNodeIdentifierPartRegex.test(identifier)); } exports.validateSourceNodeIdentifier = validateSourceNodeIdentifier; function areNumbersClose(a, b, epsilon = 1e-10) { return Math.abs(a - b) < epsilon; } class SourceNodeMetaData extends BaseModel_1.BaseModel { constructor(type, id, sensorValues, sourceNodeIndex) { super(); this.type = type; this.sensorValues = sensorValues; this.sourceNodeIndex = sourceNodeIndex; this.id = id; } get presentInOriginalSourceCode() { if (this.sourceNodeIndex === undefined) { return true; } return this.sourceNodeIndex.presentInOriginalSourceCode; } set presentInOriginalSourceCode(v) { if (this.sourceNodeIndex !== undefined) { this.sourceNodeIndex.presentInOriginalSourceCode = v; } } normalize(newGlobalIndex) { if (this.isAggregate()) { throw new Error('SourceNodeMetaData.normalize: can only be executed for non aggregate SourceNodeMetaData'); } const self = this; const sourceNodeIndex = self.getSourceNodeIndexByID(self.id); if (sourceNodeIndex === undefined) { throw new Error('SourceNodeMetaData.normalize(self): could not resolve sourceNodeIndex for: ' + self.id.toString()); } const newSourceNodeIndex = sourceNodeIndex.insertToOtherIndex(newGlobalIndex); if (SourceNodeMetaData.couldHaveChildren(self)) { // remap all child nodes const new_lang_internal = new ModelMap_1.ModelMap('number'); // remap all lang_internal nodes for (const sourceNodeID of Array.from(self.lang_internal.keys()).sort()) { const sourceNodeMetaData = self.lang_internal.get(sourceNodeID); sourceNodeMetaData.normalize(newGlobalIndex); new_lang_internal.set(sourceNodeMetaData.id, sourceNodeMetaData); } const new_intern = new ModelMap_1.ModelMap('number'); // remap all intern nodes for (const sourceNodeID of Array.from(self.intern.keys()).sort()) { const sourceNodeMetaData = self.intern.get(sourceNodeID); sourceNodeMetaData.normalize(newGlobalIndex); new_intern.set(sourceNodeMetaData.id, sourceNodeMetaData); } const new_extern = new ModelMap_1.ModelMap('number'); // remap all extern nodes for (const sourceNodeID of Array.from(self.extern.keys()).sort()) { const sourceNodeMetaData = self.extern.get(sourceNodeID); sourceNodeMetaData.normalize(newGlobalIndex); new_extern.set(sourceNodeMetaData.id, sourceNodeMetaData); } self._lang_internal = new_lang_internal; self._intern = new_intern; self._extern = new_extern; } // remap the self ID and the self moduleIndex self.id = newSourceNodeIndex.id; self.sourceNodeIndex = newSourceNodeIndex; } globalIdentifier() { if (this.isNotAggregate()) { const index = this.getIndex(); if (index !== undefined) { return index.globalIdentifier(); } } throw new Error('SourceNodeMetaData.globalIdentifier: cannot resolve globalIdentifier'); } isAggregate() { return this.type === types_1.SourceNodeMetaDataType.Aggregate; } isNotAggregate() { return this.type !== types_1.SourceNodeMetaDataType.Aggregate; } getSourceNodeIndexByID(id) { var _a; return (_a = this.sourceNodeIndex) === null || _a === void 0 ? void 0 : _a.pathIndex.moduleIndex.globalIndex.getSourceNodeIndexByID(id); } getPathIndexByID(id) { var _a; return (_a = this.sourceNodeIndex) === null || _a === void 0 ? void 0 : _a.pathIndex.moduleIndex.globalIndex.getPathIndexByID(id); } getIndex() { if (this.isNotAggregate()) { return this.sourceNodeIndex; } } getPathIndex(indexRequestType, filePath) { if (this.sourceNodeIndex === undefined) { throw new Error('SourceNodeMetaData.getPathIndex: sourceNodeIndex is not defined'); } return this.sourceNodeIndex.pathIndex.moduleIndex.getFilePathIndex(indexRequestType, filePath); } // IMPORTANT to change when new measurement type gets added static merge(sourceNodeID, sourceNodeIndex, ...args) { if (args.length === 0) { throw new Error('SourceNodeMetaData.merge: no SourceNodeMetaData were given'); } const type = args[0].type; const presentInOriginalSourceCode = args.map((x) => x.presentInOriginalSourceCode).reduce((prevValue, currValue) => prevValue && currValue); const valuesToSum = { profilerHits: 0, selfCPUTime: 0, aggregatedCPUTime: 0, langInternalCPUTime: 0, internCPUTime: 0, externCPUTime: 0, selfCPUEnergyConsumption: 0, aggregatedCPUEnergyConsumption: 0, internCPUEnergyConsumption: 0, externCPUEnergyConsumption: 0, langInternalCPUEnergyConsumption: 0, selfRAMEnergyConsumption: 0, aggregatedRAMEnergyConsumption: 0, internRAMEnergyConsumption: 0, externRAMEnergyConsumption: 0, langInternalRAMEnergyConsumption: 0, }; const valuesToMerge = { lang_internal: {}, intern: {}, extern: {}, }; for (const currentSourceNodeMetaData of args) { if (type !== currentSourceNodeMetaData.type) { throw new Error('SourceNodeMetaData.merge: all SourceNodeMetaDatas should be from the same type.'); } valuesToSum.profilerHits += currentSourceNodeMetaData.sensorValues.profilerHits; valuesToSum.selfCPUTime = valuesToSum.selfCPUTime + currentSourceNodeMetaData.sensorValues.selfCPUTime; valuesToSum.aggregatedCPUTime = valuesToSum.aggregatedCPUTime + currentSourceNodeMetaData.sensorValues.aggregatedCPUTime; valuesToSum.langInternalCPUTime = valuesToSum.langInternalCPUTime + currentSourceNodeMetaData.sensorValues.langInternalCPUTime; valuesToSum.internCPUTime = valuesToSum.internCPUTime + currentSourceNodeMetaData.sensorValues.internCPUTime; valuesToSum.externCPUTime = valuesToSum.externCPUTime + currentSourceNodeMetaData.sensorValues.externCPUTime; valuesToSum.selfCPUEnergyConsumption = valuesToSum.selfCPUEnergyConsumption + currentSourceNodeMetaData.sensorValues.selfCPUEnergyConsumption; valuesToSum.aggregatedCPUEnergyConsumption = valuesToSum.aggregatedCPUEnergyConsumption + currentSourceNodeMetaData.sensorValues.aggregatedCPUEnergyConsumption; valuesToSum.internCPUEnergyConsumption = valuesToSum.internCPUEnergyConsumption + currentSourceNodeMetaData.sensorValues.internCPUEnergyConsumption; valuesToSum.externCPUEnergyConsumption = valuesToSum.externCPUEnergyConsumption + currentSourceNodeMetaData.sensorValues.externCPUEnergyConsumption; valuesToSum.langInternalCPUEnergyConsumption = valuesToSum.langInternalCPUEnergyConsumption + currentSourceNodeMetaData.sensorValues.langInternalCPUEnergyConsumption; valuesToSum.selfRAMEnergyConsumption = valuesToSum.selfRAMEnergyConsumption + currentSourceNodeMetaData.sensorValues.selfRAMEnergyConsumption; valuesToSum.aggregatedRAMEnergyConsumption = valuesToSum.aggregatedRAMEnergyConsumption + currentSourceNodeMetaData.sensorValues.aggregatedRAMEnergyConsumption; valuesToSum.internRAMEnergyConsumption = valuesToSum.internRAMEnergyConsumption + currentSourceNodeMetaData.sensorValues.internRAMEnergyConsumption; valuesToSum.externRAMEnergyConsumption = valuesToSum.externRAMEnergyConsumption + currentSourceNodeMetaData.sensorValues.externRAMEnergyConsumption; valuesToSum.langInternalRAMEnergyConsumption = valuesToSum.langInternalRAMEnergyConsumption + currentSourceNodeMetaData.sensorValues.langInternalRAMEnergyConsumption; if (SourceNodeMetaData.couldHaveChildren(currentSourceNodeMetaData)) { for (const [langInternalsSourceNodeID, sourceNodeMetaData] of currentSourceNodeMetaData.lang_internal.entries()) { const sourceNodeIndex = currentSourceNodeMetaData.getSourceNodeIndexByID(langInternalsSourceNodeID); if (sourceNodeIndex === undefined) { throw new Error('SourceNodeMetaData.merge: could not resolve sourceNodeIndex from id'); } const identifier = sourceNodeIndex.globalIdentifier().identifier; if (!valuesToMerge.lang_internal[identifier]) { valuesToMerge.lang_internal[identifier] = []; } valuesToMerge.lang_internal[identifier].push(sourceNodeMetaData); } for (const [internSourceNodeID, sourceNodeMetaData] of currentSourceNodeMetaData.intern.entries()) { const sourceNodeIndex = currentSourceNodeMetaData.getSourceNodeIndexByID(internSourceNodeID); if (sourceNodeIndex === undefined) { throw new Error('SourceNodeMetaData.merge: could not resolve sourceNodeIndex from id'); } const identifier = sourceNodeIndex.globalIdentifier().identifier; if (!valuesToMerge.intern[identifier]) { valuesToMerge.intern[identifier] = []; } valuesToMerge.intern[identifier].push(sourceNodeMetaData); } for (const [externSourceNodeID, sourceNodeMetaData] of currentSourceNodeMetaData.extern.entries()) { const sourceNodeIndex = currentSourceNodeMetaData.getSourceNodeIndexByID(externSourceNodeID); if (sourceNodeIndex === undefined) { throw new Error('SourceNodeMetaData.merge: could not resolve sourceNodeIndex from id'); } const identifier = sourceNodeIndex.globalIdentifier().identifier; if (!valuesToMerge.extern[identifier]) { valuesToMerge.extern[identifier] = []; } valuesToMerge.extern[identifier].push(sourceNodeMetaData); } } } const result = new SourceNodeMetaData(type, sourceNodeID, SensorValues_1.SensorValues.fromJSON(valuesToSum), sourceNodeIndex); result.presentInOriginalSourceCode = presentInOriginalSourceCode; for (const [identifier, sourceNodeMetaDatas] of Object.entries(valuesToMerge.lang_internal)) { const sourceNodeIndex_langInternal = sourceNodeIndex.pathIndex.moduleIndex.globalIndex.getSourceNodeIndex('upsert', GlobalIdentifier_1.GlobalIdentifier.fromIdentifier(identifier)); result.lang_internal.set(sourceNodeIndex_langInternal.id, SourceNodeMetaData.merge(sourceNodeIndex_langInternal.id, sourceNodeIndex_langInternal, ...sourceNodeMetaDatas)); } for (const [identifier, sourceNodeMetaDatas] of Object.entries(valuesToMerge.intern)) { const globalIdentifier = GlobalIdentifier_1.GlobalIdentifier.fromIdentifier(identifier); const sourceNodeIndex_intern = sourceNodeIndex.pathIndex.moduleIndex.getFilePathIndex('upsert', globalIdentifier.path).getSourceNodeIndex('upsert', globalIdentifier.sourceNodeIdentifier); result.intern.set(sourceNodeIndex_intern.id, SourceNodeMetaData.merge(sourceNodeIndex_intern.id, sourceNodeIndex_intern, ...sourceNodeMetaDatas)); } for (const [identifier, sourceNodeMetaDatas] of Object.entries(valuesToMerge.extern)) { const sourceNodeIndex_extern = sourceNodeIndex.pathIndex.moduleIndex.globalIndex.getSourceNodeIndex('upsert', GlobalIdentifier_1.GlobalIdentifier.fromIdentifier(identifier)); result.extern.set(sourceNodeIndex_extern.id, SourceNodeMetaData.merge(sourceNodeIndex_extern.id, sourceNodeIndex_extern, ...sourceNodeMetaDatas)); } return result; } removeFromIntern(filePath) { let filePaths = []; if (typeof filePath === 'string') { filePaths = [filePath]; } else { filePaths = filePath; } const filePathIDs = []; for (const filePath of filePaths) { const pathIndex = this.getPathIndex('get', filePath); if (pathIndex === undefined) { throw new Error('SourceNodeMetaData.removeFromIntern: could not resolve pathIndex from id'); } filePathIDs.push(pathIndex.id); } for (const [sourceNodeID, sourceNodeMetaData] of this.intern.entries()) { const sourceNodeIndex = this.getSourceNodeIndexByID(sourceNodeID); if (sourceNodeIndex === undefined) { throw new Error('SourceNodeMetaData.removeFromIntern: could not resolve sourceNode from id'); } if (filePathIDs.includes(sourceNodeIndex.pathIndex.id)) { this.sensorValues.internCPUTime = this.sensorValues.internCPUTime - sourceNodeMetaData.sensorValues.aggregatedCPUTime; this.sensorValues.aggregatedCPUTime = this.sensorValues.aggregatedCPUTime - sourceNodeMetaData.sensorValues.aggregatedCPUTime; this.sensorValues.internCPUEnergyConsumption = this.sensorValues.internCPUEnergyConsumption - sourceNodeMetaData.sensorValues.aggregatedCPUEnergyConsumption; this.sensorValues.aggregatedCPUEnergyConsumption = this.sensorValues.aggregatedCPUEnergyConsumption - sourceNodeMetaData.sensorValues.aggregatedCPUEnergyConsumption; this.intern.delete(sourceNodeIndex.id); } } } static max(...args) { return new SourceNodeMetaData(types_1.SourceNodeMetaDataType.Aggregate, undefined, SensorValues_1.SensorValues.max(...args.map((node) => node.sensorValues)), undefined); } static sum(...args) { return new SourceNodeMetaData(types_1.SourceNodeMetaDataType.Aggregate, undefined, SensorValues_1.SensorValues.sum(...args.map((node) => node.sensorValues)), undefined); } static equals(...args) { if (args.length === 0) { return true; } const compare = args[0]; const sensorValuesAreEqual = SensorValues_1.SensorValues.equals(...args.map((node) => node.sensorValues)); if (!sensorValuesAreEqual) { return sensorValuesAreEqual; } for (let i = 1; i < args.length; i++) { const a = args[i]; if (a.type !== compare.type) { return false; } } return true; } static couldHaveChildren(object) { return object.type === types_1.SourceNodeMetaDataType.SourceNode || object.type === types_1.SourceNodeMetaDataType.LangInternalSourceNode; } get lang_internal() { if (this._lang_internal === undefined && SourceNodeMetaData.couldHaveChildren(this)) { this. _lang_internal = new ModelMap_1.ModelMap('number'); } return this._lang_internal; } get intern() { if (this._intern === undefined && SourceNodeMetaData.couldHaveChildren(this)) { this. _intern = new ModelMap_1.ModelMap('number'); } return this._intern; } get extern() { if (this._extern === undefined && SourceNodeMetaData.couldHaveChildren(this)) { this. _extern = new ModelMap_1.ModelMap('number'); } return this._extern; } // IMPORTANT to change when new measurement type gets added addToSensorValues({ cpuTime, cpuEnergyConsumption, ramEnergyConsumption }) { this.sensorValues.selfCPUTime = this.sensorValues.selfCPUTime + (cpuTime.selfCPUTime || 0); this.sensorValues.aggregatedCPUTime = this.sensorValues.aggregatedCPUTime + (cpuTime.aggregatedCPUTime || 0); this.sensorValues.selfCPUEnergyConsumption = this.sensorValues.selfCPUEnergyConsumption + (cpuEnergyConsumption.selfCPUEnergyConsumption || 0); this.sensorValues.aggregatedCPUEnergyConsumption = this.sensorValues.aggregatedCPUEnergyConsumption + (cpuEnergyConsumption.aggregatedCPUEnergyConsumption || 0); this.sensorValues.selfRAMEnergyConsumption = this.sensorValues.selfRAMEnergyConsumption + (ramEnergyConsumption.selfRAMEnergyConsumption || 0); this.sensorValues.aggregatedRAMEnergyConsumption = this.sensorValues.aggregatedRAMEnergyConsumption + (ramEnergyConsumption.aggregatedRAMEnergyConsumption || 0); return this; } // IMPORTANT to change when new measurement type gets added addSensorValuesToLangInternal(identifier, values) { if (!SourceNodeMetaData.couldHaveChildren(this)) { throw new Error('Cannot only add sensor values to langInternal for SourceNode and LangInternalSourceNode'); } const sourceNodeIndex = this.sourceNodeIndex.pathIndex.moduleIndex.globalIndex.getSourceNodeIndex('upsert', identifier); const sourceNodeID = sourceNodeIndex.id; let sourceNodeMetaData = this.lang_internal.get(sourceNodeID); if (!sourceNodeMetaData) { sourceNodeMetaData = new SourceNodeMetaData(types_1.SourceNodeMetaDataType.LangInternalSourceNodeReference, sourceNodeID, new SensorValues_1.SensorValues({}), sourceNodeIndex), this.lang_internal.set(sourceNodeID, sourceNodeMetaData); } sourceNodeMetaData.sensorValues.profilerHits += 1; sourceNodeMetaData.addToSensorValues({ cpuTime: values.cpuTime, cpuEnergyConsumption: values.cpuEnergyConsumption, ramEnergyConsumption: values.ramEnergyConsumption }); this.sensorValues.langInternalCPUTime = this.sensorValues.langInternalCPUTime + (values.cpuTime.aggregatedCPUTime || 0); this.sensorValues.langInternalCPUEnergyConsumption = this.sensorValues.langInternalCPUEnergyConsumption + (values.cpuEnergyConsumption.aggregatedCPUEnergyConsumption || 0); this.sensorValues.langInternalRAMEnergyConsumption = this.sensorValues.langInternalRAMEnergyConsumption + (values.ramEnergyConsumption.aggregatedRAMEnergyConsumption || 0); return sourceNodeMetaData; } // IMPORTANT to change when new measurement type gets added addSensorValuesToIntern(identifier, values) { if (!SourceNodeMetaData.couldHaveChildren(this)) { throw new Error('Cannot only add sensor values to intern for SourceNode and LangInternalSourceNode'); } const sourceNodeIndex = this.sourceNodeIndex.pathIndex.moduleIndex.globalIndex.getSourceNodeIndex('upsert', identifier); const sourceNodeID = sourceNodeIndex.id; let sourceNodeMetaData = this.intern.get(sourceNodeID); if (!sourceNodeMetaData) { sourceNodeMetaData = new SourceNodeMetaData(types_1.SourceNodeMetaDataType.InternSourceNodeReference, sourceNodeID, new SensorValues_1.SensorValues({}), sourceNodeIndex); this.intern.set(sourceNodeID, sourceNodeMetaData); } sourceNodeMetaData.sensorValues.profilerHits += 1; sourceNodeMetaData.addToSensorValues({ cpuTime: values.cpuTime, cpuEnergyConsumption: values.cpuEnergyConsumption, ramEnergyConsumption: values.ramEnergyConsumption }); this.sensorValues.internCPUTime = this.sensorValues.internCPUTime + (values.cpuTime.aggregatedCPUTime || 0); this.sensorValues.internCPUEnergyConsumption = this.sensorValues.internCPUEnergyConsumption + (values.cpuEnergyConsumption.aggregatedCPUEnergyConsumption || 0); this.sensorValues.internRAMEnergyConsumption = this.sensorValues.internRAMEnergyConsumption + (values.ramEnergyConsumption.aggregatedRAMEnergyConsumption || 0); return sourceNodeMetaData; } // IMPORTANT to change when new measurement type gets added addSensorValuesToExtern(identifier, values) { if (!SourceNodeMetaData.couldHaveChildren(this)) { throw new Error('Cannot only add sensor values to extern for SourceNode and LangInternalSourceNode'); } const sourceNodeIndex = this.sourceNodeIndex.pathIndex.moduleIndex.globalIndex.getSourceNodeIndex('upsert', identifier); const sourceNodeID = sourceNodeIndex.id; let sourceNodeMetaData = this.extern.get(sourceNodeID); if (!sourceNodeMetaData) { sourceNodeMetaData = new SourceNodeMetaData(types_1.SourceNodeMetaDataType.ExternSourceNodeReference, sourceNodeID, new SensorValues_1.SensorValues({}), sourceNodeIndex); this.extern.set(sourceNodeID, sourceNodeMetaData); } sourceNodeMetaData.sensorValues.profilerHits += 1; sourceNodeMetaData.addToSensorValues({ cpuTime: values.cpuTime, cpuEnergyConsumption: values.cpuEnergyConsumption, ramEnergyConsumption: values.ramEnergyConsumption }); this.sensorValues.externCPUTime = this.sensorValues.externCPUTime + (values.cpuTime.aggregatedCPUTime || 0); this.sensorValues.externCPUEnergyConsumption = this.sensorValues.externCPUEnergyConsumption + (values.cpuEnergyConsumption.aggregatedCPUEnergyConsumption || 0); this.sensorValues.externRAMEnergyConsumption = this.sensorValues.externRAMEnergyConsumption + (values.ramEnergyConsumption.aggregatedRAMEnergyConsumption || 0); return sourceNodeMetaData; } validate(path, identifier) { var _a; if (this.type !== types_1.SourceNodeMetaDataType.SourceNode) { return; } if (((_a = this.sourceNodeIndex) === null || _a === void 0 ? void 0 : _a.id) !== this.id) { throw new Error('SourceNodeMetaData.validate: Assertion error sourceNodeIndex and sourceNode id are not compatible'); } this.sensorValues.validate(path, identifier); const totalSensorValues = []; const totalLangInternalSensorValues = []; const totalInternSensorValues = []; const totalExternSensorValues = []; for (const nodeMetaData of this.lang_internal.values()) { const aggregatedSensorValues = nodeMetaData.sensorValues.cloneAsAggregated(); totalSensorValues.push(aggregatedSensorValues); totalLangInternalSensorValues.push(aggregatedSensorValues); nodeMetaData.sensorValues.validate(path, identifier); } for (const nodeMetaData of this.intern.values()) { const aggregatedSensorValues = nodeMetaData.sensorValues.cloneAsAggregated(); totalSensorValues.push(aggregatedSensorValues); totalInternSensorValues.push(aggregatedSensorValues); nodeMetaData.sensorValues.validate(path, identifier); } for (const nodeMetaData of this.extern.values()) { const aggregatedSensorValues = nodeMetaData.sensorValues.cloneAsAggregated(); totalSensorValues.push(aggregatedSensorValues); totalExternSensorValues.push(aggregatedSensorValues); nodeMetaData.sensorValues.validate(path, identifier); } const totalAggregate = SensorValues_1.SensorValues.sum(...totalSensorValues); const totalLangInternalAggregate = SensorValues_1.SensorValues.sum(...totalLangInternalSensorValues); const totalInternAggregate = SensorValues_1.SensorValues.sum(...totalInternSensorValues); const totalExternAggregate = SensorValues_1.SensorValues.sum(...totalExternSensorValues); // IMPORTANT to change when new measurement type gets added if (totalAggregate.aggregatedCPUTime < this.sensorValues.aggregatedCPUTime - this.sensorValues.selfCPUTime || totalLangInternalAggregate.aggregatedCPUTime !== this.sensorValues.langInternalCPUTime || totalExternAggregate.aggregatedCPUTime !== this.sensorValues.externCPUTime || totalInternAggregate.aggregatedCPUTime !== this.sensorValues.internCPUTime || // CPU Energy Consumption (totalAggregate.aggregatedCPUEnergyConsumption < this.sensorValues.aggregatedCPUEnergyConsumption - this.sensorValues.selfCPUEnergyConsumption && !areNumbersClose(totalAggregate.aggregatedCPUEnergyConsumption, this.sensorValues.aggregatedCPUEnergyConsumption - this.sensorValues.selfCPUEnergyConsumption)) || !areNumbersClose(totalLangInternalAggregate.aggregatedCPUEnergyConsumption, this.sensorValues.langInternalCPUEnergyConsumption) || !areNumbersClose(totalExternAggregate.aggregatedCPUEnergyConsumption, this.sensorValues.externCPUEnergyConsumption) || !areNumbersClose(totalInternAggregate.aggregatedCPUEnergyConsumption, this.sensorValues.internCPUEnergyConsumption) || // RAM Energy Consumption (totalAggregate.aggregatedRAMEnergyConsumption < this.sensorValues.aggregatedRAMEnergyConsumption - this.sensorValues.selfRAMEnergyConsumption && !areNumbersClose(totalAggregate.aggregatedRAMEnergyConsumption, this.sensorValues.aggregatedRAMEnergyConsumption - this.sensorValues.selfRAMEnergyConsumption)) || !areNumbersClose(totalLangInternalAggregate.aggregatedRAMEnergyConsumption, this.sensorValues.langInternalRAMEnergyConsumption) || !areNumbersClose(totalExternAggregate.aggregatedRAMEnergyConsumption, this.sensorValues.externRAMEnergyConsumption) || !areNumbersClose(totalInternAggregate.aggregatedRAMEnergyConsumption, this.sensorValues.internRAMEnergyConsumption)) { throw new Error(`SourceNodeMetaData.validate: Assertion error (SourceNode validation) ${path}:${identifier} \n` + JSON.stringify(this, null, 2) + '\n' + JSON.stringify({ totalAggregate, totalLangInternalAggregate, totalInternAggregate, totalExternAggregate, reason: { 'totalAggregatedTime < aggregatedCPUTime - selfCPUTime': totalAggregate.aggregatedCPUTime < this.sensorValues.aggregatedCPUTime - this.sensorValues.selfCPUTime, 'totalLangInternalCPUTime != langInternalCPUTime': totalLangInternalAggregate.aggregatedCPUTime !== this.sensorValues.langInternalCPUTime, 'totalExternCPUTime != externCPUTime': totalExternAggregate.aggregatedCPUTime !== this.sensorValues.externCPUTime, 'totalInternCPUTime != internCPUTime': totalInternAggregate.aggregatedCPUTime !== this.sensorValues.internCPUTime, // CPU Energy Consumption 'totalAggregatedCPUEnergyConsumption < aggregatedCPUEnergyConsumption - selfCPUEnergyConsumption': !areNumbersClose(totalAggregate.aggregatedCPUEnergyConsumption, this.sensorValues.aggregatedCPUEnergyConsumption - this.sensorValues.selfCPUEnergyConsumption), 'totalLangInternalCPUEnergyConsumption != langInternalCPUEnergyConsumption': !areNumbersClose(totalLangInternalAggregate.aggregatedCPUEnergyConsumption, this.sensorValues.langInternalCPUEnergyConsumption), 'totalExternCPUEnergyConsumption != externCPUEnergyConsumption': !areNumbersClose(totalExternAggregate.aggregatedCPUEnergyConsumption, this.sensorValues.externCPUEnergyConsumption), 'totalInternCPUEnergyConsumption != internCPUEnergyConsumption': !areNumbersClose(totalInternAggregate.aggregatedCPUEnergyConsumption, this.sensorValues.internCPUEnergyConsumption), // RAM Energy Consumption 'totalAggregatedRAMEnergyConsumption < aggregatedRAMEnergyConsumption - selfRAMEnergyConsumption': !areNumbersClose(totalAggregate.aggregatedRAMEnergyConsumption, this.sensorValues.aggregatedRAMEnergyConsumption - this.sensorValues.selfRAMEnergyConsumption), 'totalLangInternalRAMEnergyConsumption != langInternalRAMEnergyConsumption': !areNumbersClose(totalLangInternalAggregate.aggregatedRAMEnergyConsumption, this.sensorValues.langInternalRAMEnergyConsumption), 'totalExternRAMEnergyConsumption != externRAMEnergyConsumption': !areNumbersClose(totalExternAggregate.aggregatedRAMEnergyConsumption, this.sensorValues.externRAMEnergyConsumption), 'totalInternRAMEnergyConsumption != internRAMEnergyConsumption': !areNumbersClose(totalInternAggregate.aggregatedRAMEnergyConsumption, this.sensorValues.internRAMEnergyConsumption) } }, null, 2)); } } toJSON() { var _a, _b, _c; return { id: this.id, type: this.type, sensorValues: this.sensorValues.toJSON(), lang_internal: (_a = this.lang_internal) === null || _a === void 0 ? void 0 : _a.toJSON(), intern: (_b = this.intern) === null || _b === void 0 ? void 0 : _b.toJSON(), extern: (_c = this.extern) === null || _c === void 0 ? void 0 : _c.toJSON() }; } static fromJSON(json, globalIndex) { let data; if (typeof json === 'string') { data = JSON.parse(json); } else { data = json; } if (data.type !== types_1.SourceNodeMetaDataType.Aggregate) { if (globalIndex === undefined) { throw new Error('SourceNodeMetaData.fromJSON: expect a globalIndex for all SourceNodeMetaDataTypes except Aggregate'); } if (data.id === undefined) { throw new Error('SourceNodeMetaData.fromJSON: expect an ID for all SourceNodeMetaDataTypes except Aggregate'); } } const sourceNodeIndex = data.type !== types_1.SourceNodeMetaDataType.Aggregate ? globalIndex.getSourceNodeIndexByID(data.id) : undefined; const result = new SourceNodeMetaData(data.type, data.id, SensorValues_1.SensorValues.fromJSON(data.sensorValues), sourceNodeIndex); if (SourceNodeMetaData.couldHaveChildren(result)) { if (data.lang_internal) { for (const [sourceNodeID_string, nodeMetaData] of Object.entries(data.lang_internal)) { const sourceNodeID = parseInt(sourceNodeID_string); result.lang_internal.set(sourceNodeID, SourceNodeMetaData.fromJSON(nodeMetaData, globalIndex)); } } if (data.intern) { for (const [sourceNodeID_string, nodeMetaData] of Object.entries(data.intern)) { const sourceNodeID = parseInt(sourceNodeID_string); result.intern.set(sourceNodeID, SourceNodeMetaData.fromJSON(nodeMetaData, globalIndex)); } } if (data.extern) { for (const [sourceNodeID_string, nodeMetaData] of Object.entries(data.extern)) { const sourceNodeID = parseInt(sourceNodeID_string); result.extern.set(sourceNodeID, SourceNodeMetaData.fromJSON(nodeMetaData, globalIndex)); } } } return result; } toBuffer() { if (this.isAggregate()) { throw new Error('SourceNodeMetaData.toBuffer: can only be executed for non aggregate type'); } const self = this; const buffers = [ BufferHelper_1.BufferHelper.UIntToBuffer(self.id), BufferHelper_1.BufferHelper.UIntToBuffer(this.type), this.sensorValues.toBuffer() ]; if (this.lang_internal !== undefined) { buffers.push(this.lang_internal.toBuffer()); } if (this.intern !== undefined) { buffers.push(this.intern.toBuffer()); } if (this.extern !== undefined) { buffers.push(this.extern.toBuffer()); } return Buffer.concat(buffers); } static consumeFromBuffer(buffer, globalIndex) { let remainingBuffer = buffer; const { instance: sourceNodeID, remainingBuffer: newRemainingBuffer1 } = BufferHelper_1.BufferHelper.UIntFromBuffer(remainingBuffer); remainingBuffer = newRemainingBuffer1; const { instance: type, remainingBuffer: newRemainingBuffer2 } = BufferHelper_1.BufferHelper.UIntFromBuffer(remainingBuffer); remainingBuffer = newRemainingBuffer2; const { instance: sensorValues, remainingBuffer: newRemainingBuffer3 } = SensorValues_1.SensorValues.consumeFromBuffer(remainingBuffer); remainingBuffer = newRemainingBuffer3; let instance = undefined; if (type !== types_1.SourceNodeMetaDataType.SourceNode && type !== types_1.SourceNodeMetaDataType.LangInternalSourceNode) { const sourceNodeIndex = globalIndex.getSourceNodeIndexByID(sourceNodeID); if (sourceNodeIndex === undefined) { throw new Error('SourceNodeMetaData.consumeFromBuffer(SourceNode|LangInternalSourceNode): expected sourceNodeIndex to be given'); } instance = new SourceNodeMetaData(type, sourceNodeID, sensorValues, sourceNodeIndex); } else { const sourceNodeIndex = globalIndex.getSourceNodeIndexByID(sourceNodeID); if (sourceNodeIndex === undefined) { throw new Error('SourceNodeMetaData.consumeFromBuffer: expected sourceNodeIndex to be given'); } instance = new SourceNodeMetaData(type, sourceNodeID, sensorValues, sourceNodeIndex); const { instance: lang_internal, remainingBuffer: newRemainingBuffer4 } = ModelMap_1.ModelMap.consumeFromBuffer(remainingBuffer, 'number', (buffer) => { return SourceNodeMetaData.consumeFromBuffer(buffer, globalIndex); }); remainingBuffer = newRemainingBuffer4; instance._lang_internal = lang_internal; const { instance: intern, remainingBuffer: newRemainingBuffer5 } = ModelMap_1.ModelMap.consumeFromBuffer(remainingBuffer, 'number', (buffer) => { return SourceNodeMetaData.consumeFromBuffer(buffer, globalIndex); }); remainingBuffer = newRemainingBuffer5; instance._intern = intern; const { instance: extern, remainingBuffer: newRemainingBuffer6 } = ModelMap_1.ModelMap.consumeFromBuffer(remainingBuffer, 'number', (buffer) => { return SourceNodeMetaData.consumeFromBuffer(buffer, globalIndex); }); remainingBuffer = newRemainingBuffer6; instance._extern = extern; } return { instance: instance, remainingBuffer }; } } exports.SourceNodeMetaData = SourceNodeMetaData; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU291cmNlTm9kZU1ldGFEYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21vZGVsL1NvdXJjZU5vZGVNZXRhRGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBdUM7QUFDdkMseUNBQXFDO0FBQ3JDLGlEQUE2QztBQUs3QyxpRUFBNkQ7QUFDN0QseURBQXFEO0FBQ3JELGtFQUF1RjtBQUN2RixRQUFRO0FBQ1Isb0NBZ0JpQjtBQUVqQixTQUFnQiw0QkFBNEIsQ0FBQyxVQUF1QztJQUNuRixPQUFPLENBQUMsMkJBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksK0NBQTZCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUE7QUFDdEYsQ0FBQztBQUZELG9FQUVDO0FBRUQsU0FBUyxlQUFlLENBQUMsQ0FBUyxFQUFFLENBQVMsRUFBRSxPQUFPLEdBQUcsS0FBSztJQUM3RCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQTtBQUNqQyxDQUFDO0FBc0JELE1BQWEsa0JBQXFELFNBQVEscUJBQVM7SUFXbEYsWUFDQyxJQUFPLEVBQ1AsRUFBK0UsRUFDL0UsWUFBMEIsRUFDMUIsZUFDNEQ7UUFFNUQsS0FBSyxFQUFFLENBQUE7UUFDUCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQTtRQUNoQixJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQTtRQUNoQyxJQUFJLENBQUMsZUFBZSxHQUFHLGVBQWUsQ0FBQTtRQUN0QyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQTtJQUNiLENBQUM7SUFFRCxJQUFXLDJCQUEyQjtRQUNyQyxJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEMsT0FBTyxJQUFJLENBQUE7UUFDWixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLDJC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