changeset 44259:220d4d2e3185

rust-nodemap: abstracting the indexing In the forthcoming mutable implementation, we'll have to visit node trees that are more complex than a single slice, although the algorithm will still be expressed in simple indexing terms. We still refrain using `#[inline]` indications as being premature optimizations, but we strongly hope the compiler will indeed inline most of the glue. Differential Revision: https://phab.mercurial-scm.org/D7792
author Georges Racinet <georges.racinet@octobus.net>
date Thu, 26 Dec 2019 15:47:14 +0100
parents e52401a95b94
children a19331456d48
files rust/hg-core/src/revlog/nodemap.rs
diffstat 1 files changed, 20 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/rust/hg-core/src/revlog/nodemap.rs	Thu Jan 23 17:18:13 2020 +0100
+++ b/rust/hg-core/src/revlog/nodemap.rs	Thu Dec 26 15:47:14 2019 +0100
@@ -17,6 +17,7 @@
 };
 use std::fmt;
 use std::ops::Deref;
+use std::ops::Index;
 
 #[derive(Debug, PartialEq)]
 pub enum NodeMapError {
@@ -195,6 +196,14 @@
     readonly: Box<dyn Deref<Target = [Block]> + Send>,
 }
 
+impl Index<usize> for NodeTree {
+    type Output = Block;
+
+    fn index(&self, i: usize) -> &Block {
+        &self.readonly[i]
+    }
+}
+
 /// Return `None` unless the `Node` for `rev` has given prefix in `index`.
 fn has_prefix_or_none<'p>(
     idx: &impl RevlogIndex,
@@ -213,6 +222,14 @@
 }
 
 impl NodeTree {
+    fn len(&self) -> usize {
+        self.readonly.len()
+    }
+
+    fn is_empty(&self) -> bool {
+        self.len() == 0
+    }
+
     /// Main working method for `NodeTree` searches
     ///
     /// This partial implementation lacks special cases for NULL_REVISION
@@ -220,14 +237,13 @@
         &self,
         prefix: NodePrefixRef<'p>,
     ) -> Result<Option<Revision>, NodeMapError> {
-        let blocks: &[Block] = &*self.readonly;
-        if blocks.is_empty() {
+        if self.is_empty() {
             return Ok(None);
         }
-        let mut visit = blocks.len() - 1;
+        let mut visit = self.len() - 1;
         for i in 0..prefix.len() {
             let nybble = prefix.get_nybble(i);
-            match blocks[visit].get(nybble) {
+            match self[visit].get(nybble) {
                 Element::None => return Ok(None),
                 Element::Rev(r) => return Ok(Some(r)),
                 Element::Block(idx) => visit = idx,