]> git.lizzy.rs Git - rust.git/blob - crates/ra_ide_api/src/status.rs
e11eed223c10321570acfdf7a56b6d2fc852c9e3
[rust.git] / crates / ra_ide_api / src / status.rs
1 use std::{
2     fmt,
3     iter::FromIterator,
4     sync::Arc,
5 };
6
7 use ra_syntax::{AstNode, TreeArc, SourceFile};
8 use ra_db::{
9     ParseQuery, FileTextQuery, SourceRootId,
10     salsa::{Database, debug::{DebugQueryTable, TableEntry}},
11 };
12
13 use crate::{
14     FileId, db::RootDatabase,
15     symbol_index::{SymbolIndex, LibrarySymbolsQuery},
16 };
17
18 pub(crate) fn status(db: &RootDatabase) -> String {
19     let files_stats = db.query(FileTextQuery).entries::<FilesStats>();
20     let syntax_tree_stats = db.query(ParseQuery).entries::<SyntaxTreeStats>();
21     let symbols_stats = db
22         .query(LibrarySymbolsQuery)
23         .entries::<LibrarySymbolsStats>();
24     let n_defs = {
25         let interner: &hir::HirInterner = db.as_ref();
26         interner.len()
27     };
28     format!(
29         "{}\n{}\n{}\nn_defs {}\n",
30         files_stats, symbols_stats, syntax_tree_stats, n_defs
31     )
32 }
33
34 #[derive(Default)]
35 struct FilesStats {
36     total: usize,
37     size: Bytes,
38 }
39
40 impl fmt::Display for FilesStats {
41     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
42         write!(fmt, "{} ({}) files", self.total, self.size)
43     }
44 }
45
46 impl FromIterator<TableEntry<FileId, Arc<String>>> for FilesStats {
47     fn from_iter<T>(iter: T) -> FilesStats
48     where
49         T: IntoIterator<Item = TableEntry<FileId, Arc<String>>>,
50     {
51         let mut res = FilesStats::default();
52         for entry in iter {
53             res.total += 1;
54             res.size += entry.value.unwrap().len();
55         }
56         res
57     }
58 }
59
60 #[derive(Default)]
61 struct SyntaxTreeStats {
62     total: usize,
63     retained: usize,
64     retained_size: Bytes,
65 }
66
67 impl fmt::Display for SyntaxTreeStats {
68     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
69         write!(
70             fmt,
71             "{} trees, {} ({}) retained",
72             self.total, self.retained, self.retained_size,
73         )
74     }
75 }
76
77 impl FromIterator<TableEntry<FileId, TreeArc<SourceFile>>> for SyntaxTreeStats {
78     fn from_iter<T>(iter: T) -> SyntaxTreeStats
79     where
80         T: IntoIterator<Item = TableEntry<FileId, TreeArc<SourceFile>>>,
81     {
82         let mut res = SyntaxTreeStats::default();
83         for entry in iter {
84             res.total += 1;
85             if let Some(value) = entry.value {
86                 res.retained += 1;
87                 res.retained_size += value.syntax().memory_size_of_subtree();
88             }
89         }
90         res
91     }
92 }
93
94 #[derive(Default)]
95 struct LibrarySymbolsStats {
96     total: usize,
97     size: Bytes,
98 }
99
100 impl fmt::Display for LibrarySymbolsStats {
101     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
102         write!(fmt, "{} ({}) symbols", self.total, self.size,)
103     }
104 }
105
106 impl FromIterator<TableEntry<SourceRootId, Arc<SymbolIndex>>> for LibrarySymbolsStats {
107     fn from_iter<T>(iter: T) -> LibrarySymbolsStats
108     where
109         T: IntoIterator<Item = TableEntry<SourceRootId, Arc<SymbolIndex>>>,
110     {
111         let mut res = LibrarySymbolsStats::default();
112         for entry in iter {
113             let value = entry.value.unwrap();
114             res.total += value.len();
115             res.size += value.memory_size();
116         }
117         res
118     }
119 }
120
121 #[derive(Default)]
122 struct Bytes(usize);
123
124 impl fmt::Display for Bytes {
125     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126         let bytes = self.0;
127         if bytes < 4096 {
128             return write!(f, "{} bytes", bytes);
129         }
130         let kb = bytes / 1024;
131         if kb < 4096 {
132             return write!(f, "{}kb", kb);
133         }
134         let mb = kb / 1024;
135         write!(f, "{}mb", mb)
136     }
137 }
138
139 impl std::ops::AddAssign<usize> for Bytes {
140     fn add_assign(&mut self, x: usize) {
141         self.0 += x;
142     }
143 }