| 251 | .is_some_and(|cell| cell.hash == key_hash && cell.text == key) |
| 252 | }) |
| 253 | } |
| 254 | |
| 255 | #[inline] |
| 256 | pub fn query(&'static self) -> CSVQuery { |
| 257 | CSVQuery::new(self) |
| 258 | } |
| 259 | |
| 260 | pub fn to_buf(&self) -> CsvBuf { |
| 261 | CsvBuf::from_static(self) |
| 262 | } |
| 263 | |
| 264 | /// Run `f` against the cached hash index for `col`, building it on first |
| 265 | /// use. Holds the lock guard across `f` so the index is never cloned out |
| 266 | /// (a per-query `O(rows)` copy on the seeded fast path). |
| 267 | fn with_hash_index<R>( |
| 268 | &'static self, |
| 269 | col: usize, |
| 270 | f: impl FnOnce(&CsvColumnHashIndex) -> R, |
| 271 | ) -> R { |
| 272 | let indexes = self |
| 273 | .query_indexes |
| 274 | .get_or_init(|| RwLock::new(HashMap::new())); |
| 275 | { |
| 276 | let read = indexes.read().expect("csv query index rwlock poisoned"); |
| 277 | if let Some(index) = read.get(&col) { |
| 278 | return f(index); |
| 279 | } |
| 280 | } |