rs_parse_snapshot/
parallel.rs

1use 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; // 代表当前是第几个 edge
65    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                    // let to_node = &node_struct_arr[get_ordinal(&id_to_ordinal, to_node_id)];
95
96                    // if to_node_id != node_id {
97                    //     to_node.borrow_mut().p.push(node.id);
98                    // }
99                    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}