(
&self,
file_index: FileIndex<IndexFileId>,
max_loads: u16,
skipm: &mut FxHashSet<u64>,
)
| 187 | } |
| 188 | |
| 189 | pub fn get_lazy_object( |
| 190 | &self, |
| 191 | file_index: FileIndex<IndexFileId>, |
| 192 | max_loads: u16, |
| 193 | skipm: &mut FxHashSet<u64>, |
| 194 | ) -> Result<SharedNode, BufIoError> { |
| 195 | let combined_index = Self::combine_index(&file_index); |
| 196 | |
| 197 | if let Some(item) = self.registry.get(&combined_index) { |
| 198 | return Ok(item); |
| 199 | } |
| 200 | |
| 201 | if max_loads == 0 || !skipm.insert(combined_index) { |
| 202 | return Ok(LazyItem::new_pending(file_index)); |
| 203 | } |
| 204 | |
| 205 | let mut mutex = self |
| 206 | .loading_items |
| 207 | .get_or_create(combined_index, || Arc::new(Mutex::new(false))); |
| 208 | let mut load_complete = mutex.lock().unwrap(); |
| 209 | |
| 210 | loop { |
| 211 | // check again |
| 212 | if let Some(item) = self.registry.get(&combined_index) { |
| 213 | return Ok(item); |
| 214 | } |
| 215 | |
| 216 | // another thread loaded the data but its not in the registry (got evicted), retry |
| 217 | if *load_complete { |
| 218 | drop(load_complete); |
| 219 | mutex = self |
| 220 | .loading_items |
| 221 | .get_or_create(combined_index, || Arc::new(Mutex::new(false))); |
| 222 | load_complete = mutex.lock().unwrap(); |
| 223 | continue; |
| 224 | } |
| 225 | |
| 226 | break; |
| 227 | } |
| 228 | |
| 229 | let bufman = self.bufmans.get(file_index.file_id)?; |
| 230 | let data = ProbNode::deserialize( |
| 231 | &bufman, |
| 232 | &self.latest_version_links_bufman, |
| 233 | file_index, |
| 234 | self, |
| 235 | max_loads - 1, |
| 236 | skipm, |
| 237 | )?; |
| 238 | let item = LazyItem::new(data, file_index.file_id, file_index.offset); |
| 239 | |
| 240 | self.registry.insert(combined_index, item); |
| 241 | *load_complete = true; |
| 242 | self.loading_items.delete(&combined_index); |
| 243 | |
| 244 | Ok(item) |
| 245 | } |
| 246 |
no test coverage detected