rs_parse_snapshot/
parallel.rs1use crate::calculate::calculate::{calculate_constructor, calculate_source};
2use crate::common::{
3 find_char_boundary, get_edges_property, get_node_property, get_ordinal, read_to_snapshot,
4};
5use crate::define::define::{Edge, Node, RcNode, EDGE_FIELDS};
6use crate::log::log_time;
7use chrono::prelude::*;
8use rayon::prelude::*;
9use std::cell::RefCell;
10use std::collections::HashMap;
11use std::rc::Rc;
12use yuuang_dominators::Graph;
13pub fn parse_snapshot_with_node_parallel(
14 path: &str,
15 graph: &mut Graph<usize, usize>,
16) -> (Vec<RcNode>, HashMap<usize, usize>) {
17 println!("use multiple threads");
18 let mut id_to_ordinal = HashMap::new();
19 let (snapshot, node_fields_len) = read_to_snapshot(path);
20 let now = Local::now().timestamp_millis();
21 let nodes = snapshot.snapshot.node_count;
22
23 let mut node_struct_arr: Vec<Node> = (0..nodes)
24 .into_par_iter()
25 .map(|index| {
26 let node_start = index * node_fields_len;
27 let node_type = String::from(get_node_property(node_start, 0, &snapshot));
28 let name = String::from(get_node_property(node_start, 1, &snapshot));
29 let constructor = calculate_constructor(&node_type, &name);
30 let size = usize::from(get_node_property(node_start, 3, &snapshot));
31 let mut node = Node {
32 nt: node_type,
33 name: name,
34 id: usize::from(get_node_property(node_start, 2, &snapshot)),
35 ec: usize::from(get_node_property(node_start, 4, &snapshot)),
36 size: size,
37 rs: size,
38 edges: vec![],
39 p: vec![],
40 c: constructor,
41 se: None,
42 };
43 let name = &mut node.name;
44 node.name = if name.len() > 500 {
45 let idx = find_char_boundary(name.as_str(), 500);
46 name.truncate(idx);
47 name.clone()
48 } else {
49 name.clone()
50 };
51
52 node
53 })
54 .collect();
55 node_struct_arr.iter().enumerate().for_each(|(idx, node)| {
56 id_to_ordinal.insert(node.id, idx);
57 graph.add_node(node.id);
58 });
59 log_time(
60 "calculate nodes spend",
61 Local::now().timestamp_millis() - now,
62 );
63
64 let mut edge_index = 0; let mut edge_index_map = HashMap::new();
66 node_struct_arr
67 .iter()
68 .enumerate()
69 .for_each(|(index, node)| {
70 edge_index_map.insert(index, edge_index);
71 edge_index += node.ec
72 });
73 let now = Local::now().timestamp_millis();
74 node_struct_arr
75 .par_iter_mut()
76 .enumerate()
77 .for_each(|(node_index, node)| {
78 let node_id = node.id;
79 let edge_count = node.ec;
80 let edges = (0..edge_count)
81 .map(|edge_index| {
82 let node_edge_index = edge_index_map.get(&node_index).unwrap();
83 let edge_start = (edge_index + node_edge_index) * EDGE_FIELDS.len();
84 let edge_type = String::from(get_edges_property(edge_start, 0, &snapshot));
85 let is_weak_retainer = edge_type == String::from("weak");
86 let edge = Edge {
87 et: edge_type,
88 ni: String::from(get_edges_property(edge_start, 1, &snapshot)),
89 tn: usize::from(get_edges_property(edge_start, 2, &snapshot)),
90 isw: if is_weak_retainer { 1 } else { 0 },
91 isr: 1,
92 };
93 let to_node_id = edge.tn;
94 edge
100 })
101 .collect();
102 node.edges = edges;
103 });
104 log_time(
105 "calculate edge spend",
106 Local::now().timestamp_millis() - now,
107 );
108 let now = Local::now().timestamp_millis();
109 let node_struct_arr: Vec<RcNode> = node_struct_arr
110 .into_iter()
111 .map(|node| {
112 return Rc::new(RefCell::new(node));
113 })
114 .collect();
115 log_time(
116 "calculate node to rc node spend",
117 Local::now().timestamp_millis() - now,
118 );
119
120 let now = Local::now().timestamp_millis();
121 calculate_source(&node_struct_arr, &id_to_ordinal);
122 log_time(
123 "calculate source spend",
124 Local::now().timestamp_millis() - now,
125 );
126
127 (node_struct_arr, id_to_ordinal)
128}