Merge var storage of different paths when meet path join. The default merge operation is Union.
(
&mut self,
path_vec: Vec<usize>,
merge_callback: F,
)
| 616 | |
| 617 | /// Merge var storage of different paths when meet path join. The default merge operation is Union. |
| 618 | fn path_join<F: Fn(Vec<Symbol<T>>) -> Symbol<T>>( |
| 619 | &mut self, |
| 620 | path_vec: Vec<usize>, |
| 621 | merge_callback: F, |
| 622 | ) -> Result<()> { |
| 623 | let mut merge_store: Storage<T> = HashMap::new(); |
| 624 | let mut changed_var: HashSet<&VarName> = HashSet::new(); |
| 625 | // find the same vars but have different symbols in paths. |
| 626 | for path_id in &path_vec { |
| 627 | let path_store = self |
| 628 | .path_storage |
| 629 | .get(path_id) |
| 630 | .ok_or_else(|| eyre::eyre!("path id {path_id} not found."))?; |
| 631 | for (var_name, sym) in path_store.iter() { |
| 632 | if merge_store.contains_key(var_name) { |
| 633 | //log::trace!("The merge store already contains {var_name:?}"); |
| 634 | let exist_sym = merge_store.get(var_name).unwrap(); |
| 635 | // find different symbols |
| 636 | if !exist_sym.eq(sym) { |
| 637 | changed_var.insert(var_name); |
| 638 | } |
| 639 | } else { |
| 640 | merge_store.insert(var_name.clone(), sym.clone()); |
| 641 | } |
| 642 | } |
| 643 | } |
| 644 | // merge the symbols from different paths to a single symbol |
| 645 | for var in changed_var { |
| 646 | let mut wait_to_merge = vec![]; |
| 647 | for path_id in &path_vec { |
| 648 | let path_store = self |
| 649 | .path_storage |
| 650 | .get(path_id) |
| 651 | .ok_or_else(|| eyre::eyre!("path id {path_id} not found."))?; |
| 652 | if path_store.contains_key(var) { |
| 653 | let value = path_store.get(var).unwrap(); |
| 654 | wait_to_merge.push(value.clone()); |
| 655 | } |
| 656 | } |
| 657 | log::trace!("merge symbol for var: {var:?}"); |
| 658 | let new_sym = (merge_callback)(wait_to_merge); |
| 659 | merge_store.insert(var.clone(), new_sym); |
| 660 | } |
| 661 | |
| 662 | for (_var, sym) in merge_store.iter_mut() { |
| 663 | sym.get_data_mut().refine()?; |
| 664 | } |
| 665 | // create new path id. |
| 666 | self.path_id = self.new_path_id(); |
| 667 | // initial the storage for the new path |
| 668 | self.path_storage.insert(self.path_id, merge_store); |
| 669 | Ok(()) |
| 670 | } |
| 671 | } |
| 672 | |
| 673 | #[derive(Default)] |
no test coverage detected