1
1
use petgraph:: Graph ;
2
2
use serde:: Serialize ;
3
3
use std:: {
4
- collections:: HashMap ,
5
4
fmt,
6
5
ops:: { Deref , DerefMut } ,
7
6
} ;
7
+ use std:: hash:: RandomState ;
8
+ use std:: num:: NonZeroUsize ;
9
+ use clru:: { CLruCache , CLruCacheConfig , WeightScale } ;
10
+ use petgraph:: graph:: Edge ;
8
11
use trustify_common:: { cpe:: Cpe , purl:: Purl } ;
9
12
use trustify_entity:: relationship:: Relationship ;
10
13
use utoipa:: ToSchema ;
@@ -35,7 +38,39 @@ pub struct PackageNode {
35
38
pub document_id : String ,
36
39
pub product_name : String ,
37
40
pub product_version : String ,
41
+ pub approximate_memory_size : usize ,
38
42
}
43
+
44
+ impl PackageNode {
45
+ pub ( crate ) fn set_approximate_memory_size ( & self ) -> PackageNode {
46
+
47
+ // Is there a better way to do this? I think this will under-estimate the memory size
48
+ let approximate_memory_size =
49
+ size_of :: < PackageNode > ( ) +
50
+ self . sbom_id . len ( ) +
51
+ self . node_id . len ( ) +
52
+ self . purl . iter ( ) . fold ( 0 , |acc, purl|
53
+ // use the json string length as an approximation of the memory size
54
+ acc + serde_json:: to_string ( purl) . unwrap_or_else ( |_| "" . to_string ( ) ) . len ( )
55
+ ) +
56
+ self . cpe . iter ( ) . fold ( 0 , |acc, cpe|
57
+ // use the json string length as an approximation of the memory size
58
+ acc + serde_json:: to_string ( cpe) . unwrap_or_else ( |_| "" . to_string ( ) ) . len ( )
59
+ ) +
60
+ self . name . len ( ) +
61
+ self . version . len ( ) +
62
+ self . published . len ( ) +
63
+ self . document_id . len ( ) +
64
+ self . product_name . len ( ) +
65
+ self . product_version . len ( ) ;
66
+
67
+ PackageNode {
68
+ approximate_memory_size,
69
+ ..self . clone ( )
70
+ }
71
+ }
72
+ }
73
+
39
74
impl fmt:: Display for PackageNode {
40
75
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
41
76
write ! ( f, "{:?}" , self . purl)
@@ -151,22 +186,38 @@ impl DerefMut for DepSummary {
151
186
}
152
187
}
153
188
154
- #[ derive( Debug ) ]
155
189
pub struct GraphMap {
156
- map : HashMap < String , Graph < PackageNode , Relationship , petgraph:: Directed > > ,
190
+ map : CLruCache < String , Graph < PackageNode , Relationship , petgraph:: Directed > , RandomState , GraphMapWeightScale > ,
157
191
}
158
192
193
+ struct GraphMapWeightScale ;
194
+
195
+ impl WeightScale < String , Graph < PackageNode , Relationship , petgraph:: Directed > > for GraphMapWeightScale {
196
+ fn weight ( & self , key : & String , value : & Graph < PackageNode , Relationship , petgraph:: Directed > ) -> usize {
197
+ let mut result = key. len ( ) ;
198
+ for n in value. raw_nodes ( ) {
199
+ result + n. weight . approximate_memory_size ;
200
+ }
201
+ result = value. raw_edges ( ) . len ( ) * size_of :: < Edge < Relationship > > ( ) ;
202
+ result
203
+ }
204
+ }
205
+
206
+
159
207
impl GraphMap {
160
208
// Create a new instance of GraphMap
161
- pub fn new ( ) -> Self {
209
+ pub fn new ( cap : NonZeroUsize ) -> Self {
210
+ let x = CLruCache :: with_config (
211
+ CLruCacheConfig :: new ( cap) . with_scale ( GraphMapWeightScale { } ) ,
212
+ ) ;
162
213
GraphMap {
163
- map : HashMap :: new ( ) ,
214
+ map : x ,
164
215
}
165
216
}
166
217
167
218
// Check if the map contains a key
168
219
pub fn contains_key ( & self , key : & str ) -> bool {
169
- self . map . contains_key ( key)
220
+ self . map . contains ( key)
170
221
}
171
222
172
223
// Get the number of graphs in the map
@@ -185,27 +236,22 @@ impl GraphMap {
185
236
key : String ,
186
237
graph : Graph < PackageNode , Relationship , petgraph:: Directed > ,
187
238
) {
188
- self . map . insert ( key, graph) ;
239
+ self . map . put_with_weight ( key, graph) ;
189
240
}
190
241
191
242
// Retrieve a reference to a graph by its key (read access)
192
- pub fn get ( & self , key : & str ) -> Option < & Graph < PackageNode , Relationship , petgraph:: Directed > > {
243
+ pub fn get ( & mut self , key : & str ) -> Option < & Graph < PackageNode , Relationship , petgraph:: Directed > > {
193
244
self . map . get ( key)
194
245
}
195
246
196
- // Retrieve all sbom ids(read access)
197
- pub fn sbom_ids ( & self ) -> Vec < String > {
198
- self . map . keys ( ) . cloned ( ) . collect ( )
199
- }
200
-
201
247
// Clear all graphs from the map
202
248
pub fn clear ( & mut self ) {
203
249
self . map . clear ( ) ;
204
250
}
205
251
}
206
252
207
- impl Default for GraphMap {
208
- fn default ( ) -> Self {
209
- Self :: new ( )
210
- }
211
- }
253
+ // impl Default for GraphMap {
254
+ // fn default() -> Self {
255
+ // Self::new()
256
+ // }
257
+ // }
0 commit comments