(D8958#inline-14994 followup 2/2)
- make Index owner of its bytes
- make Index::new return an error if offset != bytes.len()
Alphare |
hg-reviewers |
(D8958#inline-14994 followup 2/2)
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
Path | Packages | |||
---|---|---|---|---|
M | rust/hg-core/src/revlog/index.rs (19 lines) | |||
M | rust/hg-core/src/revlog/revlog.rs (2 lines) |
use std::ops::Deref; | use std::ops::Deref; | ||||
use byteorder::{BigEndian, ByteOrder}; | use byteorder::{BigEndian, ByteOrder}; | ||||
use crate::revlog::revlog::RevlogError; | |||||
use crate::revlog::{Revision, NULL_REVISION}; | use crate::revlog::{Revision, NULL_REVISION}; | ||||
pub const INDEX_ENTRY_SIZE: usize = 64; | pub const INDEX_ENTRY_SIZE: usize = 64; | ||||
/// A Revlog index | /// A Revlog index | ||||
pub struct Index { | pub struct Index { | ||||
bytes: Box<dyn Deref<Target = [u8]> + Send>, | bytes: Box<dyn Deref<Target = [u8]> + Send>, | ||||
/// Offsets of starts of index blocks. | /// Offsets of starts of index blocks. | ||||
/// Only needed when the index is interleaved with data. | /// Only needed when the index is interleaved with data. | ||||
offsets: Option<Vec<usize>>, | offsets: Option<Vec<usize>>, | ||||
} | } | ||||
impl Index { | impl Index { | ||||
/// Create an index from bytes. | /// Create an index from bytes. | ||||
/// Calculate the start of each entry when is_inline is true. | /// Calculate the start of each entry when is_inline is true. | ||||
pub fn new(bytes: Box<dyn Deref<Target = [u8]> + Send>) -> Self { | pub fn new( | ||||
bytes: Box<dyn Deref<Target = [u8]> + Send>, | |||||
) -> Result<Self, RevlogError> { | |||||
if is_inline(&bytes) { | if is_inline(&bytes) { | ||||
let mut offset: usize = 0; | let mut offset: usize = 0; | ||||
let mut offsets = Vec::new(); | let mut offsets = Vec::new(); | ||||
while offset + INDEX_ENTRY_SIZE <= bytes.len() { | while offset + INDEX_ENTRY_SIZE <= bytes.len() { | ||||
offsets.push(offset); | offsets.push(offset); | ||||
let end = offset + INDEX_ENTRY_SIZE; | let end = offset + INDEX_ENTRY_SIZE; | ||||
let entry = IndexEntry { | let entry = IndexEntry { | ||||
bytes: &bytes[offset..end], | bytes: &bytes[offset..end], | ||||
offset_override: None, | offset_override: None, | ||||
}; | }; | ||||
offset += INDEX_ENTRY_SIZE + entry.compressed_len(); | offset += INDEX_ENTRY_SIZE + entry.compressed_len(); | ||||
} | } | ||||
Self { | if offset == bytes.len() { | ||||
Ok(Self { | |||||
bytes, | bytes, | ||||
offsets: Some(offsets), | offsets: Some(offsets), | ||||
}) | |||||
} else { | |||||
Err(RevlogError::Corrupted) | |||||
} | } | ||||
} else { | } else { | ||||
Self { | Ok(Self { | ||||
bytes, | bytes, | ||||
offsets: None, | offsets: None, | ||||
} | }) | ||||
} | } | ||||
} | } | ||||
/// Value of the inline flag. | /// Value of the inline flag. | ||||
pub fn is_inline(&self) -> bool { | pub fn is_inline(&self) -> bool { | ||||
is_inline(&self.bytes) | is_inline(&self.bytes) | ||||
} | } | ||||
Is this comment still relevant?