Buffer the writes when writing a layer to disk.

Significantly reduces the CPU time spent on libc::write.
This commit is contained in:
Heikki Linnakangas
2021-09-21 16:54:29 +03:00
parent 49c8c03465
commit a91eeb1c65
3 changed files with 13 additions and 9 deletions

View File

@@ -16,14 +16,14 @@ pub fn read_blob(reader: &BoundedReader<&'_ File>, range: &BlobRange) -> Result<
Ok(buf)
}
pub struct BlobWriter {
writer: ChapterWriter<File>,
pub struct BlobWriter<W> {
writer: ChapterWriter<W>,
offset: u64,
}
impl BlobWriter {
impl<W: Write> BlobWriter<W> {
// This function takes a BookWriter and creates a new chapter to ensure offset is 0.
pub fn new(book_writer: BookWriter<File>, chapter_id: impl Into<ChapterId>) -> Self {
pub fn new(book_writer: BookWriter<W>, chapter_id: impl Into<ChapterId>) -> Self {
let writer = book_writer.new_chapter(chapter_id);
Self { writer, offset: 0 }
}
@@ -39,7 +39,7 @@ impl BlobWriter {
Ok(range)
}
pub fn close(self) -> bookfile::Result<BookWriter<File>> {
pub fn close(self) -> bookfile::Result<BookWriter<W>> {
self.writer.close()
}
}

View File

@@ -56,7 +56,7 @@ use std::collections::BTreeMap;
use std::fmt::Write as _;
use std::fs;
use std::fs::File;
use std::io::Write;
use std::io::{BufWriter, Write};
use std::ops::Bound::Included;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex, MutexGuard};
@@ -425,7 +425,8 @@ impl DeltaLayer {
// Note: This overwrites any existing file. There shouldn't be any.
// FIXME: throw an error instead?
let file = File::create(&path)?;
let book = BookWriter::new(file, DELTA_FILE_MAGIC)?;
let buf_writer = BufWriter::new(file);
let book = BookWriter::new(buf_writer, DELTA_FILE_MAGIC)?;
let mut page_version_writer = BlobWriter::new(book, PAGE_VERSIONS_CHAPTER);
@@ -482,6 +483,7 @@ impl DeltaLayer {
Summary::ser_into(&summary, &mut chapter)?;
let book = chapter.close()?;
// This flushes the underlying 'buf_writer'.
book.close()?;
trace!("saved {}", &path.display());

View File

@@ -36,7 +36,7 @@ use serde::{Deserialize, Serialize};
use std::convert::TryInto;
use std::fs;
use std::fs::File;
use std::io::Write;
use std::io::{BufWriter, Write};
use std::path::{Path, PathBuf};
use std::sync::{Mutex, MutexGuard};
@@ -305,7 +305,8 @@ impl ImageLayer {
// Note: This overwrites any existing file. There shouldn't be any.
// FIXME: throw an error instead?
let file = File::create(&path)?;
let book = BookWriter::new(file, IMAGE_FILE_MAGIC)?;
let buf_writer = BufWriter::new(file);
let book = BookWriter::new(buf_writer, IMAGE_FILE_MAGIC)?;
let book = match &image_type {
ImageType::Blocky { .. } => {
@@ -334,6 +335,7 @@ impl ImageLayer {
Summary::ser_into(&summary, &mut chapter)?;
let book = chapter.close()?;
// This flushes the underlying 'buf_writer'.
book.close()?;
trace!("saved {}", &path.display());