pub fn scan(&mut self) -> Result<()> {
        let dir = &self.cfg.dir;
        let path = Path::new(dir);
        if !path.exists() {
            info!("Create raft log directory: {}", dir);
            fs::create_dir(dir)?;
            self.dir_lock = Some(lock_dir(dir)?);
            return Ok(());
        }
        if !path.is_dir() {
            return Err(box_err!("Not directory: {}", dir));
        }
        self.dir_lock = Some(lock_dir(dir)?);

        let (mut min_append_id, mut max_append_id) = (u64::MAX, 0);
        let (mut min_rewrite_id, mut max_rewrite_id) = (u64::MAX, 0);
        fs::read_dir(path)?.for_each(|e| {
            if let Ok(e) = e {
                let p = e.path();
                if p.is_file() {
                    match FileId::parse_file_name(p.file_name().unwrap().to_str().unwrap()) {
                        Some(FileId {
                            queue: LogQueue::Append,
                            seq,
                        }) => {
                            min_append_id = std::cmp::min(min_append_id, seq);
                            max_append_id = std::cmp::max(max_append_id, seq);
                        }
                        Some(FileId {
                            queue: LogQueue::Rewrite,
                            seq,
                        }) => {
                            min_rewrite_id = std::cmp::min(min_rewrite_id, seq);
                            max_rewrite_id = std::cmp::max(max_rewrite_id, seq);
                        }
                        _ => {}
                    }
                }
            }
        });

        for (queue, min_id, max_id, files) in [
            (
                LogQueue::Append,
                min_append_id,
                max_append_id,
                &mut self.append_files,
            ),
            (
                LogQueue::Rewrite,
                min_rewrite_id,
                max_rewrite_id,
                &mut self.rewrite_files,
            ),
        ] {
            if max_id > 0 {
                // Try to cleanup stale metadata left by the previous version.
                let max_sample = 100;
                // Find the first obsolete metadata.
                let mut delete_start = None;
                for i in 0..max_sample {
                    let seq = i * min_id / max_sample;
                    let file_id = FileId { queue, seq };
                    let path = file_id.build_file_path(dir);
                    if self.file_system.exists_metadata(&path) {
                        delete_start = Some(i.saturating_sub(1) * min_id / max_sample + 1);
                        break;
                    }
                }
                // Delete metadata starting from the oldest. Abort on error.
                if let Some(start) = delete_start {
                    let mut success = 0;
                    for seq in start..min_id {
                        let file_id = FileId { queue, seq };
                        let path = file_id.build_file_path(dir);
                        match self.file_system.delete_metadata(&path) {
                            Err(e) => {
                                error!("failed to delete metadata of {}: {}.", path.display(), e);
                                break;
                            }
                            Ok(true) => success += 1,
                            _ => {}
                        }
                    }
                    warn!(
                        "deleted {} stale files of {:?} in range [{}, {}).",
                        success, queue, start, min_id,
                    );
                }
                for seq in min_id..=max_id {
                    let file_id = FileId { queue, seq };
                    let path = file_id.build_file_path(dir);
                    if !path.exists() {
                        warn!(
                            "Detected a hole when scanning directory, discarding files before {:?}.",
                            file_id,
                        );
                        files.clear();
                    } else {
                        let handle = Arc::new(self.file_system.open(&path)?);
                        files.push(FileToRecover {
                            seq,
                            handle,
                            version: None,
                        });
                    }
                }
            }
        }
        Ok(())
    }
/// Scans for all log files under the working directory. The directory will
/// be created if not exists.
Scans for all log files under the working directory. The directory will
be created if not exists.
Scans for all log files under the working directory . The directory will be created if not exists .
pub fn scan(&mut self) -> Result<()> {
        let dir = &self.cfg.dir;
        let path = Path::new(dir);
        if !path.exists() {
            info!("Create raft log directory: {}", dir);
            fs::create_dir(dir)?;
            self.dir_lock = Some(lock_dir(dir)?);
            return Ok(());
        }
        if !path.is_dir() {
            return Err(box_err!("Not directory: {}", dir));
        }
        self.dir_lock = Some(lock_dir(dir)?);
        let (mut min_append_id, mut max_append_id) = (u64::MAX, 0);
        let (mut min_rewrite_id, mut max_rewrite_id) = (u64::MAX, 0);
        fs::read_dir(path)?.for_each(|e| {
            if let Ok(e) = e {
                let p = e.path();
                if p.is_file() {
                    match FileId::parse_file_name(p.file_name().unwrap().to_str().unwrap()) {
                        Some(FileId {
                            queue: LogQueue::Append,
                            seq,
                        }) => {
                            min_append_id = std::cmp::min(min_append_id, seq);
                            max_append_id = std::cmp::max(max_append_id, seq);
                        }
                        Some(FileId {
                            queue: LogQueue::Rewrite,
                            seq,
                        }) => {
                            min_rewrite_id = std::cmp::min(min_rewrite_id, seq);
                            max_rewrite_id = std::cmp::max(max_rewrite_id, seq);
                        }
                        _ => {}
                    }
                }
            }
        });
        for (queue, min_id, max_id, files) in [
            (
                LogQueue::Append,
                min_append_id,
                max_append_id,
                &mut self.append_files,
            ),
            (
                LogQueue::Rewrite,
                min_rewrite_id,
                max_rewrite_id,
                &mut self.rewrite_files,
            ),
        ] {
            if max_id > 0 {
                // Try to cleanup stale metadata left by the previous version.
                let max_sample = 100;
                // Find the first obsolete metadata.
                let mut delete_start = None;
                for i in 0..max_sample {
                    let seq = i * min_id / max_sample;
                    let file_id = FileId { queue, seq };
                    let path = file_id.build_file_path(dir);
                    if self.file_system.exists_metadata(&path) {
                        delete_start = Some(i.saturating_sub(1) * min_id / max_sample + 1);
                        break;
                    }
                }
                // Delete metadata starting from the oldest. Abort on error.
                if let Some(start) = delete_start {
                    let mut success = 0;
                    for seq in start..min_id {
                        let file_id = FileId { queue, seq };
                        let path = file_id.build_file_path(dir);
                        match self.file_system.delete_metadata(&path) {
                            Err(e) => {
                                error!("failed to delete metadata of {}: {}.", path.display(), e);
                                break;
                            }
                            Ok(true) => success += 1,
                            _ => {}
                        }
                    }
                    warn!(
                        "deleted {} stale files of {:?} in range [{}, {}).",
                        success, queue, start, min_id,
                    );
                }
                for seq in min_id..=max_id {
                    let file_id = FileId { queue, seq };
                    let path = file_id.build_file_path(dir);
                    if !path.exists() {
                        warn!(
                            "Detected a hole when scanning directory, discarding files before {:?}.",
                            file_id,
                        );
                        files.clear();
                    } else {
                        let handle = Arc::new(self.file_system.open(&path)?);
                        files.push(FileToRecover {
                            seq,
                            handle,
                            version: None,
                        });
                    }
                }
            }
        }
        Ok(())
    }
pub fn scan ( & mut self ) -> Result < ( ) > { let dir = & self . cfg . dir ; let path = Path :: new ( dir ) ; if ! path . exists ( ) { info ! ( " " dir ) ; fs :: create_dir ( dir ) ? ; self . dir_lock = Some ( lock_dir ( dir ) ? ) ; return Ok ( ( ) ) ; } if ! path . is_dir ( ) { return Err ( box_err ! ( " " dir ) ) ; } self . dir_lock = Some ( lock_dir ( dir ) ? ) ; let ( mut min_append_id , mut max_append_id ) = ( u64 :: MAX , 0 ) ; let ( mut min_rewrite_id , mut max_rewrite_id ) = ( u64 :: MAX , 0 ) ; fs :: read_dir ( path ) ? . for_each ( | e | { if let Ok ( e ) = e { let p = e . path ( ) ; if p . is_file ( ) { match FileId :: parse_file_name ( p . file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) ) { Some ( FileId { queue : LogQueue :: Append , seq , } ) => { min_append_id = std :: cmp :: min ( min_append_id , seq ) ; max_append_id = std :: cmp :: max ( max_append_id , seq ) ; } Some ( FileId { queue : LogQueue :: Rewrite , seq , } ) => { min_rewrite_id = std :: cmp :: min ( min_rewrite_id , seq ) ; max_rewrite_id = std :: cmp :: max ( max_rewrite_id , seq ) ; } _ => { } } } } } ) ; for ( queue , min_id , max_id , files ) in [ ( LogQueue :: Append , min_append_id , max_append_id , & mut self . append_files , ) , ( LogQueue :: Rewrite , min_rewrite_id , max_rewrite_id , & mut self . rewrite_files , ) , ] { if max_id > 0 { // Try to cleanup stale metadata left by the previous version. let max_sample = 100 ; // Find the first obsolete metadata. let mut delete_start = None ; for i in 0 .. max_sample { let seq = i * min_id / max_sample ; let file_id = FileId { queue , seq } ; let path = file_id . build_file_path ( dir ) ; if self . file_system . exists_metadata ( & path ) { delete_start = Some ( i . saturating_sub ( 1 ) * min_id / max_sample + 1 ) ; break ; } } // Delete metadata starting from the oldest. Abort on error. if let Some ( start ) = delete_start { let mut success = 0 ; for seq in start .. min_id { let file_id = FileId { queue , seq } ; let path = file_id . build_file_path ( dir ) ; match self . file_system . delete_metadata ( & path ) { Err ( e ) => { error ! ( " " path display ( ) e ) ; break ; } Ok ( true ) => success += 1 , _ => { } } } warn ! ( " " success queue start min_id ) ; } for seq in min_id ..= max_id { let file_id = FileId { queue , seq } ; let path = file_id . build_file_path ( dir ) ; if ! path . exists ( ) { warn ! ( " " file_id ) ; files . clear ( ) ; } else { let handle = Arc :: new ( self . file_system . open ( & path ) ? ) ; files . push ( FileToRecover { seq , handle , version : None , } ) ; } } } } Ok ( ( ) ) }
Scans for all log files under the working directory.
Scans for all log files under the working directory .
&mut self