| @@ -6,6 +6,7 @@ use std::{ · 5 unmodified lines |
| 6 | }; | 6 | }; |
| 7 | | 7 | |
| 8 | use git_features::threading::OwnShared; | 8 | use git_features::threading::OwnShared; |
| | 9 | use git_hash::oid; |
| 9 | | 10 | |
| 10 | use crate::store::{handle, types, RefreshMode}; | 11 | use crate::store::{handle, types, RefreshMode}; |
| 11 | | 12 | |
| @@ -25,7 +26,33 @@ pub enum SingleOrMultiIndex { · 13 unmodified lines |
| 25 | }, | 26 | }, |
| 26 | } | 27 | } |
| 27 | | 28 | |
| 28 | // pub enum SingleOrMultiIndexRef<'a> {} | 29 | /// A utility to allow looking up pack offsets for a particular pack |
| | 30 | pub enum IntraPackLookup<'a> { |
| | 31 | Single(&'a git_pack::index::File), |
| | 32 | /// the internal pack-id inside of a multi-index for which the lookup is supposed to be. |
| | 33 | /// Used to prevent ref-delta OIDs to, for some reason, point to a different pack. |
| | 34 | Multi { |
| | 35 | index: &'a git_pack::multi_index::File, |
| | 36 | required_pack_index: git_pack::multi_index::PackIndex, |
| | 37 | }, |
| | 38 | } |
| | 39 | |
| | 40 | impl<'a> IntraPackLookup<'a> { |
| | 41 | pub(crate) fn pack_offset_by_id(&self, id: &oid) -> Option<git_pack::data::Offset> { |
| | 42 | match self { |
| | 43 | IntraPackLookup::Single(index) => index |
| | 44 | .lookup(id) |
| | 45 | .map(|entry_index| index.pack_offset_at_index(entry_index)), |
| | 46 | IntraPackLookup::Multi { |
| | 47 | index, |
| | 48 | required_pack_index, |
| | 49 | } => index.lookup(id).and_then(|entry_index| { |
| | 50 | let (pack_index, pack_offset) = index.pack_id_and_pack_offset_at_index(entry_index); |
| | 51 | (pack_index == *required_pack_index).then(|| pack_offset) |
| | 52 | }), |
| | 53 | } |
| | 54 | } |
| | 55 | } |
| 29 | | 56 | |
| 30 | pub struct IndexLookup { | 57 | pub struct IndexLookup { |
| 31 | pub(crate) file: SingleOrMultiIndex, | 58 | pub(crate) file: SingleOrMultiIndex, |
| @@ -45,11 +72,12 @@ pub(crate) mod index_lookup { · 13 unmodified lines |
| 45 | | 72 | |
| 46 | use git_hash::oid; | 73 | use git_hash::oid; |
| 47 | | 74 | |
| | 75 | use crate::store::handle::IntraPackLookup; |
| 48 | use crate::store::{handle, types}; | 76 | use crate::store::{handle, types}; |
| 49 | | 77 | |
| 50 | pub(crate) struct Outcome<'a> { | 78 | pub(crate) struct Outcome<'a> { |
| 51 | pub object_index: handle::IndexForObjectInPack, | 79 | pub object_index: handle::IndexForObjectInPack, |
| 52 | pub index_file: &'a git_pack::index::File, | 80 | pub index_file: IntraPackLookup<'a>, |
| 53 | pub pack: &'a mut Option<Arc<git_pack::data::File>>, | 81 | pub pack: &'a mut Option<Arc<git_pack::data::File>>, |
| 54 | } | 82 | } |
| 55 | | 83 | |
| @@ -62,10 +90,9 @@ pub(crate) mod index_lookup { · 6 unmodified lines |
| 62 | (self.id == pack_id.index).then(|| match &self.file { | 90 | (self.id == pack_id.index).then(|| match &self.file { |
| 63 | handle::SingleOrMultiIndex::Single { index, .. } => index.iter(), | 91 | handle::SingleOrMultiIndex::Single { index, .. } => index.iter(), |
| 64 | handle::SingleOrMultiIndex::Multi { index, .. } => { | 92 | handle::SingleOrMultiIndex::Multi { index, .. } => { |
| 65 | // TODO: figure out if this could actually not be true all the time. | 93 | let pack_index = pack_id.multipack_index.expect( |
| 66 | let pack_index = pack_id | 94 | "BUG: multi-pack index must be set if this is a multi-pack, pack-indices seem unstable", |
| 67 | .multipack_index | 95 | ); |
| 68 | .expect("multi-pack index must be set if this is a multi-pack"); | | |
| 69 | Box::new(index.iter().filter_map(move |e| { | 96 | Box::new(index.iter().filter_map(move |e| { |
| 70 | (e.pack_index == pack_index as u32).then(|| git_pack::index::Entry { | 97 | (e.pack_index == pack_index as u32).then(|| git_pack::index::Entry { |
| 71 | oid: e.oid, | 98 | oid: e.oid, |
| @@ -81,11 +108,10 @@ pub(crate) mod index_lookup { · 9 unmodified lines |
| 81 | (self.id == pack_id.index).then(move || match &mut self.file { | 108 | (self.id == pack_id.index).then(move || match &mut self.file { |
| 82 | handle::SingleOrMultiIndex::Single { data, .. } => data, | 109 | handle::SingleOrMultiIndex::Single { data, .. } => data, |
| 83 | handle::SingleOrMultiIndex::Multi { data, .. } => { | 110 | handle::SingleOrMultiIndex::Multi { data, .. } => { |
| 84 | // TODO: figure out if this could actually not be true all the time. | 111 | let pack_index = pack_id.multipack_index.expect( |
| 85 | let pack_index = pack_id | 112 | "BUG: multi-pack index must be set if this is a multi-pack, pack-indices seem unstable", |
| 86 | .multipack_index | 113 | ); |
| 87 | .expect("multi-pack index must be set if this is a multi-pack"); | 114 | &mut data[pack_index as usize] |
| 88 | &mut data[pack_index] | | |
| 89 | } | 115 | } |
| 90 | }) | 116 | }) |
| 91 | } | 117 | } |
| @@ -130,12 +156,11 @@ pub(crate) mod index_lookup { · 38 unmodified lines |
| 130 | }, | 156 | }, |
| 131 | pack_offset: index.pack_offset_at_index(idx), | 157 | pack_offset: index.pack_offset_at_index(idx), |
| 132 | }, | 158 | }, |
| 133 | index_file: &**index, | 159 | index_file: IntraPackLookup::Single(&**index), |
| 134 | pack: data, | 160 | pack: data, |
| 135 | }), | 161 | }), |
| 136 | handle::SingleOrMultiIndex::Multi { index, data } => index.lookup(object_id).map(move |idx| { | 162 | handle::SingleOrMultiIndex::Multi { index, data } => index.lookup(object_id).map(move |idx| { |
| 137 | let (pack_index, pack_offset) = index.pack_offset_and_pack_id_at_index(idx); | 163 | let (pack_index, pack_offset) = index.pack_id_and_pack_offset_at_index(idx); |
| 138 | let pack_index = pack_index as usize; | | |
| 139 | Outcome { | 164 | Outcome { |
| 140 | object_index: handle::IndexForObjectInPack { | 165 | object_index: handle::IndexForObjectInPack { |
| 141 | pack_id: types::PackId { | 166 | pack_id: types::PackId { |
| @@ -144,9 +169,11 @@ pub(crate) mod index_lookup { · 2 unmodified lines |
| 144 | }, | 169 | }, |
| 145 | pack_offset, | 170 | pack_offset, |
| 146 | }, | 171 | }, |
| 147 | // index_file: &**index, | 172 | index_file: IntraPackLookup::Multi { |
| 148 | index_file: todo!("figure out how to pass different kinds of indices"), | 173 | index: &**index, |
| 149 | pack: &mut data[pack_index], | 174 | required_pack_index: pack_index, |
| | 175 | }, |
| | 176 | pack: &mut data[pack_index as usize], |
| 150 | } | 177 | } |
| 151 | }), | 178 | }), |
| 152 | } | 179 | } |