Revert "rework prune rewrite with iterators (#3568)" (#3569)

This reverts commit 5092652b0c.
This commit is contained in:
Antioch Peverell 2021-02-22 14:18:23 +00:00 committed by GitHub
parent 5092652b0c
commit 4de2d92433
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 51 deletions

View file

@ -25,6 +25,7 @@ extern crate log;
use failure; use failure;
#[macro_use] #[macro_use]
extern crate failure_derive; extern crate failure_derive;
#[macro_use]
extern crate grin_core as core; extern crate grin_core as core;
extern crate grin_util as util; extern crate grin_util as util;

View file

@ -354,29 +354,29 @@ impl<T: PMMRable> PMMRBackend<T> {
// 1. Save compact copy of the hash file, skipping removed data. // 1. Save compact copy of the hash file, skipping removed data.
{ {
let pos_to_rm = pos_to_rm.iter().map(|x| x as u64).map(|pos| { let pos_to_rm = map_vec!(pos_to_rm, |pos| {
let shift = self.prune_list.get_shift(pos); let shift = self.prune_list.get_shift(pos.into());
pos - shift pos as u64 - shift
}); });
self.hash_file.write_tmp_pruned(pos_to_rm)?; self.hash_file.save_prune(&pos_to_rm)?;
self.hash_file.replace_with_tmp()?;
} }
// 2. Save compact copy of the data file, skipping removed leaves. // 2. Save compact copy of the data file, skipping removed leaves.
{ {
let pos_to_rm = pos_to_rm let leaf_pos_to_rm = pos_to_rm
.iter() .iter()
.filter(|&x| pmmr::is_leaf(x.into()))
.map(|x| x as u64) .map(|x| x as u64)
.filter(|&x| pmmr::is_leaf(x)) .collect::<Vec<_>>();
.map(|pos| {
let flat_pos = pmmr::n_leaves(pos);
let shift = self.prune_list.get_leaf_shift(pos);
flat_pos - shift
});
self.data_file.write_tmp_pruned(pos_to_rm)?; let pos_to_rm = map_vec!(leaf_pos_to_rm, |&pos| {
self.data_file.replace_with_tmp()?; let flat_pos = pmmr::n_leaves(pos);
let shift = self.prune_list.get_leaf_shift(pos);
flat_pos - shift
});
self.data_file.save_prune(&pos_to_rm)?;
} }
// 3. Update the prune list and write to disk. // 3. Update the prune list and write to disk.

View file

@ -154,18 +154,10 @@ where
} }
/// Write the file out to disk, pruning removed elements. /// Write the file out to disk, pruning removed elements.
pub fn write_tmp_pruned<I>(&self, prune_pos: I) -> io::Result<()> pub fn save_prune(&mut self, prune_pos: &[u64]) -> io::Result<()> {
where
I: IntoIterator<Item = u64>,
{
// Need to convert from 1-index to 0-index (don't ask). // Need to convert from 1-index to 0-index (don't ask).
let prune_idx = prune_pos.into_iter().map(|x| x - 1); let prune_idx: Vec<_> = prune_pos.iter().map(|x| x - 1).collect();
self.file.write_tmp_pruned(prune_idx) self.file.save_prune(prune_idx.as_slice())
}
/// Replace underlying file with the file at our tmp path.
pub fn replace_with_tmp(&mut self) -> io::Result<()> {
self.file.replace_with_tmp()
} }
} }
@ -493,52 +485,39 @@ where
Ok(file) Ok(file)
} }
fn tmp_file_path(&self) -> PathBuf {
self.path.with_extension("tmp")
}
/// Saves a copy of the current file content, skipping data at the provided /// Saves a copy of the current file content, skipping data at the provided
/// prune positions. prune_pos must be ordered. /// prune positions. prune_pos must be ordered.
fn write_tmp_pruned<I>(&self, prune_pos: I) -> io::Result<()> pub fn save_prune(&mut self, prune_pos: &[u64]) -> io::Result<()> {
where let tmp_path = self.path.with_extension("tmp");
I: IntoIterator<Item = u64>,
{
let mut prune_pos = prune_pos.into_iter().peekable();
// Scope the reader and writer to within the block so we can safely replace files later on. // Scope the reader and writer to within the block so we can safely replace files later on.
{ {
let reader = File::open(&self.path)?; let reader = File::open(&self.path)?;
let mut buf_reader = BufReader::new(reader); let mut buf_reader = BufReader::new(reader);
let mut streaming_reader = StreamingReader::new(&mut buf_reader, self.version); let mut streaming_reader = StreamingReader::new(&mut buf_reader, self.version);
let tmp_path = self.tmp_file_path();
let mut buf_writer = BufWriter::new(File::create(tmp_path)?); let mut buf_writer = BufWriter::new(File::create(&tmp_path)?);
let mut bin_writer = BinWriter::new(&mut buf_writer, self.version); let mut bin_writer = BinWriter::new(&mut buf_writer, self.version);
let mut current_pos = 0; let mut current_pos = 0;
let mut prune_pos = prune_pos;
while let Ok(elmt) = T::read(&mut streaming_reader) { while let Ok(elmt) = T::read(&mut streaming_reader) {
if let Some(pos) = prune_pos.peek() { if prune_pos.contains(&current_pos) {
if *pos == current_pos { // Pruned pos, moving on.
// Pruned pos, moving on. prune_pos = &prune_pos[1..];
prune_pos.next(); } else {
current_pos += 1; // Not pruned, write to file.
continue; elmt.write(&mut bin_writer)
} .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
} }
// Not pruned, write to file.
elmt.write(&mut bin_writer)
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
current_pos += 1; current_pos += 1;
} }
buf_writer.flush()?; buf_writer.flush()?;
} }
Ok(())
}
fn replace_with_tmp(&mut self) -> io::Result<()> {
// Replace the underlying file - // Replace the underlying file -
// pmmr_data.tmp -> pmmr_data.bin // pmmr_data.tmp -> pmmr_data.bin
self.replace(self.tmp_file_path())?; self.replace(&tmp_path)?;
// Now rebuild our size file to reflect the pruned data file. // Now rebuild our size file to reflect the pruned data file.
// This will replace the underlying file internally. // This will replace the underlying file internally.
@ -596,6 +575,7 @@ where
} }
/// Replace the underlying file with another file, deleting the original. /// Replace the underlying file with another file, deleting the original.
/// Takes an optional size_file path in addition to path.
fn replace<P>(&mut self, with: P) -> io::Result<()> fn replace<P>(&mut self, with: P) -> io::Result<()>
where where
P: AsRef<Path> + Debug, P: AsRef<Path> + Debug,