mod.rs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. use core::slice::SlicePattern;
  2. use std::{
  3. fs::File,
  4. io::{BufRead, BufReader},
  5. };
  6. use crate::{
  7. error::parse_error::{ParseError, ParseErrorType},
  8. unit::UnitType,
  9. };
  10. use super::{parse_util::UnitParseUtil, UnitParser};
  11. pub struct GraphNode {
  12. value: String,
  13. edges: Vec<usize>,
  14. incoming_edges: Vec<usize>,
  15. }
  16. pub struct Graph {
  17. total_edge: u32,
  18. max_edge: u32,
  19. nodes: Vec<GraphNode>,
  20. value: Vec<String>,
  21. }
  22. impl Graph {
  23. fn new() -> Self {
  24. return Graph {
  25. max_edge: 0,
  26. total_edge: 0,
  27. nodes: Vec::new(),
  28. value: Vec::new(),
  29. };
  30. }
  31. pub fn add_node(&mut self, value: &String) -> usize {
  32. let index = self.nodes.len();
  33. //如果nodes中已经有了这个value则无需重复添加,直接返回nodes中的value对应的index
  34. if let Some(idx) = self.value.iter().position(|x| *x == *value) {
  35. return idx;
  36. }
  37. //如果value在nodes中不存在,则添加value
  38. self.nodes.push(GraphNode {
  39. value: value.to_string(),
  40. edges: Vec::new(),
  41. incoming_edges: Vec::new(),
  42. });
  43. self.value.push(value.to_string());
  44. return index;
  45. }
  46. pub fn add_edge(&mut self, from: usize, to: usize) {
  47. self.total_edge += 1;
  48. self.nodes[from].edges.push(to);
  49. self.nodes[to].incoming_edges.push(from);
  50. }
  51. pub fn topological_sort(&mut self) -> Result<Vec<String>, ParseError> {
  52. let mut result = Vec::new();
  53. let mut visited = Vec::new();
  54. let mut stack = Vec::new();
  55. for (i, node) in self.nodes.iter().enumerate() {
  56. if node.incoming_edges.len() == 0 {
  57. stack.push(i);
  58. }
  59. }
  60. while stack.len() > 0 {
  61. let index = stack.pop().unwrap();
  62. if visited.contains(&index) {
  63. continue;
  64. }
  65. visited.push(index);
  66. result.push(self.nodes[index].value.clone());
  67. let len = self.nodes[index].edges.len();
  68. for i in 0..len {
  69. let edge = self.nodes[index].edges[i];
  70. self.nodes[edge].incoming_edges.retain(|&x| x != index);
  71. if self.nodes[edge].incoming_edges.len() == 0 {
  72. stack.push(edge);
  73. }
  74. }
  75. }
  76. if result.len() != self.nodes.len() {
  77. return Err(ParseError::new(
  78. ParseErrorType::ECircularDependency,
  79. "".to_string(),
  80. 0,
  81. ));
  82. }
  83. result.reverse();
  84. return Ok(result);
  85. }
  86. fn add_edges(&mut self, path: &String, after: Vec<String>) {
  87. //因为service的依赖关系规模不会很大,故先使用递归实现
  88. //TODO:改递归
  89. for target in after {
  90. let s = self.add_node(&path);
  91. let t = self.add_node(&target);
  92. self.add_edge(s, t);
  93. if self.total_edge > self.max_edge {
  94. return;
  95. }
  96. self.add_edges(&target, Self::parse_after(&target));
  97. }
  98. }
  99. pub fn construct_graph(unit: String) -> Result<Graph, ParseError> {
  100. //计算整个依赖图中的节点数
  101. let mut node_num = 1;
  102. let mut dep = Vec::new();
  103. Self::get_node_num(&unit, &mut dep, &mut node_num);
  104. let mut graph: Graph = Graph::new();
  105. graph.max_edge = node_num * (node_num - 1);
  106. graph.add_node(&unit);
  107. let after = Self::parse_after(&unit);
  108. //递归添加边来构建图
  109. graph.add_edges(&unit, after);
  110. if graph.max_edge < graph.total_edge {
  111. return Err(ParseError::new(
  112. ParseErrorType::ECircularDependency,
  113. unit,
  114. 0,
  115. ));
  116. }
  117. return Ok(graph);
  118. }
  119. pub fn parse_after(path: &String) -> Vec<String> {
  120. let mut ret = Vec::new();
  121. let file = File::open(path).expect("Failed to open file");
  122. let reader = BufReader::new(file);
  123. let mut lines_with_after = Vec::new();
  124. for line_result in reader.lines() {
  125. if let Ok(line) = line_result {
  126. if line.starts_with("After") {
  127. lines_with_after.push(line);
  128. }
  129. }
  130. }
  131. for line in lines_with_after {
  132. let after = &line.split('=').collect::<Vec<&str>>()[1];
  133. let units = after.split_whitespace().collect::<Vec<&str>>();
  134. for unit in units {
  135. ret.push(String::from(unit));
  136. }
  137. }
  138. ret
  139. }
  140. /// ## 获取到unit文件依赖图节点数
  141. ///
  142. /// ### param file_path unit文件路径
  143. ///
  144. /// ### dependencies 缓存after依赖的容器
  145. ///
  146. /// ### total_after_count 返回节点数
  147. ///
  148. /// ### return
  149. fn get_node_num(
  150. file_path: &str,
  151. dependencies: &mut Vec<String>,
  152. total_after_count: &mut u32,
  153. ) -> Result<(), ParseError> {
  154. let reader = UnitParser::get_unit_reader(file_path, UnitType::Unknown)?;
  155. let mut current_after_count = 0;
  156. for line_result in reader.lines() {
  157. if let Ok(line) = line_result {
  158. if line.starts_with("After=") {
  159. let dependencies_str = &line[6..];
  160. let dependency_list: Vec<&str> = dependencies_str.split_whitespace().collect();
  161. for dependency in dependency_list {
  162. if dependencies.contains(&dependency.to_string()) {
  163. // 循环依赖检查
  164. continue;
  165. }
  166. dependencies.push(dependency.to_string());
  167. // 递归解析依赖链
  168. Self::get_node_num(dependency, dependencies, total_after_count)?;
  169. }
  170. current_after_count += 1;
  171. }
  172. }
  173. }
  174. *total_after_count += current_after_count;
  175. Ok(())
  176. }
  177. }