@@ -13,47 +13,154 @@ pub struct MemTable {
1313impl MemTable {
1414 pub fn new ( log_path : & str ) -> Self {
1515 let logger = Logger :: new ( log_path) . unwrap ( ) ;
16- MemTable {
16+ let mut memtable = MemTable {
1717 documents : BTreeMap :: new ( ) ,
1818 schema : Schema {
1919 types : vec ! [ ] ,
2020 properties : None ,
2121 items : None ,
2222 } ,
2323 logger,
24- }
24+ } ;
25+ memtable. recover ( log_path) ;
26+ memtable
2527 }
2628
27- pub fn insert ( & mut self , doc : Value ) -> String {
28- let doc_schema = infer_schema ( & doc) ;
29- self . schema . merge ( doc_schema. clone ( ) ) ;
30- let id = Uuid :: now_v7 ( ) . to_string ( ) ;
31- self . documents . insert ( id. clone ( ) , doc. clone ( ) ) ;
32- self . logger
33- . log ( Operation :: Insert { doc } )
34- . expect ( "Failed to log insert" ) ;
35- id
36- }
29+ fn recover ( & mut self , log_path : & str ) {
3730
38- pub fn delete ( & mut self , id : & str ) {
39- self . documents . remove ( id) ;
40- self . logger
41- . log ( Operation :: Delete { id : id. to_string ( ) } )
42- . expect ( "Failed to log delete" ) ;
43- }
31+ let log_content = std:: fs:: read_to_string ( log_path) . unwrap_or_default ( ) ;
32+
33+ for line in log_content. lines ( ) {
34+
35+ if line. is_empty ( ) {
36+
37+ continue ;
38+
39+ }
40+
41+ let entry: crate :: log:: LogEntry = serde_json:: from_str ( line) . unwrap ( ) ;
42+
43+ match entry. op {
44+
45+ Operation :: Insert { id, doc } => {
46+
47+ self . insert_with_id ( & id, doc) ;
48+
49+ }
50+
51+ Operation :: Update { id, doc } => {
52+
53+ self . _update ( & id, doc) ;
54+
55+ }
56+
57+ Operation :: Delete { id } => {
58+
59+ self . _delete ( & id) ;
60+
61+ }
62+
63+ }
64+
65+ }
66+
67+ }
68+
69+
70+
71+ fn insert_with_id ( & mut self , id : & str , doc : Value ) {
72+
73+ let doc_schema = infer_schema ( & doc) ;
74+
75+ self . schema . merge ( doc_schema) ;
76+
77+ self . documents . insert ( id. to_string ( ) , doc) ;
78+
79+ }
80+
81+
82+
83+ pub fn insert ( & mut self , doc : Value ) -> String {
84+
85+ let doc_schema = infer_schema ( & doc) ;
86+
87+ self . schema . merge ( doc_schema. clone ( ) ) ;
88+
89+ let id = Uuid :: now_v7 ( ) . to_string ( ) ;
90+
91+ self . documents . insert ( id. clone ( ) , doc. clone ( ) ) ;
92+
93+ self . logger
94+
95+ . log ( Operation :: Insert {
96+
97+ id : id. clone ( ) ,
98+
99+ doc,
100+
101+ } )
102+
103+ . expect ( "Failed to log insert" ) ;
104+
105+ id
106+
107+ }
108+
109+
110+
111+ fn _delete ( & mut self , id : & str ) {
112+
113+ self . documents . remove ( id) ;
114+
115+ }
116+
117+
118+
119+ pub fn delete ( & mut self , id : & str ) {
120+
121+ self . _delete ( id) ;
122+
123+ self . logger
124+
125+ . log ( Operation :: Delete { id : id. to_string ( ) } )
126+
127+ . expect ( "Failed to log delete" ) ;
128+
129+ }
130+
131+
132+
133+ fn _update ( & mut self , id : & str , doc : Value ) {
134+
135+ let doc_schema = infer_schema ( & doc) ;
136+
137+ self . schema . merge ( doc_schema) ;
138+
139+ self . documents . insert ( id. to_string ( ) , doc) ;
140+
141+ }
142+
143+
144+
145+ pub fn update ( & mut self , id : & str , doc : Value ) {
146+
147+ self . _update ( id, doc. clone ( ) ) ;
148+
149+ self . logger
150+
151+ . log ( Operation :: Update {
152+
153+ id : id. to_string ( ) ,
154+
155+ doc,
156+
157+ } )
158+
159+ . expect ( "Failed to log update" ) ;
160+
161+ }
44162
45- pub fn update ( & mut self , id : & str , doc : Value ) {
46- let doc_schema = infer_schema ( & doc) ;
47- self . schema . merge ( doc_schema) ;
48- self . documents . insert ( id. to_string ( ) , doc. clone ( ) ) ;
49- self . logger
50- . log ( Operation :: Update {
51- id : id. to_string ( ) ,
52- doc,
53- } )
54- . expect ( "Failed to log update" ) ;
55163 }
56- }
57164
58165#[ cfg( test) ]
59166mod tests {
@@ -125,7 +232,10 @@ mod tests {
125232
126233 let entry1: crate :: log:: LogEntry = serde_json:: from_str ( lines. next ( ) . unwrap ( ) ) . unwrap ( ) ;
127234 match entry1. op {
128- Operation :: Insert { doc } => assert_eq ! ( doc, doc1) ,
235+ Operation :: Insert { id, doc } => {
236+ assert_eq ! ( id, id1) ;
237+ assert_eq ! ( doc, doc1) ;
238+ }
129239 _ => panic ! ( "Expected insert operation" ) ,
130240 }
131241
@@ -144,4 +254,20 @@ mod tests {
144254 _ => panic ! ( "Expected delete operation" ) ,
145255 }
146256 }
257+
258+ #[ test]
259+ fn test_memtable_recover ( ) {
260+ let ( log_file, mut memtable) = create_test_memtable ( ) ;
261+ let doc1 = json ! ( { "a" : 1 } ) ;
262+ let id1 = memtable. insert ( doc1. clone ( ) ) ;
263+
264+ let doc2 = json ! ( { "b" : "hello" } ) ;
265+ let id2 = memtable. insert ( doc2. clone ( ) ) ;
266+
267+ memtable. delete ( & id1) ;
268+
269+ let memtable2 = MemTable :: new ( log_file. path ( ) . to_str ( ) . unwrap ( ) ) ;
270+ assert_eq ! ( memtable2. documents. len( ) , 1 ) ;
271+ assert_eq ! ( * memtable2. documents. get( & id2) . unwrap( ) , doc2) ;
272+ }
147273}
0 commit comments