use bun_collections::array_hash_map::ArrayHashAdapter;
use bun_collections::multi_array_list;
use bun_collections::{ArrayHashMap, DynamicBitSetUnmanaged, MultiArrayList};
use super::base::IndexInt;
use super::use_directive::UseDirective;
#[derive(bun_collections::SoaRowDerive, Clone, Copy)]
pub struct ServerComponentBoundary {
pub use_directive: UseDirective,
pub source_index: IndexInt,
pub reference_source_index: IndexInt,
pub ssr_source_index: IndexInt,
}
bun_collections::multi_array_columns! {
pub trait ServerComponentBoundaryColumns for ServerComponentBoundary {
use_directive: UseDirective,
source_index: IndexInt,
reference_source_index: IndexInt,
ssr_source_index: IndexInt,
}
}
#[derive(Default)]
pub struct List {
pub list: MultiArrayList<ServerComponentBoundary>,
pub map: Map,
}
type Map = ArrayHashMap<(), ()>;
impl List {
pub fn put(
&mut self,
source_index: IndexInt,
use_directive: UseDirective,
reference_source_index: IndexInt,
ssr_source_index: IndexInt,
) -> Result<(), bun_alloc::AllocError> {
self.list.append(ServerComponentBoundary {
source_index,
use_directive,
reference_source_index,
ssr_source_index,
})?;
let gop = self.map.get_or_put_adapted(
&source_index,
&Adapter {
source_indices: self.list.items_named::<IndexInt>("source_index"),
},
)?;
debug_assert!(!gop.found_existing);
Ok(())
}
pub fn get_index(&self, real_source_index: IndexInt) -> Option<usize> {
self.map.get_index_adapted(
&real_source_index,
&Adapter {
source_indices: self.list.items_named::<IndexInt>("source_index"),
},
)
}
pub fn slice(&self) -> Slice<'_> {
Slice {
list: self.list.slice(),
map: &self.map,
}
}
}
pub struct Slice<'a> {
pub list: multi_array_list::Slice<ServerComponentBoundary>,
pub map: &'a Map,
}
impl<'a> Slice<'a> {
pub fn get_index(&self, real_source_index: IndexInt) -> Option<usize> {
self.map.get_index_adapted(
&real_source_index,
&Adapter {
source_indices: self.list.items_named::<IndexInt>("source_index"),
},
)
}
pub fn get_reference_source_index(&self, real_source_index: IndexInt) -> Option<u32> {
let i = self.map.get_index_adapted(
&real_source_index,
&Adapter {
source_indices: self.list.items_named::<IndexInt>("source_index"),
},
)?;
Some(self.list.items_named::<IndexInt>("reference_source_index")[i])
}
pub fn bit_set(
&self,
input_file_count: usize,
) -> Result<DynamicBitSetUnmanaged, bun_alloc::AllocError> {
let mut scb_bitset = DynamicBitSetUnmanaged::init_empty(input_file_count)?;
for &source_index in self.list.items_named::<IndexInt>("source_index") {
scb_bitset.set(source_index as usize);
}
Ok(scb_bitset)
}
}
pub(crate) struct Adapter<'a> {
pub source_indices: &'a [IndexInt],
}
impl<'a> ArrayHashAdapter<IndexInt, ()> for Adapter<'a> {
#[inline]
fn hash(&self, key: &IndexInt) -> u32 {
bun_wyhash::hash_int(*key)
}
#[inline]
fn eql(&self, a: &IndexInt, _b: &(), b_index: usize) -> bool {
*a == self.source_indices[b_index]
}
}