1
1
mod dynamic_storage;
2
2
mod operation;
3
- mod persisted_storage_log;
4
3
mod storage;
5
4
6
5
use std:: {
@@ -22,7 +21,7 @@ use auto_hash_map::{AutoMap, AutoSet};
22
21
use indexmap:: IndexSet ;
23
22
use parking_lot:: { Condvar , Mutex } ;
24
23
use rustc_hash:: { FxHashMap , FxHashSet , FxHasher } ;
25
- use smallvec:: smallvec;
24
+ use smallvec:: { smallvec, SmallVec } ;
26
25
use tokio:: time:: { Duration , Instant } ;
27
26
use turbo_tasks:: {
28
27
backend:: {
@@ -34,8 +33,8 @@ use turbo_tasks::{
34
33
task_statistics:: TaskStatisticsApi ,
35
34
trace:: TraceRawVcs ,
36
35
util:: IdFactoryWithReuse ,
37
- CellId , FunctionId , FxDashMap , RawVc , ReadCellOptions , ReadConsistency , SessionId , TaskId ,
38
- TraitTypeId , TurboTasksBackendApi , ValueTypeId , TRANSIENT_TASK_BIT ,
36
+ CellId , FunctionId , FxDashMap , KeyValuePair , RawVc , ReadCellOptions , ReadConsistency ,
37
+ SessionId , TaskId , TraitTypeId , TurboTasksBackendApi , ValueTypeId , TRANSIENT_TASK_BIT ,
39
38
} ;
40
39
41
40
pub use self :: { operation:: AnyOperation , storage:: TaskDataCategory } ;
@@ -49,17 +48,21 @@ use crate::{
49
48
CleanupOldEdgesOperation , ConnectChildOperation , ExecuteContext , ExecuteContextImpl ,
50
49
Operation , OutdatedEdge , TaskGuard ,
51
50
} ,
52
- persisted_storage_log:: PersistedStorageLog ,
53
- storage:: { get, get_many, get_mut, get_mut_or_insert_with, iter_many, remove, Storage } ,
51
+ storage:: {
52
+ get, get_many, get_mut, get_mut_or_insert_with, iter_many, remove,
53
+ InnerStorageSnapshot , Storage ,
54
+ } ,
54
55
} ,
55
56
backing_storage:: BackingStorage ,
56
57
data:: {
57
58
ActivenessState , AggregationNumber , CachedDataItem , CachedDataItemKey , CachedDataItemType ,
58
- CachedDataItemValue , CachedDataItemValueRef , CachedDataUpdate , CellRef , CollectibleRef ,
59
- CollectiblesRef , DirtyState , InProgressCellState , InProgressState , InProgressStateInner ,
60
- OutputValue , RootType ,
59
+ CachedDataItemValue , CachedDataItemValueRef , CellRef , CollectibleRef , CollectiblesRef ,
60
+ DirtyState , InProgressCellState , InProgressState , InProgressStateInner , OutputValue ,
61
+ RootType ,
62
+ } ,
63
+ utils:: {
64
+ bi_map:: BiMap , chunked_vec:: ChunkedVec , ptr_eq_arc:: PtrEqArc , sharded:: Sharded , swap_retain,
61
65
} ,
62
- utils:: { bi_map:: BiMap , chunked_vec:: ChunkedVec , ptr_eq_arc:: PtrEqArc , sharded:: Sharded } ,
63
66
} ;
64
67
65
68
const BACKEND_JOB_INITIAL_SNAPSHOT : BackendJobId = unsafe { BackendJobId :: new_unchecked ( 1 ) } ;
@@ -163,8 +166,6 @@ struct TurboTasksBackendInner<B: BackingStorage> {
163
166
task_cache : BiMap < Arc < CachedTaskType > , TaskId > ,
164
167
transient_tasks : FxDashMap < TaskId , Arc < TransientTask > > ,
165
168
166
- persisted_storage_data_log : Option < PersistedStorageLog > ,
167
- persisted_storage_meta_log : Option < PersistedStorageLog > ,
168
169
storage : Storage ,
169
170
170
171
/// Number of executing operations + Highest bit is set when snapshot is
@@ -227,8 +228,6 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
227
228
persisted_task_cache_log : need_log. then ( || Sharded :: new ( shard_amount) ) ,
228
229
task_cache : BiMap :: new ( ) ,
229
230
transient_tasks : FxDashMap :: default ( ) ,
230
- persisted_storage_data_log : need_log. then ( || PersistedStorageLog :: new ( shard_amount) ) ,
231
- persisted_storage_meta_log : need_log. then ( || PersistedStorageLog :: new ( shard_amount) ) ,
232
231
storage : Storage :: new ( ) ,
233
232
in_progress_operations : AtomicUsize :: new ( 0 ) ,
234
233
snapshot_request : Mutex :: new ( SnapshotRequest :: new ( ) ) ,
@@ -333,15 +332,6 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
333
332
}
334
333
}
335
334
336
- fn persisted_storage_log ( & self , category : TaskDataCategory ) -> Option < & PersistedStorageLog > {
337
- match category {
338
- TaskDataCategory :: Data => & self . persisted_storage_data_log ,
339
- TaskDataCategory :: Meta => & self . persisted_storage_meta_log ,
340
- TaskDataCategory :: All => unreachable ! ( ) ,
341
- }
342
- . as_ref ( )
343
- }
344
-
345
335
fn should_persist ( & self ) -> bool {
346
336
matches ! ( self . options. storage_mode, Some ( StorageMode :: ReadWrite ) )
347
337
}
@@ -827,16 +817,12 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
827
817
. map ( |op| op. arc ( ) . clone ( ) )
828
818
. collect :: < Vec < _ > > ( ) ;
829
819
drop ( snapshot_request) ;
830
- fn take_from_log ( log : & Option < PersistedStorageLog > ) -> Vec < ChunkedVec < CachedDataUpdate > > {
831
- log. as_ref ( ) . map ( |l| l. take ( ) ) . unwrap_or_default ( )
832
- }
833
- let persisted_storage_meta_log = take_from_log ( & self . persisted_storage_meta_log ) ;
834
- let persisted_storage_data_log = take_from_log ( & self . persisted_storage_data_log ) ;
835
- let persisted_task_cache_log = self
820
+ let mut persisted_task_cache_log = self
836
821
. persisted_task_cache_log
837
822
. as_ref ( )
838
823
. map ( |l| l. take ( |i| i) )
839
824
. unwrap_or_default ( ) ;
825
+ self . storage . start_snapshot ( ) ;
840
826
let mut snapshot_request = self . snapshot_request . lock ( ) ;
841
827
snapshot_request. snapshot_requested = false ;
842
828
self . in_progress_operations
@@ -845,50 +831,131 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
845
831
let snapshot_time = Instant :: now ( ) ;
846
832
drop ( snapshot_request) ;
847
833
848
- // TODO track which items are persisting
849
- // TODO This is very inefficient, maybe the BackingStorage could compute that since it need
850
- // to iterate items anyway.
851
- // let mut counts: FxHashMap<TaskId, u32> =
852
- // FxHashMap::with_capacity_and_hasher(); for log in persisted_storage_meta_log
853
- // .iter()
854
- // .chain(persisted_storage_data_log.iter())
855
- // {
856
- // for CachedDataUpdate { task, .. } in log.iter() {
857
- // *counts.entry(*task).or_default() += 1;
858
- // }
859
- // }
834
+ let preprocess = |task_id : TaskId , inner : & storage:: InnerStorage | {
835
+ if task_id. is_transient ( ) {
836
+ return ( None , None ) ;
837
+ }
838
+ let len = inner. len ( ) ;
839
+ let mut meta = Vec :: with_capacity ( len) ;
840
+ let mut data = Vec :: with_capacity ( len) ;
841
+ for ( key, value) in inner. iter_all ( ) {
842
+ if key. is_persistent ( ) && value. is_persistent ( ) {
843
+ match key. category ( ) {
844
+ TaskDataCategory :: Meta => {
845
+ meta. push ( CachedDataItem :: from_key_and_value_ref ( key, value) )
846
+ }
847
+ TaskDataCategory :: Data => {
848
+ data. push ( CachedDataItem :: from_key_and_value_ref ( key, value) )
849
+ }
850
+ _ => { }
851
+ }
852
+ }
853
+ }
860
854
861
- let mut new_items = false ;
855
+ (
856
+ inner. state ( ) . meta_restored ( ) . then_some ( meta) ,
857
+ inner. state ( ) . data_restored ( ) . then_some ( data) ,
858
+ )
859
+ } ;
860
+ let process = |task_id : TaskId , ( meta, data) : ( Option < Vec < _ > > , Option < Vec < _ > > ) | {
861
+ (
862
+ task_id,
863
+ meta. map ( |d| B :: serialize ( task_id, & d) ) ,
864
+ data. map ( |d| B :: serialize ( task_id, & d) ) ,
865
+ )
866
+ } ;
867
+ let process_snapshot = |task_id : TaskId , inner : Box < InnerStorageSnapshot > | {
868
+ if task_id. is_transient ( ) {
869
+ return ( task_id, None , None ) ;
870
+ }
871
+ let len = inner. len ( ) ;
872
+ let mut meta = Vec :: with_capacity ( len) ;
873
+ let mut data = Vec :: with_capacity ( len) ;
874
+ for ( key, value) in inner. iter_all ( ) {
875
+ if key. is_persistent ( ) && value. is_persistent ( ) {
876
+ match key. category ( ) {
877
+ TaskDataCategory :: Meta => {
878
+ meta. push ( CachedDataItem :: from_key_and_value_ref ( key, value) )
879
+ }
880
+ TaskDataCategory :: Data => {
881
+ data. push ( CachedDataItem :: from_key_and_value_ref ( key, value) )
882
+ }
883
+ _ => { }
884
+ }
885
+ }
886
+ }
887
+ (
888
+ task_id,
889
+ inner. meta_restored . then ( || B :: serialize ( task_id, & meta) ) ,
890
+ inner. data_restored . then ( || B :: serialize ( task_id, & data) ) ,
891
+ )
892
+ } ;
862
893
863
- fn shards_empty < T > ( shards : & [ ChunkedVec < T > ] ) -> bool {
864
- shards. iter ( ) . all ( |shard| shard. is_empty ( ) )
865
- }
894
+ let snapshot = {
895
+ let _span = tracing:: trace_span!( "take snapshot" ) ;
896
+ self . storage
897
+ . take_snapshot ( & preprocess, & process, & process_snapshot)
898
+ } ;
866
899
867
- if !shards_empty ( & persisted_task_cache_log)
868
- || !shards_empty ( & persisted_storage_meta_log)
869
- || !shards_empty ( & persisted_storage_data_log)
870
- {
900
+ let task_snapshots = snapshot
901
+ . into_iter ( )
902
+ . filter_map ( |iter| {
903
+ let mut iter = iter
904
+ . filter_map (
905
+ |( task_id, meta, data) : (
906
+ _ ,
907
+ Option < Result < SmallVec < _ > > > ,
908
+ Option < Result < SmallVec < _ > > > ,
909
+ ) | {
910
+ let meta = match meta {
911
+ Some ( Ok ( meta) ) => Some ( meta) ,
912
+ None => None ,
913
+ Some ( Err ( err) ) => {
914
+ println ! (
915
+ "Serializing task {} failed (meta): {:?}" ,
916
+ self . get_task_description( task_id) ,
917
+ err
918
+ ) ;
919
+ None
920
+ }
921
+ } ;
922
+ let data = match data {
923
+ Some ( Ok ( data) ) => Some ( data) ,
924
+ None => None ,
925
+ Some ( Err ( err) ) => {
926
+ println ! (
927
+ "Serializing task {} failed (data): {:?}" ,
928
+ self . get_task_description( task_id) ,
929
+ err
930
+ ) ;
931
+ None
932
+ }
933
+ } ;
934
+ ( meta. is_some ( ) || data. is_some ( ) ) . then_some ( ( task_id, meta, data) )
935
+ } ,
936
+ )
937
+ . peekable ( ) ;
938
+ iter. peek ( ) . is_some ( ) . then_some ( iter)
939
+ } )
940
+ . collect :: < Vec < _ > > ( ) ;
941
+
942
+ swap_retain ( & mut persisted_task_cache_log, |shard| !shard. is_empty ( ) ) ;
943
+
944
+ let mut new_items = false ;
945
+
946
+ if !persisted_task_cache_log. is_empty ( ) || !task_snapshots. is_empty ( ) {
871
947
new_items = true ;
872
948
if let Err ( err) = self . backing_storage . save_snapshot (
873
949
self . session_id ,
874
950
suspended_operations,
875
951
persisted_task_cache_log,
876
- persisted_storage_meta_log,
877
- persisted_storage_data_log,
952
+ task_snapshots,
878
953
) {
879
954
println ! ( "Persisting failed: {:?}" , err) ;
880
955
return None ;
881
956
}
882
957
}
883
958
884
- // TODO add when we need to track persisted items
885
- // for (task_id, count) in counts {
886
- // self.storage
887
- // .access_mut(task_id)
888
- // .persistance_state_mut()
889
- // .finish_persisting_items(count);
890
- // }
891
-
892
959
Some ( ( snapshot_time, new_items) )
893
960
}
894
961
0 commit comments