@@ -384,7 +384,7 @@ fn read_page_from_file<P: AsRef<Path>>(filename: P) -> Result<Page> {
384384 Ok ( Page :: new ( index, capacity, page_data) )
385385}
386386
387- fn read_pageptr_from_file < ' a , P : AsRef < Path > > ( filename : P ) -> Result < PagePtr < ' a > > {
387+ fn _read_pageptr_from_file < ' a , P : AsRef < Path > > ( filename : P ) -> Result < PagePtr < ' a > > {
388388 let file = OpenOptions :: new ( ) . read ( true ) . open ( & filename) ?;
389389 let mmap = unsafe { MmapOptions :: new ( ) . populate ( ) . map ( & file) ? } ;
390390 let index = LittleEndian :: read_u64 ( & mmap[ 0 ..8 ] ) as usize ;
@@ -406,6 +406,38 @@ fn read_pageptr_from_file<'a, P: AsRef<Path>>(filename: P) -> Result<PagePtr<'a>
406406 Ok ( PagePtr :: new ( Some ( mmap) , index, first_zero_end, page_data) )
407407}
408408
409+ fn read_pageptr_from_file_chunk < ' a , P : AsRef < Path > > ( filename : P ) -> Result < PagePtr < ' a > > {
410+ let file = OpenOptions :: new ( ) . read ( true ) . open ( & filename) ?;
411+ let mmap = unsafe { MmapOptions :: new ( ) . populate ( ) . map ( & file) ? } ;
412+ let index = LittleEndian :: read_u64 ( & mmap[ 0 ..8 ] ) as usize ;
413+ let capacity = LittleEndian :: read_u64 ( & mmap[ 8 ..16 ] ) as usize ;
414+
415+ let mut first_zero_end = capacity;
416+ let chunk_size = 1024 ; // 定义每次读取的块大小
417+ let mut found_zero = false ;
418+
419+ for i in ( 0 ..capacity) . step_by ( chunk_size) {
420+ let end = usize:: min ( i + chunk_size, capacity) ;
421+ let chunk = unsafe {
422+ std:: slice:: from_raw_parts ( mmap. as_ptr ( ) . add ( 16 + i * 4 ) as * const u32 , end - i)
423+ } ;
424+ if let Some ( pos) = chunk. iter ( ) . position ( |& x| x == 0 ) {
425+ first_zero_end = i + pos + 1 ;
426+ found_zero = true ;
427+ break ;
428+ }
429+ }
430+
431+ if !found_zero {
432+ first_zero_end = capacity;
433+ }
434+
435+ let page_data =
436+ unsafe { std:: slice:: from_raw_parts ( mmap. as_ptr ( ) . add ( 16 ) as * const u32 , first_zero_end) } ;
437+
438+ Ok ( PagePtr :: new ( Some ( mmap) , index, first_zero_end, page_data) )
439+ }
440+
409441impl < ' a > CHPage < ' a > {
410442 pub fn from < P : AsRef < Path > + Debug > (
411443 config : HashConfig ,
@@ -414,7 +446,7 @@ impl<'a> CHPage<'a> {
414446 ) -> Result < CHPage < ' a > > {
415447 let page = read_page_from_file ( chunk_file1) ?;
416448 let next_page = if page. data . last ( ) . map_or ( false , |& x| x == 0 ) {
417- read_pageptr_from_file ( chunk_file2) ?
449+ read_pageptr_from_file_chunk ( chunk_file2) ?
418450 } else {
419451 PagePtr :: default ( )
420452 } ;
0 commit comments