Skip to content

Commit

Permalink
fix: linked::Store now assures unique IDs across compound stores (#260)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Dec 1, 2021
1 parent b54a985 commit 19e974a
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 8 deletions.
6 changes: 4 additions & 2 deletions git-odb/src/store/compound/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ impl compound::Store {
///
/// Only loose and packed objects will be considered. See the [linked Db][crate::store::linked::Store] for a database with
/// support for _git alternates_, i.e. linking to other repositories.
pub fn at(objects_directory: impl Into<PathBuf>) -> Result<compound::Store, Error> {
///
/// `pack_id_offset` is used to allow multiple compound databases to be used for lookups without their pack-ids clashing.
pub fn at(objects_directory: impl Into<PathBuf>, pack_id_offset: u32) -> Result<compound::Store, Error> {
let loose_objects = objects_directory.into();
if !loose_objects.is_dir() {
return Err(Error::Inaccessible(loose_objects));
Expand All @@ -44,7 +46,7 @@ impl compound::Store {
(
{
// don't rely on crc32 for producing non-clashing ids. It's the kind of bug we don't want
b.pack.id = idx as u32;
b.pack.id = idx as u32 + pack_id_offset;
b
},
mod_time,
Expand Down
10 changes: 8 additions & 2 deletions git-odb/src/store/linked/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ impl linked::Store {
///
/// _git alternate_ files will be traversed to build a chain of [`compound::Store`] instances.
pub fn at(objects_directory: impl Into<PathBuf>) -> Result<Self, Error> {
let mut dbs = vec![compound::Store::at(objects_directory.into())?];
let mut dbs = vec![compound::Store::at(objects_directory.into(), 0)?];

let compute_ofs = |db: &compound::Store| db.bundles.iter().map(|p| p.pack.id).max().map(|ofs| ofs + 1);
let mut ofs = compute_ofs(&dbs[0]).unwrap_or(0);

for object_path in alternate::resolve(dbs[0].loose.path.clone())?.into_iter() {
dbs.push(compound::Store::at(object_path)?);
let store = compound::Store::at(object_path, ofs)?;
ofs = compute_ofs(&store).unwrap_or(ofs);
dbs.push(store);
}
assert!(
!dbs.is_empty(),
Expand Down
2 changes: 1 addition & 1 deletion git-odb/tests/odb/store/compound/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use git_odb::compound::Store;
use crate::fixture_path;

fn db() -> Store {
Store::at(fixture_path("objects")).expect("valid object path")
Store::at(fixture_path("objects"), 0).expect("valid object path")
}

mod init {
Expand Down
5 changes: 2 additions & 3 deletions git-pack/src/data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@ pub struct File {
path: std::path::PathBuf,
/// A hash to represent the `path` field when used with cache lookup, or a way to identify this pack by its location on disk.
///
/// Note that `path` might not be canonicalized, thus different hashes might actually refer to the same pack on disk. This will
/// only lead to less efficient cache usage.
/// TODO: remove this intrinsic id as it will henceforth be handled separately by the object store
/// These must be unique per pack and must be stable, that is they don't change if the pack doesn't change.
/// If the same id is assigned (or reassigned) to different packs, pack creation or cache access will fail in hard-to-debug ways.
pub id: u32,
version: Version,
num_objects: u32,
Expand Down

0 comments on commit 19e974a

Please sign in to comment.