Skip to content

Commit

Permalink
feat: Handle::packed_object_count() (#298)
Browse files Browse the repository at this point in the history
Provide packed objects numbers and cache the value
for fast access later on.
  • Loading branch information
Byron committed Apr 5, 2022
1 parent aee55c0 commit 84ec54e
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
28 changes: 28 additions & 0 deletions git-odb/src/store_impls/dynamic/find.rs
Expand Up @@ -96,6 +96,25 @@ impl<S> super::Handle<S>
where
S: Deref<Target = super::Store> + Clone,
{
/// Return the exact number of packed objects after loading all currently available indices
/// as last seen on disk.
pub fn packed_object_count(&self) -> Result<u64, Error> {
let mut count = self.packed_object_count.borrow_mut();
match *count {
Some(count) => Ok(count),
None => {
let mut snapshot = self.snapshot.borrow_mut();
*snapshot = self.store.load_all_indices()?;
let mut obj_count = 0;
for index in &snapshot.indices {
obj_count += index.num_objects() as u64;
}
*count = Some(obj_count);
Ok(obj_count)
}
}
}

/// Given a prefix `candidate` with an object id and an initial `hex_len`, check if it only matches a single
/// object within the entire object database and increment its `hex_len` by one until it is unambiguous.
pub fn disambiguate_prefix(&self, mut candidate: PotentialPrefix) -> Result<Option<git_hash::Prefix>, Error> {
Expand Down Expand Up @@ -215,6 +234,7 @@ where
match self.store.load_one_index(self.refresh, snapshot.marker)? {
Some(new_snapshot) => {
*snapshot = new_snapshot;
self.clear_cache();
continue 'outer;
}
None => {
Expand Down Expand Up @@ -359,11 +379,16 @@ where
match self.store.load_one_index(self.refresh, snapshot.marker)? {
Some(new_snapshot) => {
*snapshot = new_snapshot;
self.clear_cache();
}
None => return Ok(None),
}
}
}

fn clear_cache(&self) {
self.packed_object_count.borrow_mut().take();
}
}

impl<S> git_pack::Find for super::Handle<S>
Expand Down Expand Up @@ -395,6 +420,7 @@ where
match self.store.load_one_index(self.refresh, snapshot.marker) {
Ok(Some(new_snapshot)) => {
*snapshot = new_snapshot;
self.clear_cache();
}
Ok(None) => return false, // nothing more to load, or our refresh mode doesn't allow disk refreshes
Err(_) => return false, // something went wrong, nothing we can communicate here with this trait. TODO: Maybe that should change?
Expand Down Expand Up @@ -445,6 +471,7 @@ where
match self.store.load_one_index(self.refresh, snapshot.marker).ok()? {
Some(new_snapshot) => {
*snapshot = new_snapshot;
self.clear_cache();
continue 'outer;
}
None => {
Expand Down Expand Up @@ -481,6 +508,7 @@ where
match self.store.load_one_index(self.refresh, snapshot.marker).ok()? {
Some(new_snapshot) => {
*snapshot = new_snapshot;
self.clear_cache();
}
None => return None,
}
Expand Down
3 changes: 3 additions & 0 deletions git-odb/src/store_impls/dynamic/handle.rs
Expand Up @@ -250,6 +250,7 @@ impl super::Store {
token: Some(token),
snapshot: RefCell::new(self.collect_snapshot()),
max_recursion_depth: Self::INITIAL_MAX_RECURSION_DEPTH,
packed_object_count: Default::default(),
}
}

Expand All @@ -265,6 +266,7 @@ impl super::Store {
token: Some(token),
snapshot: RefCell::new(self.collect_snapshot()),
max_recursion_depth: Self::INITIAL_MAX_RECURSION_DEPTH,
packed_object_count: Default::default(),
}
}

Expand Down Expand Up @@ -381,6 +383,7 @@ where
},
snapshot: RefCell::new(self.store.collect_snapshot()),
max_recursion_depth: self.max_recursion_depth,
packed_object_count: Default::default(),
}
}
}
1 change: 1 addition & 0 deletions git-odb/src/store_impls/dynamic/mod.rs
Expand Up @@ -24,6 +24,7 @@ where

pub(crate) token: Option<handle::Mode>,
snapshot: RefCell<load_index::Snapshot>,
packed_object_count: RefCell<Option<u64>>,
}

/// Decide what happens when all indices are loaded.
Expand Down
8 changes: 8 additions & 0 deletions git-odb/tests/odb/store/dynamic.rs
Expand Up @@ -463,6 +463,14 @@ fn assert_all_indices_loaded(handle: &git_odb::Handle, num_refreshes: usize, ope
);
}

#[test]
fn packed_object_count_causes_all_indices_to_be_loaded() {
let (handle, _tmp) = db_with_all_object_sources().unwrap();

assert_eq!(handle.packed_object_count().unwrap(), 139);
assert_all_indices_loaded(&handle, 1, 2);
}

mod disambiguate_prefix {
use std::cmp::Ordering;

Expand Down

0 comments on commit 84ec54e

Please sign in to comment.