@@ -6,7 +6,7 @@ use crate::{
66
77use std:: {
88 collections:: BTreeSet ,
9- fs:: { OpenOptions , create_dir_all} ,
9+ fs:: { OpenOptions , create_dir_all, remove_dir_all } ,
1010 io:: { self , BufReader } ,
1111 path:: PathBuf ,
1212} ;
@@ -18,6 +18,8 @@ use tracing::{error, info, trace};
1818pub ( crate ) trait Cache < K , V > {
1919 fn load ( & self , key : & K ) -> Result < Option < V > > ;
2020 fn store ( & self , key : K , value : V ) -> Result < ( ) > ;
21+
22+ fn clear ( & self , service : FormValue , owner : & str , repo : & str ) -> Result < ( ) > ;
2123}
2224
2325pub ( crate ) trait ToQuery {
@@ -88,23 +90,36 @@ impl Persist {
8890 disk : DiskCache { settings } ,
8991 }
9092 }
91-
92- /// Clear the in-memory part of the cache
93- pub ( crate ) fn clear ( & self ) {
94- // TODO: currently this removes everything from the cache. maybe use layered maps to clear
95- // only for specific `service + owner + repo`
96- self . in_memory . cache . clear ( ) ;
97- }
9893}
9994
10095impl Drop for Persist {
10196 fn drop ( & mut self ) {
10297 info ! ( "persisting cache" ) ;
10398 for r in & self . in_memory . cache {
104- if let Err ( err) = self . disk . store ( r. key ( ) . clone ( ) , r. value ( ) . clone ( ) ) {
105- error ! ( %err, key = ?r. key( ) , "cannot write cache to disk" ) ;
106- } else {
107- trace ! ( key = ?r. key( ) , "persisted" ) ;
99+ let service = * r. key ( ) ;
100+ for r in r. value ( ) {
101+ let owner = r. key ( ) ;
102+ for r in r. value ( ) {
103+ let repo = r. key ( ) ;
104+ for r in r. value ( ) {
105+ let branch = r. key ( ) ;
106+ for r in r. value ( ) {
107+ let excludes = r. key ( ) . clone ( ) ;
108+ let key = CacheKey :: new (
109+ service,
110+ owner. clone ( ) ,
111+ repo. clone ( ) ,
112+ branch. clone ( ) ,
113+ excludes,
114+ ) ;
115+ if let Err ( err) = self . disk . store ( key, r. value ( ) . clone ( ) ) {
116+ error ! ( %err, key = ?r. key( ) , "cannot write cache to disk" ) ;
117+ } else {
118+ trace ! ( key = ?r. key( ) , "persisted" ) ;
119+ }
120+ }
121+ }
122+ }
108123 }
109124 }
110125 }
@@ -125,10 +140,26 @@ impl Cache<CacheKey, CacheEntry> for Persist {
125140 fn store ( & self , key : CacheKey , value : CacheEntry ) -> Result < ( ) > {
126141 self . in_memory . store ( key, value)
127142 }
143+
144+ fn clear ( & self , service : FormValue , owner : & str , repo : & str ) -> Result < ( ) > {
145+ let im_res = self . in_memory . clear ( service, owner, repo) ;
146+ let disk_res = self . disk . clear ( service, owner, repo) ;
147+ if let Err ( e) = im_res {
148+ Err ( e) ?
149+ } else if let Err ( e) = disk_res {
150+ Err ( e) ?
151+ } else {
152+ Ok ( ( ) )
153+ }
154+ }
128155}
129156
130157struct InMemoryCache {
131- cache : DashMap < CacheKey , CacheEntry > ,
158+ #[ allow( clippy:: type_complexity) ]
159+ cache : DashMap <
160+ FormValue ,
161+ DashMap < String , DashMap < String , DashMap < String , DashMap < Excludes , CacheEntry > > > > ,
162+ > ,
132163}
133164
134165impl InMemoryCache {
@@ -141,12 +172,37 @@ impl InMemoryCache {
141172
142173impl Cache < CacheKey , CacheEntry > for InMemoryCache {
143174 fn store ( & self , key : CacheKey , value : CacheEntry ) -> Result < ( ) > {
144- self . cache . insert ( key, value) ;
175+ self . cache
176+ . entry ( key. service )
177+ . or_default ( )
178+ . entry ( key. owner )
179+ . or_default ( )
180+ . entry ( key. repo )
181+ . or_default ( )
182+ . entry ( key. branch )
183+ . or_default ( )
184+ . insert ( key. excludes , value) ;
145185 Ok ( ( ) )
146186 }
147187
148188 fn load ( & self , key : & CacheKey ) -> Result < Option < CacheEntry > > {
149- Ok ( self . cache . get ( key) . map ( |r| r. value ( ) . clone ( ) ) )
189+ Ok ( self . cache . get ( & key. service ) . and_then ( |c| {
190+ c. get ( & key. owner ) . and_then ( |c| {
191+ c. get ( & key. repo ) . and_then ( |c| {
192+ c. get ( & key. branch )
193+ . and_then ( |c| c. get ( & key. excludes ) . map ( |r| r. value ( ) . clone ( ) ) )
194+ } )
195+ } )
196+ } ) )
197+ }
198+
199+ fn clear ( & self , service : FormValue , owner : & str , repo : & str ) -> Result < ( ) > {
200+ if let Some ( c) = self . cache . get ( & service)
201+ && let Some ( c) = c. value ( ) . get ( owner)
202+ {
203+ c. value ( ) . remove ( repo) ;
204+ }
205+ Ok ( ( ) )
150206 }
151207}
152208
@@ -187,6 +243,23 @@ impl Cache<CacheKey, CacheEntry> for DiskCache {
187243 ) ?;
188244 Ok ( ( ) )
189245 }
246+
247+ fn clear ( & self , service : FormValue , owner : & str , repo : & str ) -> Result < ( ) > {
248+ let cache_dir = self
249+ . settings
250+ . cachedir
251+ . join ( service. service ( ) )
252+ . join ( owner)
253+ . join ( repo) ;
254+ remove_dir_all ( cache_dir) . or_else ( |e| {
255+ if e. kind ( ) == io:: ErrorKind :: NotFound {
256+ Ok ( ( ) )
257+ } else {
258+ Err ( e)
259+ }
260+ } ) ?;
261+ Ok ( ( ) )
262+ }
190263}
191264
192265#[ derive( Serialize , Deserialize , Clone , Debug ) ]
0 commit comments