From 903f18acfd2365d4488eeea3425ab18615e23aa1 Mon Sep 17 00:00:00 2001
From: Yuya Nishihara <yuya@tcha.org>
Date: Mon, 12 Feb 2024 11:39:55 +0900
Subject: [PATCH] index: extract helper functions for id lookup in mutable
 table

Similar to the previous commit, these functions will be reused by the change id
lookup methods. The return value isn't cloned because resolve_id_prefix() will
return (key, value) pair, and the current caller doesn't need a cloned value.
---
 lib/src/default_index/mutable.rs | 57 ++++++++++++++++++++------------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/lib/src/default_index/mutable.rs b/lib/src/default_index/mutable.rs
index 26847fde5..d5e6a7987 100644
--- a/lib/src/default_index/mutable.rs
+++ b/lib/src/default_index/mutable.rs
@@ -334,32 +334,13 @@ impl IndexSegment for MutableIndexSegment {
         &self,
         commit_id: &CommitId,
     ) -> (Option<CommitId>, Option<CommitId>) {
-        let prev_id = self
-            .commit_lookup
-            .range((Bound::Unbounded, Bound::Excluded(commit_id)))
-            .next_back()
-            .map(|(id, _)| id.clone());
-        let next_id = self
-            .commit_lookup
-            .range((Bound::Excluded(commit_id), Bound::Unbounded))
-            .next()
-            .map(|(id, _)| id.clone());
-        (prev_id, next_id)
+        let (prev_id, next_id) = resolve_neighbor_ids(&self.commit_lookup, commit_id);
+        (prev_id.cloned(), next_id.cloned())
     }
 
     fn resolve_commit_id_prefix(&self, prefix: &HexPrefix) -> PrefixResolution<CommitId> {
         let min_bytes_prefix = CommitId::from_bytes(prefix.min_prefix_bytes());
-        let mut matches = self
-            .commit_lookup
-            .range((Bound::Included(&min_bytes_prefix), Bound::Unbounded))
-            .map(|(id, _pos)| id)
-            .take_while(|&id| prefix.matches(id))
-            .fuse();
-        match (matches.next(), matches.next()) {
-            (Some(id), None) => PrefixResolution::SingleMatch(id.clone()),
-            (Some(_), Some(_)) => PrefixResolution::AmbiguousMatch,
-            (None, _) => PrefixResolution::NoMatch,
-        }
+        resolve_id_prefix(&self.commit_lookup, prefix, &min_bytes_prefix).map(|id| id.clone())
     }
 
     fn generation_number(&self, local_pos: LocalPosition) -> u32 {
@@ -499,3 +480,35 @@ impl MutableIndex for DefaultMutableIndex {
         self.0.merge_in(other.as_segment().clone());
     }
 }
+
+fn resolve_neighbor_ids<'a, K: Ord, V>(
+    lookup_table: &'a BTreeMap<K, V>,
+    id: &K,
+) -> (Option<&'a K>, Option<&'a K>) {
+    let prev_id = lookup_table
+        .range((Bound::Unbounded, Bound::Excluded(id)))
+        .next_back()
+        .map(|(id, _)| id);
+    let next_id = lookup_table
+        .range((Bound::Excluded(id), Bound::Unbounded))
+        .next()
+        .map(|(id, _)| id);
+    (prev_id, next_id)
+}
+
+fn resolve_id_prefix<'a, K: ObjectId + Ord, V>(
+    lookup_table: &'a BTreeMap<K, V>,
+    prefix: &HexPrefix,
+    min_bytes_prefix: &K,
+) -> PrefixResolution<&'a K> {
+    let mut matches = lookup_table
+        .range((Bound::Included(min_bytes_prefix), Bound::Unbounded))
+        .map(|(id, _pos)| id)
+        .take_while(|&id| prefix.matches(id))
+        .fuse();
+    match (matches.next(), matches.next()) {
+        (Some(id), None) => PrefixResolution::SingleMatch(id),
+        (Some(_), Some(_)) => PrefixResolution::AmbiguousMatch,
+        (None, _) => PrefixResolution::NoMatch,
+    }
+}