From b16844e552bab79caff8503046b8a0e743e161c8 Mon Sep 17 00:00:00 2001 From: Haoran Yi Date: Mon, 2 May 2022 10:09:27 -0500 Subject: [PATCH] mmap --- runtime/src/snapshot_utils.rs | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/runtime/src/snapshot_utils.rs b/runtime/src/snapshot_utils.rs index 10ada21b41cce4..c4a93f2e33910f 100644 --- a/runtime/src/snapshot_utils.rs +++ b/runtime/src/snapshot_utils.rs @@ -22,6 +22,7 @@ use { flate2::read::GzDecoder, lazy_static::lazy_static, log::*, + memmap2::Mmap, rayon::prelude::*, regex::Regex, solana_measure::measure::Measure, @@ -34,6 +35,7 @@ use { io::{BufReader, BufWriter, Error as IoError, ErrorKind, Read, Seek, Write}, path::{Path, PathBuf}, process::ExitStatus, + slice, str::FromStr, sync::Arc, }, @@ -1472,33 +1474,53 @@ fn untar_snapshot_in>( archive_format: ArchiveFormat, parallel_divisions: usize, ) -> Result { - let open_file = || File::open(&snapshot_tar).unwrap(); + let file = File::open(&snapshot_tar).unwrap(); + + // Map the file into immutable memory for better I/O performance + let mmap = unsafe { Mmap::map(&file) }; + let mmap = mmap.unwrap_or_else(|e| { + error!( + "Failed to map the snapshot file: {} {}.\n + Please increase the virtual memory on the system.", + snapshot_tar.as_ref().display(), + e, + ); + std::process::exit(1); + }); + + // The following code is safe because the lifetime of mmap last till the end of the function + // while the usage of mmap, BufReader's lifetime only last within fn unpack_snapshot_local. + let len = &mmap[..].len(); + let ptr = &mmap[0] as *const u8; + let slice = unsafe { slice::from_raw_parts(ptr, *len) }; + let account_paths_map = match archive_format { ArchiveFormat::TarBzip2 => unpack_snapshot_local( - || BzDecoder::new(BufReader::new(open_file())), + || BzDecoder::new(BufReader::new(slice)), unpack_dir, account_paths, parallel_divisions, )?, ArchiveFormat::TarGzip => unpack_snapshot_local( - || GzDecoder::new(BufReader::new(open_file())), + || GzDecoder::new(BufReader::new(slice)), unpack_dir, account_paths, parallel_divisions, )?, ArchiveFormat::TarZstd => unpack_snapshot_local( - || zstd::stream::read::Decoder::new(BufReader::new(open_file())).unwrap(), + || zstd::stream::read::Decoder::new(BufReader::new(slice)).unwrap(), unpack_dir, account_paths, parallel_divisions, )?, ArchiveFormat::Tar => unpack_snapshot_local( - || BufReader::new(open_file()), + || BufReader::new(slice), unpack_dir, account_paths, parallel_divisions, )?, }; + Ok(account_paths_map) }