Skip to content

Commit 38e36a6

Browse files
committed
improve pack staleness handling (#259)
Since packs can only be loaded after loading indices, one will have a marker that has to be used to check for changes that can't be reconciled. Note that this is not to protect from querying packs that aren't available on disk anymore as we will never unload them anyway when in a mode that needs pack-ids to remain stable.
1 parent a14e4d0 commit 38e36a6

File tree

1 file changed

+11
-13
lines changed
  • experiments/odb-redesign/src

1 file changed

+11
-13
lines changed

experiments/odb-redesign/src/lib.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ mod odb {
163163
Unloaded,
164164
Loaded(T),
165165
/// The file was loaded, but appeared to be missing on disk after reconciling our state with what's on disk.
166-
/// As there were handles that required pack-id stability we had to keep the pack.
166+
/// As there were handles that required pack-id stability we had to keep the item to allow finding it on later
167+
/// lookups.
167168
Garbage(T),
168169
/// File is missing on disk and could not be loaded when we tried or turned missing after reconciling our state.
169170
Missing,
@@ -322,16 +323,12 @@ mod odb {
322323
});
323324
load_indices::Outcome::Replace {
324325
indices: todo!(),
325-
mark: PackIndexMarker {
326-
generation: self.generation,
327-
pack_index_sequence: self.files.len(),
328-
},
326+
mark: self.marker(),
329327
}
330328
}
331329
}
332330

333331
/// A way to indicate which pack indices we have seen already
334-
#[derive(Copy, Clone)]
335332
pub struct PackIndexMarker {
336333
/// The generation the `pack_index_sequence` belongs to. Indices of different generations are completely incompatible.
337334
pub(crate) generation: u8,
@@ -459,19 +456,21 @@ mod odb {
459456
/// If the oid is known, just load indices again to continue
460457
/// (objects rarely ever removed so should be present, maybe in another pack though),
461458
/// and redo the entire lookup for a valid pack id whose pack can probably be loaded next time.
462-
/// The caller has to check the generation of the returned pack and compare it with their last generation,
463-
/// reloading the indices and retrying if it doesn't match.
464459
pub(crate) fn load_pack(
465460
&self,
466461
id: policy::PackId,
467-
) -> std::io::Result<Option<(PackIndexMarker, features::OwnShared<git_pack::data::File>)>> {
462+
marker: PackIndexMarker,
463+
) -> std::io::Result<Option<features::OwnShared<git_pack::data::File>>> {
464+
let state = get_ref_upgradeable(&self.state);
465+
if state.generation != marker.generation {
466+
return Ok(None);
467+
}
468468
match id.multipack_index {
469469
None => {
470-
let state = get_ref_upgradeable(&self.state);
471470
match state.files.get(id.index) {
472471
Some(f) => match f {
473472
policy::IndexAndPacks::Index(bundle) => match bundle.data.loaded() {
474-
Some(pack) => Ok(Some((state.marker(), pack.clone()))),
473+
Some(pack) => Ok(Some(pack.clone())),
475474
None => {
476475
let mut state = upgrade_ref_to_mut(state);
477476
let f = &mut state.files[id.index];
@@ -488,8 +487,7 @@ mod odb {
488487
},
489488
)
490489
})?
491-
.cloned()
492-
.map(|f| (state.marker(), f))),
490+
.cloned()),
493491
_ => unreachable!(),
494492
}
495493
}

0 commit comments

Comments
 (0)