rust/hg-core/src/revlog/file_io.rs
changeset 52185 8d35941689af
parent 52171 7be39c5110c9
equal deleted inserted replaced
52184:735bf027dd1d 52185:8d35941689af
     1 //! Helpers for revlog file reading and writing.
     1 //! Helpers for revlog file reading and writing.
     2 
     2 
     3 use std::{
     3 use std::{
     4     cell::RefCell,
     4     cell::RefCell,
     5     fs::File,
       
     6     io::{Read, Seek, SeekFrom, Write},
     5     io::{Read, Seek, SeekFrom, Write},
     7     path::{Path, PathBuf},
     6     path::{Path, PathBuf},
     8     sync::{Arc, Mutex},
     7     sync::{Arc, Mutex},
     9 };
     8 };
    10 
     9 
    11 use crate::{
    10 use crate::{
    12     errors::{HgError, IoResultExt},
    11     errors::{HgError, IoResultExt},
    13     vfs::Vfs,
    12     vfs::{Vfs, VfsFile},
    14 };
    13 };
    15 
    14 
    16 /// Wraps accessing arbitrary chunks of data within a file and reusing handles.
    15 /// Wraps accessing arbitrary chunks of data within a file and reusing handles.
    17 /// This is currently useful for accessing a revlog's data file, only reading
    16 /// This is currently useful for accessing a revlog's data file, only reading
    18 /// the ranges that are currently relevant, like a sort of basic and manual
    17 /// the ranges that are currently relevant, like a sort of basic and manual
   121     pub fn is_empty(&self) -> bool {
   120     pub fn is_empty(&self) -> bool {
   122         self.len() == 0
   121         self.len() == 0
   123     }
   122     }
   124 }
   123 }
   125 
   124 
   126 /// Holds an open [`File`] and the related data. This can be used for reading
   125 /// Holds an open [`VfsFile`] and the related data. This can be used for
   127 /// and writing. Writes can be delayed to a buffer before touching the disk,
   126 /// reading and writing. Writes can be delayed to a buffer before touching
   128 /// if relevant (in the changelog case), but reads are transparent.
   127 /// the disk, if relevant (in the changelog case), but reads are transparent.
   129 pub struct FileHandle {
   128 pub struct FileHandle {
   130     /// The actual open file
   129     /// The actual open file
   131     pub file: File,
   130     pub file: VfsFile,
   132     /// The VFS with which the file was opened
   131     /// The VFS with which the file was opened
   133     vfs: Box<dyn Vfs>,
   132     vfs: Box<dyn Vfs>,
   134     /// Filename of the open file, relative to the repo root
   133     /// Filename of the open file, relative to the repo root
   135     filename: PathBuf,
   134     filename: PathBuf,
   136     /// Buffer of delayed entry writes to the changelog index. This points
   135     /// Buffer of delayed entry writes to the changelog index. This points
   169         filename: impl AsRef<Path>,
   168         filename: impl AsRef<Path>,
   170         create: bool,
   169         create: bool,
   171         write: bool,
   170         write: bool,
   172     ) -> Result<Self, HgError> {
   171     ) -> Result<Self, HgError> {
   173         let file = if create {
   172         let file = if create {
   174             vfs.create(filename.as_ref())?
   173             vfs.create(filename.as_ref(), false)?
   175         } else if write {
   174         } else if write {
   176             vfs.open(filename.as_ref())?
   175             vfs.open(filename.as_ref())?
   177         } else {
   176         } else {
   178             vfs.open_read(filename.as_ref())?
   177             vfs.open_read(filename.as_ref())?
   179         };
   178         };
   191         filename: impl AsRef<Path>,
   190         filename: impl AsRef<Path>,
   192         create: bool,
   191         create: bool,
   193         delayed_buffer: Arc<Mutex<DelayedBuffer>>,
   192         delayed_buffer: Arc<Mutex<DelayedBuffer>>,
   194     ) -> Result<Self, HgError> {
   193     ) -> Result<Self, HgError> {
   195         let mut file = if create {
   194         let mut file = if create {
   196             vfs.create(filename.as_ref())?
   195             vfs.create(filename.as_ref(), false)?
   197         } else {
   196         } else {
   198             vfs.open(filename.as_ref())?
   197             vfs.open(filename.as_ref())?
   199         };
   198         };
   200         let size = vfs.file_size(&file)?;
   199         let size = vfs.file_size(&file)?;
   201         let offset = file
   200         let offset = file
   214             delayed_buffer: Some(delayed_buffer),
   213             delayed_buffer: Some(delayed_buffer),
   215             file,
   214             file,
   216         })
   215         })
   217     }
   216     }
   218 
   217 
   219     /// Wrap an existing [`File`]
   218     /// Wrap an existing [`VfsFile`]
   220     pub fn from_file(
   219     pub fn from_file(
   221         file: File,
   220         file: VfsFile,
   222         vfs: Box<dyn Vfs>,
   221         vfs: Box<dyn Vfs>,
   223         filename: impl AsRef<Path>,
   222         filename: impl AsRef<Path>,
   224     ) -> Self {
   223     ) -> Self {
   225         Self {
   224         Self {
   226             vfs,
   225             vfs,
   228             delayed_buffer: None,
   227             delayed_buffer: None,
   229             file,
   228             file,
   230         }
   229         }
   231     }
   230     }
   232 
   231 
   233     /// Wrap an existing [`File`], but writes go to a [`DelayedBuffer`].
   232     /// Wrap an existing [`VfsFile`], but writes go to a [`DelayedBuffer`].
   234     pub fn from_file_delayed(
   233     pub fn from_file_delayed(
   235         mut file: File,
   234         mut file: VfsFile,
   236         vfs: Box<dyn Vfs>,
   235         vfs: Box<dyn Vfs>,
   237         filename: impl AsRef<Path>,
   236         filename: impl AsRef<Path>,
   238         delayed_buffer: Arc<Mutex<DelayedBuffer>>,
   237         delayed_buffer: Arc<Mutex<DelayedBuffer>>,
   239     ) -> Result<Self, HgError> {
   238     ) -> Result<Self, HgError> {
   240         let size = vfs.file_size(&file)?;
   239         let size = vfs.file_size(&file)?;