Use temporary file to save bitmaps (#1840)

This commit is contained in:
eupn
2018-10-26 21:50:26 +03:00
committed by hashmap
parent ee5d6859fc
commit 495c9ded58
3 changed files with 51 additions and 14 deletions
+9 -9
View File
@@ -15,8 +15,6 @@
//! Compact (roaring) bitmap representing the set of leaf positions
//! that exist and are not currently pruned in the MMR.
use std::fs::File;
use std::io::{self, BufWriter, Read, Write};
use std::path::Path;
use croaring::Bitmap;
@@ -25,6 +23,10 @@ use core::core::hash::Hashed;
use core::core::pmmr;
use core::core::BlockHeader;
use prune_list::PruneList;
use save_via_temp_file;
use std::fs::File;
use std::io::{self, BufWriter, Read, Write};
/// Compact (roaring) bitmap representing the set of positions of
/// leaves that are currently unpruned in the MMR.
@@ -168,14 +170,12 @@ impl LeafSet {
// First run the optimization step on the bitmap.
self.bitmap.run_optimize();
// TODO - consider writing this to disk in a tmp file and then renaming?
// Write the updated bitmap file to disk.
{
let mut file = BufWriter::new(File::create(self.path.clone())?);
file.write_all(&self.bitmap.serialize())?;
file.flush()?;
}
save_via_temp_file(&self.path, ".tmp", |w| {
let mut w = BufWriter::new(w);
w.write_all(&self.bitmap.serialize())?;
w.flush()
})?;
// Make sure our backup in memory is up to date.
self.bitmap_bak = self.bitmap.clone();
+36
View File
@@ -76,3 +76,39 @@ pub fn u64_to_key<'a>(prefix: u8, val: u64) -> Vec<u8> {
u64_vec.insert(0, prefix);
u64_vec
}
/// Creates temporary file with name created by adding `temp_suffix` to `path`.
/// Applies writer function to it and renames temporary file into original specified by `path`.
pub fn save_via_temp_file<F>(
path: &str,
temp_suffix: &str,
mut writer: F,
) -> Result<(), std::io::Error>
where
F: FnMut(Box<std::io::Write>) -> Result<(), std::io::Error>,
{
assert_ne!(*temp_suffix, *"");
use std::fs::{remove_file, rename, File};
use std::path::Path;
// Write temporary file
let temp_name = format!("{}{}", &path, temp_suffix);
let temp_path = Path::new(&temp_name);
if temp_path.exists() {
remove_file(&temp_path)?;
}
let file = File::create(&temp_path)?;
writer(Box::new(file))?;
// Move temporary file into original
let original = Path::new(&path);
if original.exists() {
remove_file(&original)?;
}
rename(&temp_path, &original)?;
Ok(())
}
+6 -5
View File
@@ -28,6 +28,7 @@ use std::path::Path;
use croaring::Bitmap;
use core::core::pmmr::{bintree_postorder_height, family, path};
use save_via_temp_file;
/// Maintains a list of previously pruned nodes in PMMR, compacting the list as
/// parents get pruned and allowing checking whether a leaf is pruned. Given
@@ -115,13 +116,13 @@ impl PruneList {
// Run the optimization step on the bitmap.
self.bitmap.run_optimize();
// TODO - consider writing this to disk in a tmp file and then renaming?
// Write the updated bitmap file to disk.
if let Some(ref path) = self.path {
let mut file = BufWriter::new(File::create(path)?);
file.write_all(&self.bitmap.serialize())?;
file.flush()?;
save_via_temp_file(&path, ".tmp", |w| {
let mut w = BufWriter::new(w);
w.write_all(&self.bitmap.serialize())?;
w.flush()
})?;
}
// Rebuild our "shift caches" here as we are flushing changes to disk