Refactor graph class into a separate service
Remove the Graph class from the base-node service, and put it in a separate service. Change-Id: I02c1c348b592c65d82979c391cc72921930f752b
This commit is contained in:
parent
8c5d003150
commit
0163d79423
@ -28,6 +28,7 @@
|
|||||||
'horizon.app.core.openstack-service-api.ironic',
|
'horizon.app.core.openstack-service-api.ironic',
|
||||||
'horizon.app.core.openstack-service-api.glance',
|
'horizon.app.core.openstack-service-api.glance',
|
||||||
'horizon.dashboard.admin.ironic.base-node.service',
|
'horizon.dashboard.admin.ironic.base-node.service',
|
||||||
|
'horizon.dashboard.admin.ironic.graph.service',
|
||||||
'horizon.dashboard.admin.ironic.validHostNamePattern',
|
'horizon.dashboard.admin.ironic.validHostNamePattern',
|
||||||
'$log',
|
'$log',
|
||||||
'ctrl'
|
'ctrl'
|
||||||
@ -37,6 +38,7 @@
|
|||||||
ironic,
|
ironic,
|
||||||
glance,
|
glance,
|
||||||
baseNodeService,
|
baseNodeService,
|
||||||
|
graphService,
|
||||||
validHostNamePattern,
|
validHostNamePattern,
|
||||||
$log,
|
$log,
|
||||||
ctrl) {
|
ctrl) {
|
||||||
@ -131,7 +133,7 @@
|
|||||||
*/
|
*/
|
||||||
ctrl._sortDriverProperties = function() {
|
ctrl._sortDriverProperties = function() {
|
||||||
// Build dependency graph between driver properties
|
// Build dependency graph between driver properties
|
||||||
var graph = new baseNodeService.Graph();
|
var graph = new graphService.Graph();
|
||||||
|
|
||||||
// Create vertices
|
// Create vertices
|
||||||
angular.forEach(ctrl.driverProperties, function(property, name) {
|
angular.forEach(ctrl.driverProperties, function(property, name) {
|
||||||
|
@ -64,7 +64,6 @@
|
|||||||
var service = {
|
var service = {
|
||||||
DriverProperty: DriverProperty,
|
DriverProperty: DriverProperty,
|
||||||
PostfixExpr: PostfixExpr,
|
PostfixExpr: PostfixExpr,
|
||||||
Graph: Graph,
|
|
||||||
driverPropertyGroupHasRequired: driverPropertyGroupHasRequired,
|
driverPropertyGroupHasRequired: driverPropertyGroupHasRequired,
|
||||||
driverPropertyGroupsToString: driverPropertyGroupsToString,
|
driverPropertyGroupsToString: driverPropertyGroupsToString,
|
||||||
compareDriverPropertyGroups: compareDriverPropertyGroups
|
compareDriverPropertyGroups: compareDriverPropertyGroups
|
||||||
@ -570,108 +569,6 @@
|
|||||||
: [PostfixExpr.status.MALFORMED, PostfixExpr.UNDEFINED];
|
: [PostfixExpr.status.MALFORMED, PostfixExpr.UNDEFINED];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Class for representing and manipulating undirected
|
|
||||||
* graphs
|
|
||||||
*
|
|
||||||
* @property {object} vertices - Associative array of vertex objects
|
|
||||||
* indexed by property name
|
|
||||||
* @return {object} Graph
|
|
||||||
*/
|
|
||||||
function Graph() {
|
|
||||||
this.vertices = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Graph.prototype.getVertex = function(vertexName) {
|
|
||||||
var vertex = null;
|
|
||||||
if (this.vertices.hasOwnProperty(vertexName)) {
|
|
||||||
vertex = this.vertices[vertexName];
|
|
||||||
}
|
|
||||||
return vertex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Add a vertex to this graph
|
|
||||||
*
|
|
||||||
* @param {string} name - Vertex name
|
|
||||||
* @param {object} data - Vertex data
|
|
||||||
* @returns {object} - Newly created vertex
|
|
||||||
*/
|
|
||||||
Graph.prototype.addVertex = function(name, data) {
|
|
||||||
var vertex = {name: name, data: data, adjacents: []};
|
|
||||||
this.vertices[name] = vertex;
|
|
||||||
return vertex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Add an undirected edge between two vertices
|
|
||||||
*
|
|
||||||
* @param {string} vertexName1 - Name of first vertex
|
|
||||||
* @param {string} vertexName2 - Name of second vertex
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
Graph.prototype.addEdge = function(vertexName1, vertexName2) {
|
|
||||||
this.vertices[vertexName1].adjacents.push(vertexName2);
|
|
||||||
this.vertices[vertexName2].adjacents.push(vertexName1);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Depth-first-search graph traversal utility function
|
|
||||||
*
|
|
||||||
* @param {object} vertex - Root vertex from which traveral will begin.
|
|
||||||
* It is assumed that this vertex has not alreday been visited as part
|
|
||||||
* of this traversal.
|
|
||||||
* @param {object} visited - Associative array. Each named property
|
|
||||||
* corresponds to a vertex with the same name, and has boolean value
|
|
||||||
* indicating whether the vertex has been alreday visited.
|
|
||||||
* @param {object[]} component - Array of vertices that define a strongly
|
|
||||||
* connected component.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
Graph.prototype._dfsTraverse = function(vertex, visited, component) {
|
|
||||||
var graph = this;
|
|
||||||
visited[vertex.name] = true;
|
|
||||||
component.push(vertex);
|
|
||||||
|
|
||||||
/* eslint-disable no-unused-vars */
|
|
||||||
angular.forEach(vertex.adjacents, function(vertexName) {
|
|
||||||
if (!visited[vertexName]) {
|
|
||||||
graph._dfsTraverse(graph.vertices[vertexName], visited, component);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
/* eslint-enable no-unused-vars */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @description Perform a depth-first-search on a specified graph to
|
|
||||||
* find strongly connected components. A user provided function will
|
|
||||||
* be called to process each component.
|
|
||||||
*
|
|
||||||
* @param {function} componentFunc - Function called on each strongly
|
|
||||||
* connected component. Accepts aruments: array of vertex objects, and
|
|
||||||
* user-provided extra data that can be used in processing the component.
|
|
||||||
* @param {object} extra - Extra data that is passed into the component
|
|
||||||
* processing function.
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
Graph.prototype.dfs = function(componentFunc, extra) {
|
|
||||||
var graph = this;
|
|
||||||
var visited = {};
|
|
||||||
angular.forEach(
|
|
||||||
graph.vertices,
|
|
||||||
function(unused, name) {
|
|
||||||
visited[name] = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
angular.forEach(this.vertices, function(vertex, vertexName) {
|
|
||||||
if (!visited[vertexName]) {
|
|
||||||
var component = [];
|
|
||||||
graph._dfsTraverse(vertex, visited, component);
|
|
||||||
componentFunc(component, extra);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Check whether a group contains required properties
|
* @description Check whether a group contains required properties
|
||||||
*
|
*
|
||||||
|
136
ironic_ui/static/dashboard/admin/ironic/graph.service.js
Normal file
136
ironic_ui/static/dashboard/admin/ironic/graph.service.js
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 Cray Inc.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('horizon.dashboard.admin.ironic')
|
||||||
|
.factory('horizon.dashboard.admin.ironic.graph.service',
|
||||||
|
graphService);
|
||||||
|
|
||||||
|
graphService.$inject = [];
|
||||||
|
|
||||||
|
function graphService() {
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
Graph: Graph
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Class for representing and manipulating undirected
|
||||||
|
* graphs
|
||||||
|
*
|
||||||
|
* @property {object} vertices - Associative array of vertex objects
|
||||||
|
* indexed by property name
|
||||||
|
* @return {object} Graph
|
||||||
|
*/
|
||||||
|
function Graph() {
|
||||||
|
this.vertices = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Graph.prototype.getVertex = function(vertexName) {
|
||||||
|
var vertex = null;
|
||||||
|
if (this.vertices.hasOwnProperty(vertexName)) {
|
||||||
|
vertex = this.vertices[vertexName];
|
||||||
|
}
|
||||||
|
return vertex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Add a vertex to this graph
|
||||||
|
*
|
||||||
|
* @param {string} name - Vertex name
|
||||||
|
* @param {object} data - Vertex data
|
||||||
|
* @returns {object} - Newly created vertex
|
||||||
|
*/
|
||||||
|
Graph.prototype.addVertex = function(name, data) {
|
||||||
|
var vertex = {name: name, data: data, adjacents: []};
|
||||||
|
this.vertices[name] = vertex;
|
||||||
|
return vertex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Add an undirected edge between two vertices
|
||||||
|
*
|
||||||
|
* @param {string} vertexName1 - Name of first vertex
|
||||||
|
* @param {string} vertexName2 - Name of second vertex
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
Graph.prototype.addEdge = function(vertexName1, vertexName2) {
|
||||||
|
this.vertices[vertexName1].adjacents.push(vertexName2);
|
||||||
|
this.vertices[vertexName2].adjacents.push(vertexName1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Depth-first-search graph traversal utility function
|
||||||
|
*
|
||||||
|
* @param {object} vertex - Root vertex from which traveral will begin.
|
||||||
|
* It is assumed that this vertex has not alreday been visited as part
|
||||||
|
* of this traversal.
|
||||||
|
* @param {object} visited - Associative array. Each named property
|
||||||
|
* corresponds to a vertex with the same name, and has boolean value
|
||||||
|
* indicating whether the vertex has been alreday visited.
|
||||||
|
* @param {object[]} component - Array of vertices that define a strongly
|
||||||
|
* connected component.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
Graph.prototype._dfsTraverse = function(vertex, visited, component) {
|
||||||
|
var graph = this;
|
||||||
|
visited[vertex.name] = true;
|
||||||
|
component.push(vertex);
|
||||||
|
|
||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
angular.forEach(vertex.adjacents, function(vertexName) {
|
||||||
|
if (!visited[vertexName]) {
|
||||||
|
graph._dfsTraverse(graph.vertices[vertexName], visited, component);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/* eslint-enable no-unused-vars */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description Perform a depth-first-search on a specified graph to
|
||||||
|
* find strongly connected components. A user provided function will
|
||||||
|
* be called to process each component.
|
||||||
|
*
|
||||||
|
* @param {function} componentFunc - Function called on each strongly
|
||||||
|
* connected component. Accepts aruments: array of vertex objects, and
|
||||||
|
* user-provided extra data that can be used in processing the component.
|
||||||
|
* @param {object} extra - Extra data that is passed into the component
|
||||||
|
* processing function.
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
Graph.prototype.dfs = function(componentFunc, extra) {
|
||||||
|
var graph = this;
|
||||||
|
var visited = {};
|
||||||
|
angular.forEach(
|
||||||
|
graph.vertices,
|
||||||
|
function(unused, name) {
|
||||||
|
visited[name] = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
angular.forEach(this.vertices, function(vertex, vertexName) {
|
||||||
|
if (!visited[vertexName]) {
|
||||||
|
var component = [];
|
||||||
|
graph._dfsTraverse(vertex, visited, component);
|
||||||
|
componentFunc(component, extra);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
})();
|
Loading…
Reference in New Issue
Block a user