UNPKG

@syntest/cfg-core

Version:
108 lines 3.85 kB
"use strict"; /* * Copyright 2020-2021 Delft University of Technology and SynTest contributors * * This file is part of SynTest Framework - SynTest Core. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.CFG = void 0; const Node_1 = require("./nodes/Node"); class CFG { constructor() { this._nodes = []; this._edges = []; } get nodes() { return this._nodes; } set nodes(value) { this._nodes = value; } get edges() { return this._edges; } set edges(value) { this._edges = value; } getRootNodes() { return this._nodes .filter((node) => node.type === Node_1.NodeType.Root) .map((node) => node); } getNodeById(nodeId) { const node = this._nodes.find((node) => node.id == nodeId); return node; } /* Method return a map that has node ids as keys, and list of pairs as a value. Each of the pairs in the list of certain node represent a node of a parent as a first value, and a number that indicates if the edge that connects this two nodes has a defined branch type i.e. weight of the edge */ getRotatedAdjacencyList() { const adjList = new Map(); for (const edge of this._edges) { if (!adjList.has(edge.from)) { adjList.set(edge.from, []); } if (!adjList.has(edge.to)) { adjList.set(edge.to, []); } adjList.get(edge.to).push({ first: edge.from, second: edge.branchType !== undefined ? 1 : 0, }); } return adjList; } findClosestAncestor(from, targets) { const rotatedAdjList = this.getRotatedAdjacencyList(); const visitedNodeIdSet = new Set([from]); const searchQueue = [{ first: 0, second: from }]; let current = undefined; while (searchQueue.length != 0) { current = searchQueue.shift(); const currentDistance = current.first; const currentNodeId = current.second; // get all neigbors of currently considered node const parentsOfCurrent = rotatedAdjList.get(currentNodeId); for (const pairOfParent of parentsOfCurrent) { const nextNodeId = pairOfParent.first; // ignore if already visited node if (visitedNodeIdSet.has(nextNodeId)) { continue; } // return if one of targets nodes was found if (targets.has(nextNodeId)) { return { distance: currentDistance + pairOfParent.second, ancestor: this.getNodeById(nextNodeId), }; } // add element to queue and visited nodes to continue search visitedNodeIdSet.add(nextNodeId); searchQueue.push({ first: currentDistance + pairOfParent.second, second: nextNodeId, }); } } return { distance: -1, ancestor: null, }; } } exports.CFG = CFG; //# sourceMappingURL=CFG.js.map