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.
--- 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();