pub fn new<P: AsRef<Path>>(base_dir: P, lock_info: LockInfo) -> Result<Self, Error> {
        let base_dir = base_dir.as_ref();
        fs::create_dir_all(&base_dir)?;
        {
            // TODO: flock this for good measure?
            let _ = file_storage_lock(&Self::lockfile_path(&base_dir), lock_info)?;
        }
        let data_path = Self::data_path(&base_dir);
        let mut data_file = OpenOptions::new()
            .append(true)
            .read(true)
            .create(true)
            .open(&data_path)?;

        let metadata_path = Self::metadata_path(&base_dir);
        let mut metadata_file = OpenOptions::new()
            .write(true)
            .read(true)
            .create(true)
            .open(&metadata_path)?;

        // Retrieve the last truncated sequence number from the metadata file
        // unless that file was just created, in which case default to 0.
        let mut bytes = Vec::new();
        metadata_file.read_to_end(&mut bytes)?;
        let len = bytes.len();
        let seqno_start = if len != 0 {
            let mut bytes = &bytes[..];
            let mut buf = [0u8; 8];
            // Decode sequence number
            bytes.read_exact(&mut buf).map_err(|e| {
                format!(
                    "could not read log metadata file: found {} bytes (expected 8) {:?}",
                    len, e,
                )
            })?;
            SeqNo(u64::from_le_bytes(buf))
        } else {
            metadata_file.write_all(&0u64.to_le_bytes())?;
            metadata_file.sync_all()?;
            SeqNo(0)
        };

        // Retrieve the most recently written sequence number in the log,
        // unless the log is empty in which case default to 0.
        let seqno_end = {
            let len = data_file.metadata()?.len();

            if len > 0 {
                let mut buf = [0u8; 8];
                data_file.seek(SeekFrom::End(-8))?;
                data_file.read_exact(&mut buf)?;
                // NB: seqno_end is exclusive, so we have to add one to the
                // seqno of the most recent write to reconstruct it.
                SeqNo(u64::from_le_bytes(buf) + 1)
            } else {
                SeqNo(0)
            }
        };

        if seqno_start > seqno_end {
            return Err(format!(
                "invalid sequence number range found for file log: start: {:?} end: {:?}",
                seqno_start, seqno_end,
            )
            .into());
        }

        Ok(FileLog {
            base_dir: Some(base_dir.to_owned()),
            dataz: Arc::new(Mutex::new(FileLogCore {
                dataz: data_file,
                metadata: metadata_file,
            })),
            seqno: seqno_start..seqno_end,
            buf: Vec::new(),
        })
    }
/// Returns a new [FileLog] which stores files under the given dir.
///
/// To ensure directory-wide mutual exclusion, a LOCK file is placed in
/// base_dir at construction time. If this file already exists (indicating
/// that another FileLog is already using the dir), an error is returned
/// from `new`.
///
/// The contents of `lock_info` are stored in the LOCK file and should
/// include anything that would help debug an unexpected LOCK file, such as
/// version, ip, worker number, etc.
///
/// The data is stored in a separate file, and is formatted as a sequential list of
/// chunks corresponding to each write. Each chunk consists of:
/// `length` - A 64 bit unsigned int (little-endian) indicating the size of `data`.
/// `data` - `length` bytes of data.
/// `sequence_number` - A 64 bit unsigned int (little-endian) indicating the sequence number
/// assigned to `data`.
///
/// Additionally, the metadata about the last truncated sequence number is stored in a
/// metadata file, which only ever contains a single 64 bit unsigned integer (also little-endian)
/// that indicates the most recently truncated offset (ie all offsets less than this are truncated).
Returns a new [FileLog] which stores files under the given dir.
To ensure directory-wide mutual exclusion, a LOCK file is placed in
base_dir at construction time. If this file already exists (indicating
that another FileLog is already using the dir), an error is returned
from `new`.

The contents of `lock_info` are stored in the LOCK file and should
include anything that would help debug an unexpected LOCK file, such as
version, ip, worker number, etc.

The data is stored in a separate file, and is formatted as a sequential list of
chunks corresponding to each write. Each chunk consists of:
`length` - A 64 bit unsigned int (little-endian) indicating the size of `data`.
`data` - `length` bytes of data.
`sequence_number` - A 64 bit unsigned int (little-endian) indicating the sequence number
assigned to `data`.

Additionally, the metadata about the last truncated sequence number is stored in a
metadata file, which only ever contains a single 64 bit unsigned integer (also little-endian)
that indicates the most recently truncated offset .
Returns a new [ FileLog ] which stores files under the given dir . To ensure directory - wide mutual exclusion a LOCK file is placed in base_dir at construction time . If this file already exists ( indicating that another FileLog is already using the dir ) an error is returned from ` new ` . The contents of ` lock_info ` are stored in the LOCK file and should include anything that would help debug an unexpected LOCK file such as version ip worker number etc . The data is stored in a separate file and is formatted as a sequential list of chunks corresponding to each write . Each chunk consists of : ` length ` - A 64 bit unsigned int ( little - endian ) indicating the size of ` data ` . ` data ` - ` length ` bytes of data . ` sequence_number ` - A 64 bit unsigned int ( little - endian ) indicating the sequence number assigned to ` data ` . Additionally the metadata about the last truncated sequence number is stored in a metadata file which only ever contains a single 64 bit unsigned integer ( also little - endian ) that indicates the most recently truncated offset .
pub fn new<P: AsRef<Path>>(base_dir: P, lock_info: LockInfo) -> Result<Self, Error> {
        let base_dir = base_dir.as_ref();
        fs::create_dir_all(&base_dir)?;
        {
            // TODO: flock this for good measure?
            let _ = file_storage_lock(&Self::lockfile_path(&base_dir), lock_info)?;
        }
        let data_path = Self::data_path(&base_dir);
        let mut data_file = OpenOptions::new()
            .append(true)
            .read(true)
            .create(true)
            .open(&data_path)?;
        let metadata_path = Self::metadata_path(&base_dir);
        let mut metadata_file = OpenOptions::new()
            .write(true)
            .read(true)
            .create(true)
            .open(&metadata_path)?;
        // Retrieve the last truncated sequence number from the metadata file
        // unless that file was just created, in which case default to 0.
        let mut bytes = Vec::new();
        metadata_file.read_to_end(&mut bytes)?;
        let len = bytes.len();
        let seqno_start = if len != 0 {
            let mut bytes = &bytes[..];
            let mut buf = [0u8; 8];
            // Decode sequence number
            bytes.read_exact(&mut buf).map_err(|e| {
                format!(
                    "could not read log metadata file: found {} bytes (expected 8) {:?}",
                    len, e,
                )
            })?;
            SeqNo(u64::from_le_bytes(buf))
        } else {
            metadata_file.write_all(&0u64.to_le_bytes())?;
            metadata_file.sync_all()?;
            SeqNo(0)
        };
        // Retrieve the most recently written sequence number in the log,
        // unless the log is empty in which case default to 0.
        let seqno_end = {
            let len = data_file.metadata()?.len();
            if len > 0 {
                let mut buf = [0u8; 8];
                data_file.seek(SeekFrom::End(-8))?;
                data_file.read_exact(&mut buf)?;
                // NB: seqno_end is exclusive, so we have to add one to the
                // seqno of the most recent write to reconstruct it.
                SeqNo(u64::from_le_bytes(buf) + 1)
            } else {
                SeqNo(0)
            }
        };
        if seqno_start > seqno_end {
            return Err(format!(
                "invalid sequence number range found for file log: start: {:?} end: {:?}",
                seqno_start, seqno_end,
            )
            .into());
        }
        Ok(FileLog {
            base_dir: Some(base_dir.to_owned()),
            dataz: Arc::new(Mutex::new(FileLogCore {
                dataz: data_file,
                metadata: metadata_file,
            })),
            seqno: seqno_start..seqno_end,
            buf: Vec::new(),
        })
    }
pub fn new < P : AsRef < Path > > ( base_dir : P , lock_info : LockInfo ) -> Result < Self , Error > { let base_dir = base_dir . as_ref ( ) ; fs :: create_dir_all ( & base_dir ) ? ; { // TODO: flock this for good measure? let _ = file_storage_lock ( & Self :: lockfile_path ( & base_dir ) , lock_info ) ? ; } let data_path = Self :: data_path ( & base_dir ) ; let mut data_file = OpenOptions :: new ( ) . append ( true ) . read ( true ) . create ( true ) . open ( & data_path ) ? ; let metadata_path = Self :: metadata_path ( & base_dir ) ; let mut metadata_file = OpenOptions :: new ( ) . write ( true ) . read ( true ) . create ( true ) . open ( & metadata_path ) ? ; // Retrieve the last truncated sequence number from the metadata file // unless that file was just created, in which case default to 0. let mut bytes = Vec :: new ( ) ; metadata_file . read_to_end ( & mut bytes ) ? ; let len = bytes . len ( ) ; let seqno_start = if len != 0 { let mut bytes = & bytes [ .. ] ; let mut buf = [ 0u8 ; 8 ] ; // Decode sequence number bytes . read_exact ( & mut buf ) . map_err ( | e | { format ! ( " " len e ) } ) ? ; SeqNo ( u64 :: from_le_bytes ( buf ) ) } else { metadata_file . write_all ( & 0u64 . to_le_bytes ( ) ) ? ; metadata_file . sync_all ( ) ? ; SeqNo ( 0 ) } ; // Retrieve the most recently written sequence number in the log, // unless the log is empty in which case default to 0. let seqno_end = { let len = data_file . metadata ( ) ? . len ( ) ; if len > 0 { let mut buf = [ 0u8 ; 8 ] ; data_file . seek ( SeekFrom :: End ( - 8 ) ) ? ; data_file . read_exact ( & mut buf ) ? ; // NB: seqno_end is exclusive, so we have to add one to the // seqno of the most recent write to reconstruct it. SeqNo ( u64 :: from_le_bytes ( buf ) + 1 ) } else { SeqNo ( 0 ) } } ; if seqno_start > seqno_end { return Err ( format ! ( " " seqno_start seqno_end ) . into ( ) ) ; } Ok ( FileLog { base_dir : Some ( base_dir . to_owned ( ) ) , dataz : Arc :: new ( Mutex :: new ( FileLogCore { dataz : data_file , metadata : metadata_file , } ) ) , seqno : seqno_start .. seqno_end , buf : Vec :: new ( ) , } ) }
Returns a new [FileLog] which stores files under the given dir.
Returns a new [ FileLog ] which stores files under the given dir .
base_dir
P
lock_info
LockInfo
base_dir
P
lock_info
LockInfo