Kaynağa Gözat

重构整体数据结构,解决之前出现的问题

GnoCiYeH 1 yıl önce
ebeveyn
işleme
dfc5e29dd8

+ 32 - 18
src/executor/dep_graph/mod.rs

@@ -1,25 +1,30 @@
 #[cfg(target_os = "dragonos")]
 use drstd as std;
 
+use core::slice::SlicePattern;
 use std::cmp::PartialEq;
-use std::vec::Vec;
 use std::sync::Arc;
+use std::vec::Vec;
 
-use crate::{error::runtime_error::{RuntimeError, RuntimeErrorType}, unit::Unit};
+use crate::{
+    error::runtime_error::{RuntimeError, RuntimeErrorType},
+    manager::GLOBAL_UNIT_MANAGER,
+    unit::Unit,
+};
 
-pub struct DepGraphNode<'a> {
-    value: &'a Arc<dyn Unit>,
+pub struct DepGraphNode {
+    value: usize,
     edges: Vec<usize>,
     incoming_edges: Vec<usize>,
 }
 
-pub struct DepGraph<'a> {
-    nodes: Vec<DepGraphNode<'a>>,
-    value: Vec<&'a Arc<dyn Unit>>,
+pub struct DepGraph {
+    nodes: Vec<DepGraphNode>,
+    value: Vec<usize>,
 }
 
 // 提供拓扑排序方法,在启动服务时确定先后顺序
-impl<'a> DepGraph<'a> {
+impl DepGraph {
     fn new() -> Self {
         return DepGraph {
             nodes: Vec::new(),
@@ -27,10 +32,14 @@ impl<'a> DepGraph<'a> {
         };
     }
 
-    pub fn add_node(&mut self, value: &'a Arc<dyn Unit>) -> usize {
+    pub fn add_node(&mut self, value: usize) -> usize {
         let index = self.nodes.len();
         //如果nodes中已经有了这个value则无需重复添加,直接返回nodes中的value对应的index
-        if let Some(idx) = self.value.iter().position(|x| x.unit_id() == value.unit_id()) {
+        if let Some(idx) = self
+            .value
+            .iter()
+            .position(|x| *x == value)
+        {
             return idx;
         }
         //如果value在nodes中不存在,则添加value
@@ -46,7 +55,7 @@ impl<'a> DepGraph<'a> {
         self.nodes[from].edges.push(to);
         self.nodes[to].incoming_edges.push(from);
     }
-    pub fn topological_sort(&mut self) -> Result<Vec<&Arc<dyn Unit>>, RuntimeError> {
+    pub fn topological_sort(&mut self) -> Result<Vec<usize>, RuntimeError> {
         let mut result = Vec::new();
         let mut visited = Vec::new();
         let mut stack = Vec::new();
@@ -78,23 +87,28 @@ impl<'a> DepGraph<'a> {
         return Ok(result);
     }
 
-    fn add_edges(&mut self,unit: &'a Arc<dyn Unit>,after: &'a [Arc<dyn Unit>]) {
+    fn add_edges(&mut self, unit: usize, after: &[usize]) {
         //因为service的依赖关系规模不会很大,故先使用递归实现
         //TODO:改递归
         for target in after {
             let s = self.add_node(unit);
-            let t = self.add_node(target);
+            let t = self.add_node(*target);
             self.add_edge(s, t);
-            self.add_edges(target, target.unit_base().unit_part().after());
+
+            let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
+            let after = manager.get_unit_with_id(target).unwrap().unit_base().unit_part().after();
+
+            self.add_edges(*target,after);
         }
     }
 
-    pub fn construct_graph(unit: &'a Arc<dyn Unit>) -> DepGraph<'a> {
-        let mut graph: DepGraph<'_> = DepGraph::new();
-        graph.add_node(unit);
+    pub fn construct_graph(unit: &Arc<dyn Unit>) -> DepGraph {
+        let mut graph: DepGraph = DepGraph::new();
+        graph.add_node(unit.unit_id());
         let after = unit.unit_base().unit_part().after();
+
         //递归添加边来构建图
-        graph.add_edges(unit, after);
+        graph.add_edges(unit.unit_id(), after);
         return graph;
     }
 }

+ 3 - 3
src/executor/mod.rs

@@ -9,7 +9,7 @@ use std::sync::Arc;
 
 use crate::{
     error::runtime_error::{RuntimeError, RuntimeErrorType},
-    unit::Unit,
+    unit::Unit, manager::GLOBAL_UNIT_MANAGER,
 };
 
 use self::dep_graph::DepGraph;
@@ -23,9 +23,9 @@ impl Executor {
         let mut graph = DepGraph::construct_graph(unit);
 
         let sort_ret = graph.topological_sort()?;
-
+        let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
         for u in sort_ret {
-            if let Err(e) = u.run() {
+            if let Err(e) = manager.get_unit_with_id(&u).unwrap().run() {
                 return Err(e);
             }
         }

+ 4 - 2
src/executor/service_executor/mod.rs

@@ -13,12 +13,14 @@ pub struct ServiceExecutor;
 
 impl ServiceExecutor {
     pub fn exec(service: &ServiceUnit) -> Result<(), RuntimeError> {
+        let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
         //处理conflict
         let conflicts = service.unit_base().unit_part().conflicts();
         for u in conflicts {
             // 如果有冲突项enable的时候,该unit不能启动
-            if *u.unit_base().state() == UnitState::Enabled {
-                eprintln!("{}: Service startup failed: conflict unit", u.unit_base().unit_part().description());
+            let unit = manager.get_unit_with_id(u).unwrap();
+            if *unit.unit_base().state() == UnitState::Enabled {
+                eprintln!("{}: Service startup failed: conflict unit", unit.unit_base().unit_part().description());
                 return Err(RuntimeError::new(RuntimeErrorType::ExecFailed));
             }
         }

+ 15 - 4
src/manager/mod.rs

@@ -28,10 +28,10 @@ impl RunnnigUnit {
 
 pub struct UnitManager {
     // 通过unit_id映射unit
-    pub id_to_unit: HashMap<usize, Arc<dyn Unit>>,
+    pub id_to_unit: HashMap<usize,Arc<dyn Unit>>,
 
     // 通过path的hash值来映射Unit
-    pub path_to_unit: HashMap<u64,Arc<dyn Unit>>,
+    pub path_to_unit: HashMap<u64,usize>,
 
     pub running_table: Vec<RunnnigUnit>
 }
@@ -39,7 +39,7 @@ pub struct UnitManager {
 unsafe impl Sync for UnitManager {}
 
 impl UnitManager {
-    pub fn insert_into_path_table(&mut self,path: &str,unit: Arc<dyn Unit>){
+    pub fn insert_into_path_table(&mut self,path: &str,unit: usize){
         let mut hasher = DefaultHasher::new();
         path.hash(&mut hasher);
         let hash = hasher.finish();
@@ -57,6 +57,17 @@ impl UnitManager {
         let mut hasher = DefaultHasher::new();
         path.hash(&mut hasher);
         let hash = hasher.finish();
-        self.path_to_unit.get(&hash)
+        let id = match self.path_to_unit.get(&hash) {
+            Some(id) => id,
+            None => {
+                return None;
+            }
+        };
+
+        self.id_to_unit.get(id)
+    }
+
+    pub fn get_unit_with_id(&self,id: &usize) -> Option<&Arc<dyn Unit>>{
+        self.id_to_unit.get(&id)
     }
 }

+ 7 - 10
src/parse/mod.rs

@@ -201,13 +201,11 @@ impl UnitParser {
     pub fn parse<T: Unit + Default + Clone + 'static>(
         path: &str,
         unit_type: UnitType,
-    ) -> Result<Arc<T>, ParseError> {
+    ) -> Result<usize, ParseError> {
         let manager = GLOBAL_UNIT_MANAGER.read().unwrap();
         if manager.contants_path(path) {
             let unit = manager.get_unit_with_path(path).unwrap();
-            let any = unit.as_any();
-            let ret: Arc<T> = Arc::new(any.downcast_ref::<T>().unwrap().clone());
-            return Ok(ret);
+            return Ok(unit.unit_id());
         }
         drop(manager);
 
@@ -328,14 +326,13 @@ impl UnitParser {
             i += 1;
         }
         unit.set_unit_base(unit_base);
-        unit.set_unit_id();
-        let dret: Arc<dyn Unit> = Arc::new(unit.clone());
+        let id = unit.set_unit_id();
+        let dret: Arc<dyn Unit> = Arc::new(unit);
 
         let mut manager = GLOBAL_UNIT_MANAGER.write().unwrap();
-        manager.id_to_unit.insert(dret.unit_id(), dret.clone());
-        manager.insert_into_path_table(path, dret);
+        manager.id_to_unit.insert(dret.unit_id(), dret);
+        manager.insert_into_path_table(path, id);
 
-        let ret = Arc::new(unit);
-        return Ok(ret);
+        return Ok(id);
     }
 }

+ 2 - 2
src/parse/parse_util/mod.rs

@@ -440,7 +440,7 @@ impl UnitParseUtil {
     /// @param path 需解析的文件
     ///
     /// @return 解析成功则返回Ok(Arc<dyn Unit>),否则返回Err
-    pub fn parse_unit_no_type(path: &str) -> Result<Arc<dyn Unit>, ParseError> {
+    pub fn parse_unit_no_type(path: &str) -> Result<usize, ParseError> {
         let idx = match path.rfind('.') {
             Some(val) => val,
             None => {
@@ -456,7 +456,7 @@ impl UnitParseUtil {
         let suffix = &path[idx + 1..];
 
         //通过文件后缀分发给不同类型的Unit解析器解析
-        let unit: Arc<dyn Unit> = match suffix {
+        let unit = match suffix {
             //TODO: 目前为递归,后续应考虑从DragonReach管理的Unit表中寻找是否有该Unit,并且通过记录消除递归
             "service" => {
                 UnitParser::parse::<ServiceUnit>(path, UnitType::Service)?

+ 22 - 20
src/unit/mod.rs

@@ -86,8 +86,10 @@ pub trait Unit: Sync + Send + Debug {
     /// ## 设置unit_id
     ///
     /// ### return OK(())/Err
-    fn set_unit_id(&mut self) {
-        self.mut_unit_base().set_id(generate_unit_id());
+    fn set_unit_id(&mut self) -> usize {
+        let ret = generate_unit_id();
+        self.mut_unit_base().set_id(ret);
+        ret
     }
 }
 
@@ -220,14 +222,14 @@ pub struct Url {
 pub struct UnitPart {
     description: String,
     documentation: Vec<Url>,
-    requires: Vec<Arc<dyn Unit>>,
-    wants: Vec<Arc<dyn Unit>>,
-    after: Vec<Arc<dyn Unit>>,
-    before: Vec<Arc<dyn Unit>>,
-    binds_to: Vec<Arc<dyn Unit>>,
-    part_of: Vec<Arc<dyn Unit>>,
-    on_failure: Vec<Arc<dyn Unit>>,
-    conflicts: Vec<Arc<dyn Unit>>,
+    requires: Vec<usize>,
+    wants: Vec<usize>,
+    after: Vec<usize>,
+    before: Vec<usize>,
+    binds_to: Vec<usize>,
+    part_of: Vec<usize>,
+    on_failure: Vec<usize>,
+    conflicts: Vec<usize>,
 }
 
 impl Default for UnitPart {
@@ -337,35 +339,35 @@ impl UnitPart {
         &self.documentation
     }
 
-    pub fn requires(&self) -> &[Arc<dyn Unit>] {
+    pub fn requires(&self) -> &[usize] {
         &self.requires
     }
 
-    pub fn wants(&self) -> &[Arc<dyn Unit>] {
+    pub fn wants(&self) -> &[usize] {
         &self.wants
     }
 
-    pub fn after(&self) -> &[Arc<dyn Unit>] {
+    pub fn after(&self) -> &[usize] {
         &self.after
     }
 
-    pub fn before(&self) -> &[Arc<dyn Unit>] {
+    pub fn before(&self) -> &[usize] {
         &self.before
     }
 
-    pub fn binds_to(&self) -> &[Arc<dyn Unit>] {
+    pub fn binds_to(&self) -> &[usize] {
         &self.binds_to
     }
 
-    pub fn part_of(&self) -> &[Arc<dyn Unit>] {
+    pub fn part_of(&self) -> &[usize] {
         &self.part_of
     }
 
-    pub fn on_failure(&self) -> &[Arc<dyn Unit>] {
+    pub fn on_failure(&self) -> &[usize] {
         &self.on_failure
     }
 
-    pub fn conflicts(&self) -> &[Arc<dyn Unit>] {
+    pub fn conflicts(&self) -> &[usize] {
         &self.conflicts
     }
 }
@@ -375,7 +377,7 @@ impl UnitPart {
 pub struct InstallPart {
     wanted_by: Vec<Arc<TargetUnit>>,
     requires_by: Vec<Arc<TargetUnit>>,
-    also: Vec<Arc<dyn Unit>>,
+    also: Vec<usize>,
     alias: String,
 }
 
@@ -435,7 +437,7 @@ impl InstallPart {
         &self.requires_by
     }
 
-    pub fn also(&self) -> &[Arc<dyn Unit>] {
+    pub fn also(&self) -> &[usize] {
         &self.also
     }