in common/rusty_leveldb_sgx/src/db_impl.rs [240:311]
fn recover_log_file(
&mut self,
log_num: FileNum,
is_last: bool,
ve: &mut VersionEdit,
) -> Result<(bool, SequenceNumber)> {
let filename = log_file_name(&self.path, log_num);
let mut compactions = 0;
let mut max_seq = 0;
let mut save_manifest = false;
let cmp: Rc<Box<dyn Cmp>> = self.opt.cmp.clone();
let mut mem = MemTable::new(cmp.clone());
{
let logfile = self.opt.env.open_sequential_file(Path::new(&filename))?;
// Use the user-supplied comparator; it will be wrapped inside a MemtableKeyCmp.
let mut logreader = LogReader::new(
logfile, // checksum=
true,
);
log!(self.opt.log, "Recovering log file {:?}", filename);
let mut scratch = vec![];
let mut batch = WriteBatch::new();
while let Ok(len) = logreader.read(&mut scratch) {
if len == 0 {
break;
}
if len < 12 {
log!(
self.opt.log,
"corruption in log file {:06}: record shorter than 12B",
log_num
);
continue;
}
batch.set_contents(&scratch);
batch.insert_into_memtable(batch.sequence(), &mut mem);
let last_seq = batch.sequence() + batch.count() as u64 - 1;
if last_seq > max_seq {
max_seq = last_seq
}
if mem.approx_mem_usage() > self.opt.write_buffer_size {
compactions += 1;
self.write_l0_table(&mem, ve, None)?;
save_manifest = true;
mem = MemTable::new(cmp.clone());
}
batch.clear();
}
}
// Check if we can reuse the last log file.
if self.opt.reuse_logs && is_last && compactions == 0 {
assert!(self.log.is_none());
log!(self.opt.log, "reusing log file {:?}", filename);
let oldsize = self.opt.env.size_of(Path::new(&filename))?;
let oldfile = self.opt.env.open_appendable_file(Path::new(&filename))?;
let lw = LogWriter::new_with_off(BufWriter::new(oldfile), oldsize);
self.log = Some(lw);
self.log_num = Some(log_num);
self.mem = mem;
} else if mem.len() > 0 {
// Log is not reused, so write out the accumulated memtable.
save_manifest = true;
self.write_l0_table(&mem, ve, None)?;
}
Ok((save_manifest, max_seq))
}