16
16
//! Synapse instance's database. Specifically, it aims to reduce the number of
17
17
//! rows that a given room takes up in the `state_groups_state` table.
18
18
19
- mod compressor;
20
- mod database;
21
-
22
19
#[ global_allocator]
23
20
static GLOBAL : jemallocator:: Jemalloc = jemallocator:: Jemalloc ;
24
21
25
- use compressor:: Compressor ;
26
- use database:: PGEscape ;
27
-
28
22
use clap:: {
29
23
crate_authors, crate_description, crate_name, crate_version, value_t_or_exit, App , Arg ,
30
24
} ;
@@ -34,6 +28,12 @@ use state_map::StateMap;
34
28
use std:: { collections:: BTreeMap , fs:: File , io:: Write , str:: FromStr } ;
35
29
use string_cache:: DefaultAtom as Atom ;
36
30
31
+ mod compressor;
32
+ mod database;
33
+
34
+ use compressor:: Compressor ;
35
+ use database:: PGEscape ;
36
+
37
37
/// An entry for a state group. Consists of an (optional) previous group and the
38
38
/// delta from that previous group (or the full state if no previous group)
39
39
#[ derive( Default , Debug , Clone , PartialEq , Eq ) ]
@@ -42,33 +42,6 @@ pub struct StateGroupEntry {
42
42
state_map : StateMap < Atom > ,
43
43
}
44
44
45
- /// Gets the full state for a given group from the map (of deltas)
46
- fn collapse_state_maps ( map : & BTreeMap < i64 , StateGroupEntry > , state_group : i64 ) -> StateMap < Atom > {
47
- let mut entry = & map[ & state_group] ;
48
- let mut state_map = StateMap :: new ( ) ;
49
-
50
- let mut stack = vec ! [ state_group] ;
51
-
52
- while let Some ( prev_state_group) = entry. prev_state_group {
53
- stack. push ( prev_state_group) ;
54
- if !map. contains_key ( & prev_state_group) {
55
- panic ! ( "Missing {}" , prev_state_group) ;
56
- }
57
- entry = & map[ & prev_state_group] ;
58
- }
59
-
60
- for sg in stack. iter ( ) . rev ( ) {
61
- state_map. extend (
62
- map[ & sg]
63
- . state_map
64
- . iter ( )
65
- . map ( |( ( t, s) , e) | ( ( t, s) , e. clone ( ) ) ) ,
66
- ) ;
67
- }
68
-
69
- state_map
70
- }
71
-
72
45
/// Helper struct for parsing the `level_sizes` argument.
73
46
struct LevelSizes ( Vec < usize > ) ;
74
47
@@ -89,6 +62,7 @@ impl FromStr for LevelSizes {
89
62
}
90
63
}
91
64
65
+ /// Contains configuration information for this run of the compressor
92
66
pub struct Config {
93
67
db_url : String ,
94
68
output_file : Option < File > ,
@@ -100,6 +74,7 @@ pub struct Config {
100
74
}
101
75
102
76
impl Config {
77
+ /// Build up config from command line arguments
103
78
pub fn parse_arguments ( ) -> Config {
104
79
let matches = App :: new ( crate_name ! ( ) )
105
80
. version ( crate_version ! ( ) )
@@ -199,9 +174,22 @@ impl Config {
199
174
}
200
175
}
201
176
202
- pub fn run ( mut config : Config ) {
203
- // let mut config = Config::parse_arguments();
177
+ /// Runs through the steps of the compression:
178
+ ///
179
+ /// - Fetches current state groups for a room and their predecessors
180
+ /// - Outputs #state groups and #lines in table they occupy
181
+ /// - Runs the compressor to produce a new predecessor mapping
182
+ /// - Outputs #lines in table that the new mapping would occupy
183
+ /// - Outputs info about how the compressor got on
184
+ /// - Checks that number of lines saved is greater than threshold
185
+ /// - Ensures new mapping doesn't affect actual state contents
186
+ /// - Produces SQL code to carry out changes and saves it to file
187
+ ///
188
+ /// # Arguments
189
+ ///
190
+ /// * `config: Config` - A Config struct that controlls the run
204
191
192
+ pub fn run ( mut config : Config ) {
205
193
// First we need to get the current state groups
206
194
println ! ( "Fetching state from DB for room '{}'..." , config. room_id) ;
207
195
@@ -272,6 +260,17 @@ pub fn run(mut config: Config) {
272
260
output_sql ( & mut config, & state_group_map, & new_state_group_map) ;
273
261
}
274
262
263
+ /// Produces SQL code to carry out changes and saves it to file
264
+ ///
265
+ /// # Arguments
266
+ ///
267
+ /// * `config` - A Config struct that contains information
268
+ /// about the run. It's mutable because it contains
269
+ /// the pointer to the output file (which needs to
270
+ /// be mutable for the file to be written to)
271
+ /// * `old_map` - The state group data originally in the database
272
+ /// * `new_map` - The state group data generated by the compressor to
273
+ /// replace replace the old contents
275
274
fn output_sql (
276
275
config : & mut Config ,
277
276
old_map : & BTreeMap < i64 , StateGroupEntry > ,
@@ -353,6 +352,20 @@ fn output_sql(
353
352
pb. finish ( ) ;
354
353
}
355
354
355
+ /// Compares two sets of state groups
356
+ ///
357
+ /// A state group entry contains a predecessor state group and a delta.
358
+ /// The complete contents of a certain state group can be calculated by
359
+ /// following this chain of predecessors back to some empty state and
360
+ /// combining all the deltas together. This is called "collapsing".
361
+ ///
362
+ /// This function confirms that two state groups mappings lead to the
363
+ /// exact same entries for each state group after collapsing them down.
364
+ ///
365
+ /// # Arguments
366
+ /// * `old_map` - The state group data currently in the database
367
+ /// * `new_map` - The state group data that the old_map is being compared
368
+ /// to
356
369
fn check_that_maps_match (
357
370
old_map : & BTreeMap < i64 , StateGroupEntry > ,
358
371
new_map : & BTreeMap < i64 , StateGroupEntry > ,
@@ -391,3 +404,30 @@ fn check_that_maps_match(
391
404
392
405
println ! ( "New state map matches old one" ) ;
393
406
}
407
+
408
+ /// Gets the full state for a given group from the map (of deltas)
409
+ fn collapse_state_maps ( map : & BTreeMap < i64 , StateGroupEntry > , state_group : i64 ) -> StateMap < Atom > {
410
+ let mut entry = & map[ & state_group] ;
411
+ let mut state_map = StateMap :: new ( ) ;
412
+
413
+ let mut stack = vec ! [ state_group] ;
414
+
415
+ while let Some ( prev_state_group) = entry. prev_state_group {
416
+ stack. push ( prev_state_group) ;
417
+ if !map. contains_key ( & prev_state_group) {
418
+ panic ! ( "Missing {}" , prev_state_group) ;
419
+ }
420
+ entry = & map[ & prev_state_group] ;
421
+ }
422
+
423
+ for sg in stack. iter ( ) . rev ( ) {
424
+ state_map. extend (
425
+ map[ & sg]
426
+ . state_map
427
+ . iter ( )
428
+ . map ( |( ( t, s) , e) | ( ( t, s) , e. clone ( ) ) ) ,
429
+ ) ;
430
+ }
431
+
432
+ state_map
433
+ }
0 commit comments