use std::collections::{HashMap, HashSet};
use gpui::SharedString;
use super::{RecordColumn, RecordRow};
#[cfg(test)]
thread_local! {
static STABLE_ID_VISITS: std::cell::Cell<usize> = const { std::cell::Cell::new(0) };
}
#[inline]
fn note_stable_id_visits(visited: usize) {
#[cfg(test)]
STABLE_ID_VISITS.with(|visits| visits.set(visits.get().saturating_add(visited)));
#[cfg(not(test))]
let _ = visited;
}
#[cfg(test)]
pub(super) fn take_stable_id_visits() -> usize {
STABLE_ID_VISITS.with(|visits| visits.replace(0))
}
#[derive(Debug, Default)]
pub(super) struct StableIdIndex {
positions: HashMap<SharedString, usize>,
}
impl StableIdIndex {
pub(super) fn position(&self, id: &str) -> Option<usize> {
note_stable_id_visits(1);
self.positions.get(id).copied()
}
}
pub(super) fn index_valid_rows(rows: &[RecordRow]) -> Option<StableIdIndex> {
note_stable_id_visits(rows.len());
let mut positions = HashMap::with_capacity(rows.len());
for (row_ix, row) in rows.iter().enumerate() {
let mut cell_ids = HashSet::with_capacity(row.cells.len());
if !row
.cells
.iter()
.all(|cell| cell_ids.insert(cell.column_id()))
|| positions.insert(row.id.clone(), row_ix).is_some()
{
return None;
}
}
Some(StableIdIndex { positions })
}
pub(super) fn index_valid_columns(columns: &[RecordColumn]) -> Option<StableIdIndex> {
note_stable_id_visits(columns.len());
let mut positions = HashMap::with_capacity(columns.len());
for (col_ix, column) in columns.iter().enumerate() {
if positions.insert(column.id.clone(), col_ix).is_some() {
return None;
}
}
Some(StableIdIndex { positions })
}