Mercurial > hg
changeset 51195:f6403bcd9f96
rust-index: synchronize remove to Rust index
Future steps will bring the two indexes further together until we can
rip the C index entirely when running Rust code.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Wed, 28 Jun 2023 16:43:39 +0200 |
parents | f0fa98752d67 |
children | f95f70cf2ee2 |
files | rust/hg-core/src/revlog/index.rs rust/hg-cpython/src/revlog.rs |
diffstat | 2 files changed, 51 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/index.rs Wed Jun 28 11:59:43 2023 +0200 +++ b/rust/hg-core/src/revlog/index.rs Wed Jun 28 16:43:39 2023 +0200 @@ -79,6 +79,10 @@ struct IndexData { /// Immutable bytes, most likely taken from disk bytes: Box<dyn Deref<Target = [u8]> + Send>, + /// Used when stripping index contents, keeps track of the start of the + /// first stripped revision, which is used to give a slice of the + /// `bytes` field. + truncation: Option<usize>, /// Bytes that were added after reading the index added: Vec<u8>, } @@ -87,12 +91,36 @@ pub fn new(bytes: Box<dyn Deref<Target = [u8]> + Send>) -> Self { Self { bytes, + truncation: None, added: vec![], } } pub fn len(&self) -> usize { - self.bytes.len() + self.added.len() + match self.truncation { + Some(truncation) => truncation + self.added.len(), + None => self.bytes.len() + self.added.len(), + } + } + + fn remove( + &mut self, + rev: Revision, + offsets: Option<&[usize]>, + ) -> Result<(), RevlogError> { + let rev = rev.0 as usize; + let truncation = if let Some(offsets) = offsets { + offsets[rev] + } else { + rev * INDEX_ENTRY_SIZE + }; + if truncation < self.bytes.len() { + self.truncation = Some(truncation); + self.added.clear(); + } else { + self.added.truncate(truncation - self.bytes.len()); + } + Ok(()) } } @@ -102,7 +130,10 @@ fn index(&self, index: std::ops::Range<usize>) -> &Self::Output { let start = index.start; let end = index.end; - let immutable_len = self.bytes.len(); + let immutable_len = match self.truncation { + Some(truncation) => truncation, + None => self.bytes.len(), + }; if start < immutable_len { if end > immutable_len { panic!("index data cannot span existing and added ranges"); @@ -368,6 +399,14 @@ self.bytes.added.extend(revision_data.into_v1().as_bytes()); Ok(()) } + + pub fn remove(&mut self, rev: Revision) -> Result<(), RevlogError> { + self.bytes.remove(rev, self.offsets.as_deref())?; + if let Some(offsets) = self.offsets.as_mut() { + offsets.truncate(rev.0 as usize) + } + Ok(()) + } } impl super::RevlogIndex for Index {
--- a/rust/hg-cpython/src/revlog.rs Wed Jun 28 11:59:43 2023 +0200 +++ b/rust/hg-cpython/src/revlog.rs Wed Jun 28 16:43:39 2023 +0200 @@ -160,7 +160,16 @@ def __delitem__(&self, key: PyObject) -> PyResult<()> { // __delitem__ is both for `del idx[r]` and `del idx[r1:r2]` - self.cindex(py).borrow().inner().del_item(py, key)?; + self.cindex(py).borrow().inner().del_item(py, &key)?; + let start = key.getattr(py, "start")?; + let start = UncheckedRevision(start.extract(py)?); + let start = self.index(py) + .borrow() + .check_revision(start) + .ok_or_else(|| { + nodemap_error(py, NodeMapError::RevisionNotInIndex(start)) + })?; + self.index(py).borrow_mut().remove(start).unwrap(); let mut opt = self.get_nodetree(py)?.borrow_mut(); let nt = opt.as_mut().unwrap(); nt.invalidate_all();