changeset 52180:1032bb0ef365

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.
author Raphaël Gomès <rgomes@octobus.net>
date Wed, 31 Jul 2024 15:41:08 +0200
parents c90e0f65896e
children 3d797007905d
files rust/hg-cpython/src/revlog.rs
diffstat 1 files changed, 9 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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<Option<PyList>>;
     data revision_cache: RefCell<Option<PyObject>>;
     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),
         )
     }
 }