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