| 2351 | } |
| 2352 | |
| 2353 | fn find_by_git_sha_prefix(&self, prefix: &str) -> PristineResult<Option<NodeId>> { |
| 2354 | let table = match self.txn.open_table(GIT_SHA_INDEX) { |
| 2355 | Ok(t) => t, |
| 2356 | Err(redb::TableError::TableDoesNotExist(_)) => return Ok(None), |
| 2357 | Err(e) => return Err(PristineError::from(e)), |
| 2358 | }; |
| 2359 | // Range scan: prefix to prefix + "g" (one past hex range 0-f) |
| 2360 | let upper = format!("{}g", prefix); |
| 2361 | let mut matches = Vec::new(); |
| 2362 | for item in table.range(prefix..upper.as_str())? { |
| 2363 | let (key, value) = item?; |
| 2364 | matches.push((key.value().to_string(), NodeId::new(value.value()))); |
| 2365 | if matches.len() > 1 { |
| 2366 | return Err(PristineError::AmbiguousPrefix { |
| 2367 | prefix: prefix.to_string(), |
| 2368 | matches: matches.iter().map(|(k, _)| k.clone()).collect(), |
| 2369 | }); |
| 2370 | } |
| 2371 | } |
| 2372 | Ok(matches.into_iter().next().map(|(_, id)| id)) |
| 2373 | } |
| 2374 | } |
| 2375 | |
| 2376 | #[cfg(test)] |