@@ -10,8 +10,10 @@ use std::path::PathBuf;
1010use uuid:: Uuid ;
1111use xorf:: { BinaryFuse8 , Filter } ;
1212
13+ type SourceIterator < ' a > = Peekable < Box < dyn Iterator < Item = ( String , Value ) > + ' a > > ;
14+
1315struct MergedIterator < ' a > {
14- sources : Vec < Peekable < Box < dyn Iterator < Item = ( String , Value ) > + ' a > > > ,
16+ sources : Vec < SourceIterator < ' a > > ,
1517}
1618
1719impl < ' a > Iterator for MergedIterator < ' a > {
@@ -238,7 +240,7 @@ impl Collection {
238240 }
239241
240242 fn scan ( & self ) -> impl Iterator < Item = ( String , Value ) > + ' _ {
241- let mut sources: Vec < Peekable < Box < dyn Iterator < Item = ( String , Value ) > > > > = Vec :: new ( ) ;
243+ let mut sources: Vec < SourceIterator > = Vec :: new ( ) ;
242244
243245 // 1. MemTable Iterator (Priority 0 - Highest)
244246 let mem_iter = self
@@ -290,18 +292,16 @@ impl Collection {
290292 let path = self . dir . join ( format ! ( "jstable-{}" , i) ) ;
291293 if let Ok ( mut iter) = jstable:: JSTableIterator :: new ( path. to_str ( ) . unwrap ( ) ) {
292294 if iter. seek ( start_offset) . is_ok ( ) {
293- for res in iter {
294- if let Ok ( ( rid, doc) ) = res {
295- if rid == id {
296- if doc. is_null ( ) {
297- return None ; // Tombstone
298- }
299- return Some ( doc) ;
300- }
301- if rid > id. to_string ( ) {
302- // Not found in this table (sorted)
303- break ;
295+ for ( rid, doc) in iter. flatten ( ) {
296+ if rid == id {
297+ if doc. is_null ( ) {
298+ return None ; // Tombstone
304299 }
300+ return Some ( doc) ;
301+ }
302+ if rid. as_str ( ) > id {
303+ // Not found in this table (sorted)
304+ break ;
305305 }
306306 }
307307 }
@@ -344,63 +344,61 @@ impl DB {
344344 let mut collections = HashMap :: new ( ) ;
345345
346346 if let Ok ( entries) = fs:: read_dir ( root_dir) {
347- for entry in entries {
348- if let Ok ( entry) = entry {
349- if entry. path ( ) . is_dir ( ) {
350- let dir_path = entry. path ( ) ;
351-
352- // Try to find collection name from JSTable-0
353- let jstable_base_path = dir_path. join ( "jstable-0" ) ;
354- let jstable_summary_path = dir_path. join ( "jstable-0.summary" ) ;
355- let col_name = if jstable_summary_path. exists ( ) {
356- if let Ok ( iter) =
357- jstable:: JSTableIterator :: new ( jstable_base_path. to_str ( ) . unwrap ( ) )
358- {
359- Some ( iter. collection )
360- } else {
361- None
362- }
347+ for entry in entries. flatten ( ) {
348+ if entry. path ( ) . is_dir ( ) {
349+ let dir_path = entry. path ( ) ;
350+
351+ // Try to find collection name from JSTable-0
352+ let jstable_base_path = dir_path. join ( "jstable-0" ) ;
353+ let jstable_summary_path = dir_path. join ( "jstable-0.summary" ) ;
354+ let col_name = if jstable_summary_path. exists ( ) {
355+ if let Ok ( iter) =
356+ jstable:: JSTableIterator :: new ( jstable_base_path. to_str ( ) . unwrap ( ) )
357+ {
358+ Some ( iter. collection )
363359 } else {
364- // Fallback to directory name (sanitized) if no jstable
365- entry. file_name ( ) . to_str ( ) . map ( |s| s. to_string ( ) )
366- } ;
367-
368- if let Some ( name) = col_name {
369- let mut collection = Collection :: new (
370- name. clone ( ) ,
371- dir_path. clone ( ) , // Clone dir_path for collection
372- memtable_threshold,
373- jstable_threshold,
374- index_threshold,
375- log_rotation_threshold,
376- ) ;
377-
378- if log_rotation_threshold. is_some ( ) {
379- let log_path = dir_path. join ( "argus.log" ) ;
380- let log_content =
381- std:: fs:: read_to_string ( & log_path) . unwrap_or_default ( ) ;
382- for line in log_content. lines ( ) {
383- if line. is_empty ( ) {
384- continue ;
385- }
386- if let Ok ( entry) = serde_json:: from_str :: < LogEntry > ( line) {
387- match entry. op {
388- Operation :: Insert { id, doc } => {
389- collection. memtable . insert ( id, doc) ;
390- }
391- Operation :: Update { id, doc } => {
392- collection. memtable . update ( & id, doc) ;
393- }
394- Operation :: Delete { id } => {
395- collection. memtable . delete ( & id) ;
396- }
360+ None
361+ }
362+ } else {
363+ // Fallback to directory name (sanitized) if no jstable
364+ entry. file_name ( ) . to_str ( ) . map ( |s| s. to_string ( ) )
365+ } ;
366+
367+ if let Some ( name) = col_name {
368+ let mut collection = Collection :: new (
369+ name. clone ( ) ,
370+ dir_path. clone ( ) , // Clone dir_path for collection
371+ memtable_threshold,
372+ jstable_threshold,
373+ index_threshold,
374+ log_rotation_threshold,
375+ ) ;
376+
377+ if log_rotation_threshold. is_some ( ) {
378+ let log_path = dir_path. join ( "argus.log" ) ;
379+ let log_content =
380+ std:: fs:: read_to_string ( & log_path) . unwrap_or_default ( ) ;
381+ for line in log_content. lines ( ) {
382+ if line. is_empty ( ) {
383+ continue ;
384+ }
385+ if let Ok ( entry) = serde_json:: from_str :: < LogEntry > ( line) {
386+ match entry. op {
387+ Operation :: Insert { id, doc } => {
388+ collection. memtable . insert ( id, doc) ;
389+ }
390+ Operation :: Update { id, doc } => {
391+ collection. memtable . update ( & id, doc) ;
392+ }
393+ Operation :: Delete { id } => {
394+ collection. memtable . delete ( & id) ;
397395 }
398396 }
399397 }
400398 }
401-
402- collections. insert ( name, collection) ;
403399 }
400+
401+ collections. insert ( name, collection) ;
404402 }
405403 }
406404 }
0 commit comments