1+ use rocksdb:: WriteBatch ;
2+ use std:: sync:: Arc ;
3+
4+ use crate :: domain:: config:: AoConfig ;
5+ use super :: store:: LocalStoreClient ;
6+
7+ pub fn merge_dbs ( src_file_db_dir : & str , src_index_db_dir : & str , dest_file_db_dir : Option < & str > , dest_index_db_dir : Option < & str > ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
8+ // Open source databases using LocalStoreClient read-only method
9+ let src_store = LocalStoreClient :: new_read_only (
10+ & src_file_db_dir. to_string ( ) ,
11+ & src_index_db_dir. to_string ( )
12+ ) . map_err ( |e| format ! ( "Failed to open source LocalStoreClient: {:?}" , e) ) ?;
13+
14+ // Create destination store using provided paths or config
15+ let dest_store = Arc :: new (
16+ if let ( Some ( file_dir) , Some ( index_dir) ) = ( dest_file_db_dir, dest_index_db_dir) {
17+ LocalStoreClient :: new ( & file_dir. to_string ( ) , & index_dir. to_string ( ) )
18+ . map_err ( |e| format ! ( "Failed to create LocalStoreClient: {:?}" , e) ) ?
19+ } else {
20+ let config = AoConfig :: new ( None ) ?;
21+ LocalStoreClient :: new ( & config. su_file_db_dir , & config. su_index_db_dir )
22+ . map_err ( |e| format ! ( "Failed to create LocalStoreClient: {:?}" , e) ) ?
23+ }
24+ ) ;
25+
26+ // Merge file database
27+ let mut file_count = 0 ;
28+
29+ let file_iterator = src_store. file_db . iterator ( rocksdb:: IteratorMode :: Start ) ;
30+
31+ for item in file_iterator {
32+ let ( key, value) = item?;
33+ dest_store. file_db . put ( key, value) ?;
34+ file_count += 1 ;
35+
36+ if file_count % 100 == 0 {
37+ println ! ( "Processed file record {}" , file_count) ;
38+ }
39+ }
40+
41+ // Merge index database
42+ let mut index_batch = WriteBatch :: default ( ) ;
43+ let mut index_count = 0 ;
44+
45+ let index_iterator = src_store. index_db . iterator ( rocksdb:: IteratorMode :: Start ) ;
46+
47+ for item in index_iterator {
48+ let ( key, value) = item?;
49+ index_batch. put ( key, value) ;
50+ index_count += 1 ;
51+
52+ if index_count % 10000 == 0 {
53+ dest_store. index_db . write ( index_batch) ?;
54+ index_batch = WriteBatch :: default ( ) ;
55+ println ! ( "Committed index batch at record {}" , index_count) ;
56+ }
57+ }
58+
59+ if !index_batch. is_empty ( ) {
60+ dest_store. index_db . write ( index_batch) ?;
61+ println ! ( "Committed final index batch at record {}" , index_count) ;
62+ }
63+
64+ println ! ( "Successfully merged {} file records and {} index records" , file_count, index_count) ;
65+ println ! ( "Source file DB: {}" , src_file_db_dir) ;
66+ println ! ( "Source index DB: {}" , src_index_db_dir) ;
67+
68+ if let ( Some ( file_dir) , Some ( index_dir) ) = ( dest_file_db_dir, dest_index_db_dir) {
69+ println ! ( "Destination file DB: {}" , file_dir) ;
70+ println ! ( "Destination index DB: {}" , index_dir) ;
71+ } else {
72+ let config = AoConfig :: new ( None ) ?;
73+ println ! ( "Destination file DB: {}" , config. su_file_db_dir) ;
74+ println ! ( "Destination index DB: {}" , config. su_index_db_dir) ;
75+ }
76+
77+ Ok ( ( ) )
78+ }
0 commit comments