1
- mod models ;
1
+ mod counter ;
2
2
mod filesystem;
3
+ mod models;
3
4
mod users;
4
- mod counter;
5
5
6
+ use crate :: models:: definitions:: DbModel ;
6
7
use clap:: Parser ;
7
8
use rayon:: prelude:: * ;
8
- use crate :: models:: definitions:: DbModel ;
9
9
10
10
#[ derive( clap:: Parser , Default , Debug ) ]
11
- #[ clap(
12
- author = "Dheshan Mohandass" ,
13
- version,
14
- about
15
- ) ]
11
+ #[ clap( author = "Dheshan Mohandass" , version, about) ]
16
12
/// A CLI tool for tracking disk usage.
17
13
struct Arguments {
18
14
/// The root directory to track.
19
15
#[ clap( short, long) ]
20
- root_dir : String ,
16
+ root_dir : String ,
21
17
/// Enable debug mode.
22
18
#[ clap( short, long) ]
23
- debug : bool ,
19
+ debug : bool ,
24
20
}
25
21
26
- async fn ensure_user_exists ( owner : Option < i32 > , pool : std:: sync:: Arc < sqlx:: Pool < sqlx:: Postgres > > ) -> Result < ( ) , sqlx:: Error > {
22
+ async fn ensure_user_exists (
23
+ owner : Option < i32 > ,
24
+ pool : std:: sync:: Arc < sqlx:: Pool < sqlx:: Postgres > > ,
25
+ cache : std:: sync:: Arc < dashmap:: DashSet < i32 > > ,
26
+ ) -> Result < ( ) , sqlx:: Error > {
27
27
if let Some ( owner_id) = owner {
28
+ // Check if the user exists in the cache
29
+ if let Some ( _) = cache. get ( & owner_id) {
30
+ return Ok ( ( ) ) ;
31
+ }
28
32
let select_user_where_clause = format ! ( "WHERE user_id = {}" , owner_id) ;
29
- let user = models:: definitions:: User :: select_where ( & pool, & select_user_where_clause) . await . unwrap_or_default ( ) ;
30
-
33
+ let user = models:: definitions:: User :: select_where ( & pool, & select_user_where_clause)
34
+ . await
35
+ . unwrap_or_default ( ) ;
36
+
31
37
if user. is_empty ( ) {
32
38
let user = models:: definitions:: User {
33
39
user_id : owner_id,
34
- username : users:: username:: get_username ( owner_id as u32 )
40
+ username : users:: username:: get_username ( owner_id as u32 ) ,
35
41
} ;
36
42
user. insert ( & pool) . await ?;
37
43
}
44
+
45
+ cache. insert ( owner_id) ;
38
46
}
39
47
Ok ( ( ) )
40
48
}
41
49
42
- fn process_directory ( entry : walkdir:: DirEntry , pool : std:: sync:: Arc < sqlx:: Pool < sqlx:: Postgres > > , handle : tokio:: runtime:: Handle ) {
50
+ fn process_directory (
51
+ entry : walkdir:: DirEntry ,
52
+ pool : std:: sync:: Arc < sqlx:: Pool < sqlx:: Postgres > > ,
53
+ handle : tokio:: runtime:: Handle ,
54
+ cache : std:: sync:: Arc < dashmap:: DashSet < i32 > > ,
55
+ ) {
43
56
let dir_path = entry. path ( ) ;
44
57
let owner = filesystem:: fetch:: owner ( dir_path) . map ( |x| x as i32 ) ;
45
58
let parent_dir = dir_path. parent ( ) . unwrap_or ( std:: path:: Path :: new ( "/" ) ) ;
@@ -51,7 +64,7 @@ fn process_directory(entry: walkdir::DirEntry, pool: std::sync::Arc<sqlx::Pool<s
51
64
} ;
52
65
53
66
handle. block_on ( async move {
54
- if let Err ( e) = ensure_user_exists ( owner, pool. clone ( ) ) . await {
67
+ if let Err ( e) = ensure_user_exists ( owner, pool. clone ( ) , cache . clone ( ) ) . await {
55
68
log:: error!( "Failed to insert user: {:?}" , e) ;
56
69
return ;
57
70
}
@@ -61,7 +74,12 @@ fn process_directory(entry: walkdir::DirEntry, pool: std::sync::Arc<sqlx::Pool<s
61
74
} ) ;
62
75
}
63
76
64
- fn process_file ( entry : walkdir:: DirEntry , pool : std:: sync:: Arc < sqlx:: Pool < sqlx:: Postgres > > , handle : tokio:: runtime:: Handle ) {
77
+ fn process_file (
78
+ entry : walkdir:: DirEntry ,
79
+ pool : std:: sync:: Arc < sqlx:: Pool < sqlx:: Postgres > > ,
80
+ handle : tokio:: runtime:: Handle ,
81
+ cache : std:: sync:: Arc < dashmap:: DashSet < i32 > > ,
82
+ ) {
65
83
let file_path = entry. path ( ) ;
66
84
let owner = filesystem:: fetch:: owner ( file_path) . map ( |x| x as i32 ) ;
67
85
let file_size = filesystem:: fetch:: file_size ( file_path) . unwrap_or_default ( ) ;
@@ -78,7 +96,7 @@ fn process_file(entry: walkdir::DirEntry, pool: std::sync::Arc<sqlx::Pool<sqlx::
78
96
} ;
79
97
80
98
handle. block_on ( async move {
81
- if let Err ( e) = ensure_user_exists ( owner, pool. clone ( ) ) . await {
99
+ if let Err ( e) = ensure_user_exists ( owner, pool. clone ( ) , cache . clone ( ) ) . await {
82
100
log:: error!( "Failed to insert user: {:?}" , e) ;
83
101
return ;
84
102
}
@@ -143,7 +161,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
143
161
let pool_c = std:: sync:: Arc :: clone ( & pool) ;
144
162
let handle_c: tokio:: runtime:: Handle = handle. clone ( ) ;
145
163
counter:: logger:: logger_thread ( handle_c, pool_c) . await ;
146
-
164
+
165
+ let cache: std:: sync:: Arc < dashmap:: DashSet < i32 > > = std:: sync:: Arc :: new ( dashmap:: DashSet :: new ( ) ) ;
166
+
147
167
log:: info!( "Starting disk usage tracking for: {}" , root_dir) ;
148
168
walkdir:: WalkDir :: new ( root_dir)
149
169
. into_iter ( )
@@ -153,9 +173,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
153
173
let pool = std:: sync:: Arc :: clone ( & pool) ;
154
174
let handle = handle. clone ( ) ;
155
175
if entry. file_type ( ) . is_dir ( ) {
156
- process_directory ( entry, pool, handle) ;
176
+ process_directory ( entry, pool, handle, cache . clone ( ) ) ;
157
177
} else if entry. file_type ( ) . is_file ( ) {
158
- process_file ( entry, pool, handle) ;
178
+ process_file ( entry, pool, handle, cache . clone ( ) ) ;
159
179
}
160
180
} ) ;
161
181
0 commit comments