11use std:: sync:: Arc ;
22use std:: sync:: atomic:: { AtomicBool , Ordering } ;
33
4+ use ckb_db:: RocksDB ;
5+ use ckb_db_schema:: COLUMN_BLOCK_HEADER ;
46#[ cfg( feature = "stats" ) ]
57use ckb_logger:: info;
68use ckb_metrics:: HistogramTimer ;
9+ use ckb_types:: packed;
710#[ cfg( feature = "stats" ) ]
811use ckb_util:: { Mutex , MutexGuard } ;
912use ckb_util:: { RwLock , RwLockReadGuard } ;
1013
11- use ckb_types:: { U256 , core:: EpochNumberWithFraction , packed:: Byte32 } ;
14+ use ckb_types:: { U256 , core:: EpochNumberWithFraction , packed:: Byte32 , prelude :: * } ;
1215
1316use super :: MemoryMap ;
1417use crate :: types:: HeaderIndexView ;
1518
1619pub ( crate ) struct HeaderMapKernel {
1720 pub ( crate ) memory : MemoryMap ,
21+ db : RocksDB ,
1822 // Configuration
1923 memory_limit : usize ,
2024 // if ckb is in IBD mode, don't shrink memory map
@@ -39,14 +43,15 @@ struct HeaderMapKernelStats {
3943}
4044
4145impl HeaderMapKernel {
42- pub ( crate ) fn new ( memory_limit : usize , ibd_finished : Arc < AtomicBool > ) -> Self {
46+ pub ( crate ) fn new ( db : RocksDB , memory_limit : usize , ibd_finished : Arc < AtomicBool > ) -> Self {
4347 let memory = Default :: default ( ) ;
4448 let shared_best_header_value = Self :: default_shared_best_header ( ) ;
4549 let shared_best_header = RwLock :: new ( shared_best_header_value) ;
4650
4751 #[ cfg( not( feature = "stats" ) ) ]
4852 {
4953 Self {
54+ db,
5055 memory,
5156 memory_limit,
5257 ibd_finished,
@@ -57,6 +62,7 @@ impl HeaderMapKernel {
5762 #[ cfg( feature = "stats" ) ]
5863 {
5964 Self {
65+ db,
6066 memory,
6167 memory_limit,
6268 ibd_finished,
@@ -80,7 +86,13 @@ impl HeaderMapKernel {
8086 if let Some ( metrics) = ckb_metrics:: handle ( ) {
8187 metrics. ckb_header_map_memory_hit_miss_count . miss . inc ( ) ;
8288 }
83- false
89+ let contains = self
90+ . db
91+ . get_pinned ( COLUMN_BLOCK_HEADER , hash. as_slice ( ) )
92+ . unwrap ( )
93+ . is_some ( ) ;
94+
95+ contains
8496 }
8597
8698 pub ( crate ) fn get ( & self , hash : & Byte32 ) -> Option < HeaderIndexView > {
@@ -99,27 +111,46 @@ impl HeaderMapKernel {
99111 metrics. ckb_header_map_memory_hit_miss_count . miss . inc ( ) ;
100112 }
101113
114+ self . db
115+ . get_pinned ( COLUMN_BLOCK_HEADER , hash. as_slice ( ) )
116+ . unwrap ( )
117+ . and_then ( |slice| {
118+ let reader = packed:: HeaderViewReader :: from_slice_should_be_ok ( slice. as_ref ( ) ) ;
119+
120+ let header_view = Unpack :: < ckb_types:: core:: HeaderView > :: unpack ( & reader) ;
121+ Some ( header_view)
122+ } ) ;
123+
102124 None
103125 }
104126
105- pub ( crate ) fn insert ( & self , view : HeaderIndexView ) -> Option < ( ) > {
127+ pub ( crate ) fn insert (
128+ & self ,
129+ view : ckb_types:: core:: HeaderView ,
130+ total_difficulty : U256 ,
131+ ) -> Option < ( ) > {
106132 #[ cfg( feature = "stats" ) ]
107133 {
108134 self . trace ( ) ;
109135 self . stats ( ) . tick_primary_insert ( ) ;
110136 }
111- self . memory . insert ( view)
137+ let packed_header: packed:: HeaderView = view. clone ( ) . into ( ) ;
138+ let view: HeaderIndexView = ( view, total_difficulty) . into ( ) ;
139+ let hash = view. hash ( ) ;
140+ self . memory . insert ( view. into ( ) ) ;
141+
142+ self . db
143+ . put (
144+ COLUMN_BLOCK_HEADER ,
145+ hash. as_slice ( ) ,
146+ packed_header. as_slice ( ) ,
147+ )
148+ . ok ( )
112149 }
113150
114- pub ( crate ) fn remove ( & self , hash : & Byte32 ) {
115- #[ cfg( feature = "stats" ) ]
116- {
117- self . trace ( ) ;
118- self . stats ( ) . tick_primary_delete ( ) ;
119- }
120- // If IBD is not finished, don't shrink memory map
121- let allow_shrink_to_fit = self . ibd_finished . load ( Ordering :: Acquire ) ;
122- self . memory . remove ( hash, allow_shrink_to_fit) ;
151+ pub ( crate ) fn remove ( & self , _hash : & Byte32 ) {
152+ // TODO
153+ // no need to remove
123154 }
124155
125156 pub ( crate ) fn limit_memory ( & self ) {
0 commit comments