fn recover()

in common/rusty_leveldb_sgx/src/db_impl.rs [161:235]


    fn recover(&mut self, ve: &mut VersionEdit) -> Result<bool> {
        if self.opt.error_if_exists && self.opt.env.exists(&self.path.as_ref()).unwrap_or(false) {
            return err(StatusCode::AlreadyExists, "database already exists");
        }

        let _ = self.opt.env.mkdir(Path::new(&self.path));
        self.acquire_lock()?;

        if let Err(e) = read_current_file(&self.opt.env, &self.path) {
            if e.code == StatusCode::NotFound && self.opt.create_if_missing {
                self.initialize_db()?;
            } else {
                return err(
                    StatusCode::InvalidArgument,
                    "database does not exist and create_if_missing is false",
                );
            }
        }

        // If save_manifest is true, we should log_and_apply() later in order to write the new
        // manifest.
        let mut save_manifest = self.vset.borrow_mut().recover()?;

        // Recover from all log files not in the descriptor.
        let mut max_seq = 0;
        let filenames = self.opt.env.children(&self.path)?;
        let mut expected = self.vset.borrow().live_files();
        let mut log_files = vec![];

        for file in &filenames {
            if file
                .to_str()
                .ok_or_else(|| Status::new(StatusCode::InvalidArgument, "not valid UTF-8"))?
                .ends_with(SGX_RECOVERY_FILE_SUFFIX)
            {
                continue;
            }

            match parse_file_name(&file) {
                Ok((num, typ)) => {
                    expected.remove(&num);
                    if typ == FileType::Log
                        && (num >= self.vset.borrow().log_num
                            || num == self.vset.borrow().prev_log_num)
                    {
                        log_files.push(num);
                    }
                }
                Err(e) => return Err(e.annotate(format!("While parsing {:?}", file))),
            }
        }
        if !expected.is_empty() {
            log!(self.opt.log, "Missing at least these files: {:?}", expected);
            return err(StatusCode::Corruption, "missing live files (see log)");
        }

        log_files.sort();
        for i in 0..log_files.len() {
            let (save_manifest_, max_seq_) =
                self.recover_log_file(log_files[i], i == log_files.len() - 1, ve)?;
            if save_manifest_ {
                save_manifest = true;
            }
            if max_seq_ > max_seq {
                max_seq = max_seq_;
            }
            self.vset.borrow_mut().mark_file_number_used(log_files[i]);
        }

        if self.vset.borrow().last_seq < max_seq {
            self.vset.borrow_mut().last_seq = max_seq;
        }

        Ok(save_manifest)
    }