@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
597 lines • 64.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SourceNodeMetaData = 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");
// Types
const types_1 = require("../types");
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) {
function sortIDsByIdentifier(input) {
return Array.from(input.values())
.map((value) => ({
identifier: value.sourceNodeIndex.globalIdentifier().identifier,
id: value.id
})) // Pair identifier with id
.sort((a, b) => a.identifier.localeCompare(b.identifier)) // Sort by identifier
.map((pair) => pair.id); // Extract sorted ids
}
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 sortIDsByIdentifier(self.lang_internal)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
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 sortIDsByIdentifier(self.intern)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
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 sortIDsByIdentifier(self.extern)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
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;
}
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;
}
addToSensorValues(values) {
this.sensorValues.addToSelf(values);
this.sensorValues.addToAggregated(values);
return this;
}
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);
}
this.sensorValues.addToLangInternal(values);
sourceNodeMetaData.addToSensorValues(values);
return sourceNodeMetaData;
}
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);
}
this.sensorValues.addToIntern(values);
sourceNodeMetaData.addToSensorValues(values);
return sourceNodeMetaData;
}
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);
}
this.sensorValues.addToExtern(values);
sourceNodeMetaData.addToSensorValues(values);
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
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
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,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
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,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
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,
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
globalIndex));
}
}
}
return result;
}
toBuffer() {
var _a;
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((_a = this.globalIdentifier()) === null || _a === void 0 ? void 0 : _a.identifier)
];
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU291cmNlTm9kZU1ldGFEYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21vZGVsL1NvdXJjZU5vZGVNZXRhRGF0YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwyQ0FBdUM7QUFDdkMseUNBQXFDO0FBQ3JDLGlEQUE2QztBQUs3QyxpRUFBNkQ7QUFDN0QseURBQXFEO0FBQ3JELFFBQVE7QUFDUixvQ0FlaUI7QUFFakIsU0FBUyxlQUFlLENBQUMsQ0FBUyxFQUFFLENBQVMsRUFBRSxPQUFPLEdBQUcsS0FBSztJQUM3RCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQTtBQUNqQyxDQUFDO0FBNEJELE1BQWEsa0JBRVgsU0FBUSxxQkFBUztJQWNsQixZQUNDLElBQU8sRUFDUCxFQUVzQixFQUN0QixZQUEwQixFQUMxQixlQUVrRDtRQUVsRCxLQUFLLEVBQUUsQ0FBQTtRQUNQLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFBO1FBQ2hCLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFBO1FBQ2hDLElBQUksQ0FBQyxlQUFlLEdBQUcsZUFBZSxDQUFBO1FBQ3RDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFBO0lBQ2IsQ0FBQztJQUVELElBQVcsMkJBQTJCO1FBQ3JDLElBQUksSUFBSSxDQUFDLGVBQWUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN4QyxPQUFPLElBQUksQ0FBQTtRQUNaLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsMkJBQTJCLENBQUE7SUFDeEQsQ0FBQztJQUVELElBQVcsMkJBQTJCLENBQUMsQ0FBVTtRQUNoRCxJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLGVBQWUsQ0FBQywyQkFBMkIsR0FBRyxDQUFDLENBQUE7UUFDckQsQ0FBQztJQUNGLENB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