From 7ada2196e13a97003dfb9fee50b9dbde68c14fce Mon Sep 17 00:00:00 2001 From: Yuya Nishihara Date: Mon, 19 Jun 2023 18:47:55 +0900 Subject: [PATCH] id_prefix: store (CommitId, ChangeId) pairs separately in disambiguation index I'm going to rewrite IdIndex to store only first few bytes of the key. A separate table helps there. At this point, it wouldn't make sense to convert usize to u32, but the new index will store ([u8; 4], u32) pairs. --- lib/src/id_prefix.rs | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/lib/src/id_prefix.rs b/lib/src/id_prefix.rs index c9959426c..0c53f9c6f 100644 --- a/lib/src/id_prefix.rs +++ b/lib/src/id_prefix.rs @@ -14,6 +14,7 @@ use std::rc::Rc; +use itertools::Itertools as _; use once_cell::unsync::OnceCell; use crate::backend::{self, ChangeId, CommitId, ObjectId}; @@ -31,8 +32,9 @@ struct DisambiguationData { } struct Indexes { - commit_index: IdIndex, - change_index: IdIndex, + commit_change_ids: Vec<(CommitId, ChangeId)>, + commit_index: IdIndex, + change_index: IdIndex, } impl DisambiguationData { @@ -48,13 +50,16 @@ impl DisambiguationData { .evaluate(repo) .map_err(|_| PrefixDisambiguationError)?; - let mut commit_index = IdIndex::builder(); - let mut change_index = IdIndex::builder(); - for (commit_id, change_id) in revset.commit_change_ids() { - commit_index.insert(commit_id.clone(), ()); - change_index.insert(change_id, commit_id); + let commit_change_ids = revset.commit_change_ids().collect_vec(); + let mut commit_index = IdIndex::with_capacity(commit_change_ids.len()); + let mut change_index = IdIndex::with_capacity(commit_change_ids.len()); + for (i, (commit_id, change_id)) in commit_change_ids.iter().enumerate() { + let i: u32 = i.try_into().unwrap(); + commit_index.insert(commit_id.clone(), i); + change_index.insert(change_id.clone(), i); } Ok(Indexes { + commit_change_ids, commit_index: commit_index.build(), change_index: change_index.build(), }) @@ -121,8 +126,10 @@ impl IdPrefixContext { prefix: &HexPrefix, ) -> PrefixResolution> { if let Some(indexes) = self.disambiguation_indexes(repo) { - let resolution = indexes.change_index.resolve_prefix_to_values(prefix); - if let PrefixResolution::SingleMatch(ids) = resolution { + let resolution = indexes + .change_index + .resolve_prefix_with(prefix, |&i| indexes.commit_change_ids[i as usize].0.clone()); + if let PrefixResolution::SingleMatch((_, ids)) = resolution { return PrefixResolution::SingleMatch(ids); } } @@ -216,16 +223,6 @@ where .map(|(key, ())| key) } - /// Looks up entries with the given prefix, and collects values if matched - /// entries have unambiguous keys. - pub fn resolve_prefix_to_values(&self, prefix: &HexPrefix) -> PrefixResolution> - where - V: Clone, - { - self.resolve_prefix_with(prefix, |v: &V| v.clone()) - .map(|(_, values)| values) - } - /// Iterates over entries with the given prefix. pub fn resolve_prefix_range<'a: 'b, 'b>( &'a self,