# HG changeset patch # User Raphaël Gomès # Date 1722433268 -7200 # Node ID 1032bb0ef3658e2be02114c73425fb2d756ccce7 # Parent c90e0f65896e8429f1a5182b2cb4e4f7f6745dfd rust-revlog: build an in-memory nodemap if a given revlog gets queried a lot This will help with non-persistent nodemap repos that would benefit from one, and mirrors what the C implementation does. diff -r c90e0f65896e -r 1032bb0ef365 rust/hg-cpython/src/revlog.rs --- a/rust/hg-cpython/src/revlog.rs Wed Jul 31 15:11:27 2024 +0200 +++ b/rust/hg-cpython/src/revlog.rs Wed Jul 31 15:41:08 2024 +0200 @@ -43,7 +43,7 @@ use std::{ cell::{Cell, RefCell}, collections::{HashMap, HashSet}, - sync::atomic::{AtomicBool, Ordering}, + sync::atomic::{AtomicBool, AtomicUsize, Ordering}, sync::OnceLock, }; use vcsgraph::graph::Graph as VCSGraph; @@ -723,6 +723,7 @@ data head_node_ids_py_list: RefCell>; data revision_cache: RefCell>; data use_persistent_nodemap: bool; + data nodemap_queries: AtomicUsize; def __new__( _cls, @@ -766,6 +767,7 @@ assert!(!self.is_delaying(py)?); self.revision_cache(py).borrow_mut().take(); self.inner(py).borrow_mut().clear_cache(); + self.nodemap_queries(py).store(0, Ordering::Relaxed); Ok(py.None()) } @@ -1115,10 +1117,11 @@ // brute force lookup from the end backwards. If there is a very large // filelog (automation file that changes every commit etc.), it also // seems to work quite well for all measured purposes so far. - // - // TODO build an in-memory nodemap if more than 4 queries to the same - // revlog are made? - if !*self.use_persistent_nodemap(py) { + let mut nodemap_queries = + self.nodemap_queries(py).fetch_add(1, Ordering::Relaxed); + // Still need to add since `fetch_add` returns the old value + nodemap_queries += 1; + if !*self.use_persistent_nodemap(py) && nodemap_queries <= 4 { let idx = &self.inner(py).borrow().index; let res = idx.rev_from_node_no_persistent_nodemap(node.into()).ok(); @@ -2025,6 +2028,7 @@ RefCell::new(None), RefCell::new(None), use_persistent_nodemap, + AtomicUsize::new(0), ) } }