use std::any::TypeId;
use std::cell::RefCell;
use std::sync::{LazyLock, Mutex};
use crate::hashing::{one_shot_128, HashMap};
use crate::people::HashValueType;
static MULTI_PROPERTY_INDEX_MAP: LazyLock<Mutex<RefCell<HashMap<HashValueType, TypeId>>>> =
LazyLock::new(|| Mutex::new(RefCell::new(HashMap::default())));
pub fn type_ids_to_multi_property_id(type_ids: &[TypeId]) -> Option<TypeId> {
let hash = one_shot_128(&type_ids);
MULTI_PROPERTY_INDEX_MAP
.lock()
.unwrap()
.borrow()
.get(&hash)
.copied()
}
pub fn register_type_ids_to_muli_property_id(type_ids: &[TypeId], multi_property_id: TypeId) {
let hash = one_shot_128(&type_ids);
MULTI_PROPERTY_INDEX_MAP
.lock()
.unwrap()
.borrow_mut()
.insert(hash, multi_property_id);
}
const fn make_indices<const N: usize>() -> [usize; N] {
let mut arr = [0; N];
let mut i = 0;
while i < N {
arr[i] = i;
i += 1;
}
arr
}
pub fn sorted_indices<T: Ord>(keys: &[T]) -> Vec<usize> {
let mut indices: Vec<usize> = (0..keys.len()).collect();
indices.sort_by_key(|&i| &keys[i]);
indices
}
pub fn static_sorted_indices<T: Ord, const N: usize>(keys: &[T; N]) -> [usize; N] {
let mut indices = make_indices::<N>();
indices.sort_by_key(|&i| &keys[i]);
indices
}
pub fn static_apply_reordering<T: Copy, const N: usize>(values: &mut [T; N], indices: &[usize; N]) {
let tmp_values: [T; N] = *values;
for (old_index, new_index) in indices.iter().enumerate() {
values[old_index] = tmp_values[*new_index];
}
}
pub fn static_reorder_by_keys<T: Ord + Copy, U: Copy, const N: usize>(
keys: &[T; N],
values: &mut [U; N],
) {
let indices: [usize; N] = static_sorted_indices(keys);
static_apply_reordering(values, &indices);
}
pub fn reorder_by_keys<T: Ord + Copy, U: Copy>(keys: &mut [T], values: &mut [U]) {
let indices: Vec<usize> = sorted_indices(keys);
let tmp_keys = Vec::from(&*keys);
let tmp_values = Vec::from(&*values);
for (old_index, new_index) in indices.into_iter().enumerate() {
values[old_index] = tmp_values[new_index];
keys[old_index] = tmp_keys[new_index];
}
}