rust/hg-cpython/src/revlog.rs
changeset 51975 609700e5d8df
parent 51967 69bfd6b242ed
child 51976 3e135e79b7f7
equal deleted inserted replaced
51974:5d1e6f447d2d 51975:609700e5d8df
    25     },
    25     },
    26     nodemap::{Block, NodeMapError, NodeTree as CoreNodeTree},
    26     nodemap::{Block, NodeMapError, NodeTree as CoreNodeTree},
    27     revlog::{nodemap::NodeMap, Graph, NodePrefix, RevlogError, RevlogIndex},
    27     revlog::{nodemap::NodeMap, Graph, NodePrefix, RevlogError, RevlogIndex},
    28     BaseRevision, Node, Revision, UncheckedRevision, NULL_REVISION,
    28     BaseRevision, Node, Revision, UncheckedRevision, NULL_REVISION,
    29 };
    29 };
    30 use std::{cell::RefCell, collections::HashMap};
    30 use std::{
       
    31     cell::RefCell,
       
    32     collections::{HashMap, HashSet},
       
    33 };
    31 use vcsgraph::graph::Graph as VCSGraph;
    34 use vcsgraph::graph::Graph as VCSGraph;
    32 
    35 
    33 pub struct PySharedIndex {
    36 pub struct PySharedIndex {
    34     /// The underlying hg-core index
    37     /// The underlying hg-core index
    35     pub(crate) inner: &'static hg::index::Index,
    38     pub(crate) inner: &'static hg::index::Index,
   303         Ok(rust_res)
   306         Ok(rust_res)
   304     }
   307     }
   305 
   308 
   306     /// get head revisions
   309     /// get head revisions
   307     def headrevs(&self, *args, **_kw) -> PyResult<PyObject> {
   310     def headrevs(&self, *args, **_kw) -> PyResult<PyObject> {
   308         let filtered_revs = match &args.len(py) {
   311         let (filtered_revs, stop_rev) = match &args.len(py) {
   309              0 => Ok(py.None()),
   312              0 => Ok((py.None(), py.None())),
   310              1 => Ok(args.get_item(py, 0)),
   313              1 => Ok((args.get_item(py, 0), py.None())),
       
   314              2 => Ok((args.get_item(py, 0), args.get_item(py, 1))),
   311              _ => Err(PyErr::new::<cpython::exc::TypeError, _>(py, "too many arguments")),
   315              _ => Err(PyErr::new::<cpython::exc::TypeError, _>(py, "too many arguments")),
   312         }?;
   316         }?;
   313         self.inner_headrevs(py, &filtered_revs)
   317         self.inner_headrevs(py, &filtered_revs, &stop_rev)
   314     }
   318     }
   315 
   319 
   316     /// get head nodeids
   320     /// get head nodeids
   317     def head_node_ids(&self) -> PyResult<PyObject> {
   321     def head_node_ids(&self) -> PyResult<PyObject> {
   318         let rust_res = self.inner_head_node_ids(py)?;
   322         let rust_res = self.inner_head_node_ids(py)?;
   819 
   823 
   820     fn inner_headrevs(
   824     fn inner_headrevs(
   821         &self,
   825         &self,
   822         py: Python,
   826         py: Python,
   823         filtered_revs: &PyObject,
   827         filtered_revs: &PyObject,
       
   828         stop_rev: &PyObject,
   824     ) -> PyResult<PyObject> {
   829     ) -> PyResult<PyObject> {
   825         let index = &*self.index(py).borrow();
   830         let index = &*self.index(py).borrow();
   826 
   831         let stop_rev = match stop_rev.is_none(py) {
   827         let from_core = match filtered_revs.is_none(py) {
       
   828             true => index.head_revs_shortcut(),
       
   829             false => {
   832             false => {
       
   833                 let rev = stop_rev.extract::<i32>(py)?;
       
   834                 if 0 <= rev && rev < index.len() as BaseRevision {
       
   835                     Some(Revision(rev))
       
   836                 } else {
       
   837                     None
       
   838                 }
       
   839             }
       
   840             true => None,
       
   841         };
       
   842         let from_core = match (filtered_revs.is_none(py), stop_rev.is_none()) {
       
   843             (true, true) => index.head_revs_shortcut(),
       
   844             (true, false) => {
       
   845                 index.head_revs_advanced(&HashSet::new(), stop_rev, false)
       
   846             }
       
   847             _ => {
   830                 let filtered_revs =
   848                 let filtered_revs =
   831                     rev_pyiter_collect(py, filtered_revs, index)?;
   849                     rev_pyiter_collect(py, filtered_revs, index)?;
   832                 index.head_revs_filtered(&filtered_revs, true)
   850                 index.head_revs_advanced(
       
   851                     &filtered_revs,
       
   852                     stop_rev,
       
   853                     stop_rev.is_none(),
       
   854                 )
   833             }
   855             }
   834         };
   856         };
   835 
   857 
   836         if let Some(new_heads) = from_core.map_err(|e| graph_error(py, e))? {
   858         if stop_rev.is_some() {
   837             self.cache_new_heads_py_list(&new_heads, py);
   859             // we don't cache result for now
   838         }
   860             let new_heads = from_core
   839 
   861                 .map_err(|e| graph_error(py, e))?
   840         Ok(self
   862                 .expect("this case should not be cached yet");
   841             .head_revs_py_list(py)
   863 
   842             .borrow()
   864             let as_vec: Vec<PyObject> = new_heads
   843             .as_ref()
   865                 .iter()
   844             .expect("head revs should be cached")
   866                 .map(|r| PyRevision::from(*r).into_py_object(py).into_object())
   845             .clone_ref(py)
   867                 .collect();
   846             .into_object())
   868             Ok(PyList::new(py, &as_vec).into_object())
       
   869         } else {
       
   870             if let Some(new_heads) =
       
   871                 from_core.map_err(|e| graph_error(py, e))?
       
   872             {
       
   873                 self.cache_new_heads_py_list(&new_heads, py);
       
   874             }
       
   875 
       
   876             Ok(self
       
   877                 .head_revs_py_list(py)
       
   878                 .borrow()
       
   879                 .as_ref()
       
   880                 .expect("head revs should be cached")
       
   881                 .clone_ref(py)
       
   882                 .into_object())
       
   883         }
   847     }
   884     }
   848 
   885 
   849     fn check_revision(
   886     fn check_revision(
   850         index: &hg::index::Index,
   887         index: &hg::index::Index,
   851         rev: UncheckedRevision,
   888         rev: UncheckedRevision,