Don't fsync media files on import

I was seeing import speeds of only 10-20 files a second before this
change.
This commit is contained in:
Damien Elmes 2022-03-19 23:29:16 +10:00
parent 16fe18d033
commit d100f7a2c8
4 changed files with 16 additions and 7 deletions

View File

@ -63,7 +63,7 @@ impl Collection {
&tr,
progress_fn,
)?;
atomic_rename(temp_colpkg, colpkg_name)
atomic_rename(temp_colpkg, colpkg_name, true)
}
}

View File

@ -75,7 +75,7 @@ pub fn import_colpkg(
let media_folder = Path::new(target_media_folder);
restore_media(&meta, progress_fn, &mut archive, media_folder)?;
atomic_rename(tempfile, &col_path)
atomic_rename(tempfile, &col_path, true)
}
fn check_collection(col_path: &Path) -> Result<()> {
@ -143,7 +143,7 @@ fn restore_media_file(meta: &Meta, zip_file: &mut ZipFile, path: &Path) -> Resul
}
.map_err(|err| AnkiError::file_io_error(err, path))?;
atomic_rename(tempfile, path)
atomic_rename(tempfile, path, false)
}
impl MediaEntry {

View File

@ -14,11 +14,20 @@ pub(crate) fn tempfile_in_parent_of(file: &Path) -> Result<NamedTempFile> {
NamedTempFile::new_in(dir).map_err(|err| AnkiError::file_io_error(err, dir))
}
pub(crate) fn atomic_rename(file: NamedTempFile, target: &Path) -> Result<()> {
file.as_file().sync_all()?;
/// Atomically replace the target path with the provided temp file.
///
/// If `fsync` is true, file data is synced to disk prior to renaming, and the
/// folder is synced on UNIX platforms after renaming. This minimizes the
/// chances of corruption if there is a crash or power loss directly after the
/// op, but it can be considerably slower.
pub(crate) fn atomic_rename(file: NamedTempFile, target: &Path, fsync: bool) -> Result<()> {
if fsync {
file.as_file().sync_all()?;
}
file.persist(&target)
.map_err(|err| AnkiError::IoError(format!("write {target:?} failed: {err}")))?;
if !cfg!(windows) {
#[cfg(not(windows))]
if fsync {
if let Some(parent) = target.parent() {
std::fs::File::open(parent)
.and_then(|file| file.sync_all())

View File

@ -680,7 +680,7 @@ impl Collection {
let db = open_and_check_sqlite_file(out_file.path())?;
db.execute_batch("update col set ls=mod")?;
drop(db);
atomic_rename(out_file, &col_path)?;
atomic_rename(out_file, &col_path, true)?;
Ok(())
}