Mercurial > hg-stable
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,