(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?