| @@ -15,6 +15,8 @@ mod error { · 14 unmodified lines |
| 15 | 15 | pub enum Error { |
| 16 | 16 | #[error("An error occurred while obtaining an object from the loose object store")] |
| 17 | 17 | Loose(#[from] loose::find::Error), |
| 18 | + #[error("An error occurred looking up a prefix which requires iteration")] |
| 19 | + LooseWalkDir(#[from] loose::iter::Error), |
| 18 | 20 | #[error("An error occurred while obtaining an object from the packed object store")] |
| 19 | 21 | Pack(#[from] pack::data::decode_entry::Error), |
| 20 | 22 | #[error(transparent)] |
| @@ -32,8 +34,44 @@ where · 11 unmodified lines |
| 32 | 34 | S: Deref<Target = super::Store> + Clone, |
| 33 | 35 | { |
| 34 | 36 | #[allow(missing_docs)] // TODO: docs |
| 35 | | − pub fn lookup_prefix(&self, _prefix: git_hash::Prefix) -> Result<Option<crate::find::PrefixLookupResult>, Error> { |
| 36 | | − todo!() |
| 37 | + pub fn lookup_prefix(&self, prefix: git_hash::Prefix) -> Result<Option<crate::find::PrefixLookupResult>, Error> { |
| 38 | + let mut candidate: Option<git_hash::ObjectId> = None; |
| 39 | + loop { |
| 40 | + let snapshot = self.snapshot.borrow(); |
| 41 | + { |
| 42 | + for index in snapshot.indices.iter() { |
| 43 | + match (index.lookup_prefix(prefix), candidate) { |
| 44 | + (Some(Ok(oid)), Some(candidate)) if candidate != oid => return Ok(Some(Err(()))), |
| 45 | + (Some(Ok(_)), Some(_)) | (None, None) | (None, Some(_)) => continue, |
| 46 | + (Some(Err(())), _) => return Ok(Some(Err(()))), |
| 47 | + (Some(Ok(oid)), None) => { |
| 48 | + candidate = Some(oid); |
| 49 | + continue; |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + for lodb in snapshot.loose_dbs.iter() { |
| 56 | + match (lodb.lookup_prefix(prefix)?, candidate) { |
| 57 | + (Some(Ok(oid)), Some(candidate)) if candidate != oid => return Ok(Some(Err(()))), |
| 58 | + (Some(Ok(_)), Some(_)) | (None, None) | (None, Some(_)) => continue, |
| 59 | + (Some(Err(())), _) => return Ok(Some(Err(()))), |
| 60 | + (Some(Ok(oid)), None) => { |
| 61 | + candidate = Some(oid); |
| 62 | + continue; |
| 63 | + } |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + match self.store.load_one_index(self.refresh_mode, snapshot.marker)? { |
| 68 | + Some(new_snapshot) => { |
| 69 | + drop(snapshot); |
| 70 | + *self.snapshot.borrow_mut() = new_snapshot; |
| 71 | + } |
| 72 | + None => return Ok(candidate.map(Ok)), |
| 73 | + } |
| 74 | + } |
| 37 | 75 | } |
| 38 | 76 | } |
| 39 | 77 | |
| @@ -46,8 +84,8 @@ where · 6 unmodified lines |
| 46 | 84 | // TODO: probably make this method fallible, but that would mean its own error type. |
| 47 | 85 | fn contains(&self, id: impl AsRef<oid>) -> bool { |
| 48 | 86 | let id = id.as_ref(); |
| 87 | + let mut snapshot = self.snapshot.borrow_mut(); |
| 49 | 88 | loop { |
| 50 | | − let mut snapshot = self.snapshot.borrow_mut(); |
| 51 | 89 | { |
| 52 | 90 | for (idx, index) in snapshot.indices.iter().enumerate() { |
| 53 | 91 | if index.contains(id) { |
| @@ -67,8 +105,7 @@ where · 13 unmodified lines |
| 67 | 105 | |
| 68 | 106 | match self.store.load_one_index(self.refresh_mode, snapshot.marker) { |
| 69 | 107 | Ok(Some(new_snapshot)) => { |
| 70 | | − drop(snapshot); |
| 71 | | − *self.snapshot.borrow_mut() = new_snapshot; |
| 108 | + *snapshot = new_snapshot; |
| 72 | 109 | } |
| 73 | 110 | Ok(None) => return false, // nothing more to load, or our refresh mode doesn't allow disk refreshes |
| 74 | 111 | Err(_) => return false, // something went wrong, nothing we can communicate here with this trait. TODO: Maybe that should change? |
| @@ -83,8 +120,8 @@ where · 8 unmodified lines |
| 83 | 120 | pack_cache: &mut impl DecodeEntry, |
| 84 | 121 | ) -> Result<Option<(Data<'a>, Option<Location>)>, Self::Error> { |
| 85 | 122 | let id = id.as_ref(); |
| 123 | + let mut snapshot = self.snapshot.borrow_mut(); |
| 86 | 124 | 'outer: loop { |
| 87 | | − let mut snapshot = self.snapshot.borrow_mut(); |
| 88 | 125 | { |
| 89 | 126 | let marker = snapshot.marker; |
| 90 | 127 | for (idx, index) in snapshot.indices.iter_mut().enumerate() { |
| @@ -105,8 +142,7 @@ where · 14 unmodified lines |
| 105 | 142 | // The pack wasn't available anymore so we are supposed to try another round with a fresh index |
| 106 | 143 | match self.store.load_one_index(self.refresh_mode, snapshot.marker)? { |
| 107 | 144 | Some(new_snapshot) => { |
| 108 | | − drop(snapshot); |
| 109 | | − *self.snapshot.borrow_mut() = new_snapshot; |
| 145 | + *snapshot = new_snapshot; |
| 110 | 146 | continue 'outer; |
| 111 | 147 | } |
| 112 | 148 | None => { |
| @@ -166,8 +202,7 @@ where · 53 unmodified lines |
| 166 | 202 | |
| 167 | 203 | match self.store.load_one_index(self.refresh_mode, snapshot.marker)? { |
| 168 | 204 | Some(new_snapshot) => { |
| 169 | | − drop(snapshot); |
| 170 | | − *self.snapshot.borrow_mut() = new_snapshot; |
| 205 | + *snapshot = new_snapshot; |
| 171 | 206 | } |
| 172 | 207 | None => return Ok(None), |
| 173 | 208 | } |
| @@ -180,8 +215,8 @@ where · 6 unmodified lines |
| 180 | 215 | "BUG: handle must be configured to `prevent_pack_unload()` before using this method" |
| 181 | 216 | ); |
| 182 | 217 | let id = id.as_ref(); |
| 218 | + let mut snapshot = self.snapshot.borrow_mut(); |
| 183 | 219 | 'outer: loop { |
| 184 | | − let mut snapshot = self.snapshot.borrow_mut(); |
| 185 | 220 | { |
| 186 | 221 | let marker = snapshot.marker; |
| 187 | 222 | for (idx, index) in snapshot.indices.iter_mut().enumerate() { |
| @@ -202,8 +237,7 @@ where · 14 unmodified lines |
| 202 | 237 | // The pack wasn't available anymore so we are supposed to try another round with a fresh index |
| 203 | 238 | match self.store.load_one_index(self.refresh_mode, snapshot.marker).ok()? { |
| 204 | 239 | Some(new_snapshot) => { |
| 205 | | − drop(snapshot); |
| 206 | | − *self.snapshot.borrow_mut() = new_snapshot; |
| 240 | + *snapshot = new_snapshot; |
| 207 | 241 | continue 'outer; |
| 208 | 242 | } |
| 209 | 243 | None => { |
| @@ -239,8 +273,7 @@ where · 29 unmodified lines |
| 239 | 273 | |
| 240 | 274 | match self.store.load_one_index(self.refresh_mode, snapshot.marker).ok()? { |
| 241 | 275 | Some(new_snapshot) => { |
| 242 | | − drop(snapshot); |
| 243 | | − *self.snapshot.borrow_mut() = new_snapshot; |
| 276 | + *snapshot = new_snapshot; |
| 244 | 277 | } |
| 245 | 278 | None => return None, |
| 246 | 279 | } |
| @@ -279,9 +312,9 @@ where · 32 unmodified lines |
| 279 | 312 | "BUG: handle must be configured to `prevent_pack_unload()` before using this method" |
| 280 | 313 | ); |
| 281 | 314 | let pack_id = PackId::from_intrinsic_pack_id(location.pack_id); |
| 315 | + let mut snapshot = self.snapshot.borrow_mut(); |
| 316 | + let marker = snapshot.marker; |
| 282 | 317 | loop { |
| 283 | | − let mut snapshot = self.snapshot.borrow_mut(); |
| 284 | | − let marker = snapshot.marker; |
| 285 | 318 | { |
| 286 | 319 | for index in snapshot.indices.iter_mut() { |
| 287 | 320 | if let Some(possibly_pack) = index.pack(pack_id) { |
| @@ -289,7 +322,7 @@ where · 1 unmodified line |
| 289 | 322 | Some(pack) => pack, |
| 290 | 323 | None => { |
| 291 | 324 | let pack = self.store.load_pack(pack_id, marker).ok()?.expect( |
| 292 | | − "BUG: pack must exist from previous call to locaion_by_oid() and must not be unloaded", |
| 325 | + "BUG: pack must exist from previous call to location_by_oid() and must not be unloaded", |
| 293 | 326 | ); |
| 294 | 327 | *possibly_pack = Some(pack); |
| 295 | 328 | possibly_pack.as_deref().expect("just put it in") |