#![cfg_attr(bao_nightly, feature(allocator_api))]
#![warn(unused_must_use)]
extern crate self as bun_collections;
pub mod hive_array;
pub mod multi_array_list;
pub use multi_array_list::{SoaFieldInfo, SoaRow};
pub use bun_collections_macros::SoaRow as SoaRowDerive;
pub mod vec_ext;
pub use bun_core::bounded_array;
pub mod identity_context;
pub mod linear_fifo;
pub mod bit_set;
pub mod pool;
pub use pool::{ObjectPool, ObjectPoolTrait, ObjectPoolType, PoolGuard};
pub mod comptime_string_map;
pub use comptime_string_map::{ComptimeStringMap, ComptimeStringMapWithKeyType};
#[path = "StaticHashMap.rs"]
pub mod static_hash_map;
pub use static_hash_map::StaticHashMap;
pub use bounded_array::BoundedArray;
pub use hive_array::{
Fallback as HiveArrayFallback, HiveArray, HiveBox, HiveRef, HiveRefHandle, HiveSlot,
};
pub use linear_fifo::{LinearFifo, LinearFifoBufferType};
pub use multi_array_list::MultiArrayList;
#[doc(hidden)]
pub use paste::paste as __mal_paste;
pub use vec_ext::{ByteVecExt, OffsetByteList, VecExt, prepend_from};
pub use bit_set::{
AutoBitSet, DynamicBitSet, DynamicBitSetList, DynamicBitSetUnmanaged, IntegerBitSet,
StaticBitSet,
};
pub use bun_core::strings::{const_bytes_eq, const_str_eq};
pub mod dynamic_bit_set {
pub use super::bit_set::DynamicBitSet;
pub use super::bit_set::DynamicBitSetList as List;
}
pub trait PriorityCompare<T> {
fn compare(&self, a: &T, b: &T) -> core::cmp::Ordering;
}
pub struct PriorityQueue<T, C> {
pub items: Vec<T>,
pub context: C,
}
impl<T, C: Default> Default for PriorityQueue<T, C> {
fn default() -> Self {
Self {
items: Vec::new(),
context: C::default(),
}
}
}
impl<T, C> PriorityQueue<T, C> {
pub fn init(context: C) -> Self {
Self {
items: Vec::new(),
context,
}
}
#[inline]
pub fn count(&self) -> usize {
self.items.len()
}
#[inline]
pub fn len(&self) -> usize {
self.items.len()
}
pub fn deinit(&mut self) {
self.items.clear();
}
}
impl<T: Copy, C: PriorityCompare<T>> PriorityQueue<T, C> {
pub fn add(&mut self, elem: T) -> Result<(), bun_alloc::AllocError> {
self.items.push(elem);
let mut child = self.items.len() - 1;
while child > 0 {
let parent = (child - 1) / 2;
if self
.context
.compare(&self.items[child], &self.items[parent])
== core::cmp::Ordering::Less
{
self.items.swap(child, parent);
child = parent;
} else {
break;
}
}
Ok(())
}
pub fn remove_or_null(&mut self) -> Option<T> {
if self.items.is_empty() {
return None;
}
let last = self.items.len() - 1;
self.items.swap(0, last);
let out = self.items.pop();
let len = self.items.len();
let mut idx = 0usize;
loop {
let l = 2 * idx + 1;
let r = 2 * idx + 2;
let mut smallest = idx;
if l < len
&& self.context.compare(&self.items[l], &self.items[smallest])
== core::cmp::Ordering::Less
{
smallest = l;
}
if r < len
&& self.context.compare(&self.items[r], &self.items[smallest])
== core::cmp::Ordering::Less
{
smallest = r;
}
if smallest == idx {
break;
}
self.items.swap(idx, smallest);
idx = smallest;
}
out
}
}
pub use identity_context::{
ArrayIdentityContext, ArrayIdentityContextU64, IdentityContext, IdentityHash, U64,
};
pub mod array_hash_map;
pub use array_hash_map::{
ArrayHashMap, ArrayHashMapExt, AutoContext, CaseInsensitiveAsciiPrehashed,
CaseInsensitiveAsciiStringArrayHashMap, CaseInsensitiveAsciiStringContext, Entry,
GetOrPutResult, MapEntry, OccupiedEntry, StringArrayHashMap, StringHashMap,
StringHashMapContext, StringHashMapInner, StringHashMapKey, StringHashMapUnownedKey, StringSet,
VacantEntry, string_hash_map,
};
pub use hashbrown;
pub mod string_map;
pub use string_map::StringMap;
pub use bun_ptr::tagged_pointer::{TaggedPtr as TaggedPointer, TaggedPtrUnion};
pub use bun_ptr::{RawSlice, detach_lifetime, detach_ref};
pub use smallvec;
#[repr(transparent)]
pub struct SmallList<T, const N: usize>(pub smallvec::SmallVec<[T; N]>);
impl<T, const N: usize> Default for SmallList<T, N> {
#[inline]
fn default() -> Self {
Self(smallvec::SmallVec::new())
}
}
impl<T: Clone, const N: usize> Clone for SmallList<T, N> {
#[cfg_attr(bun_asan, inline(never))]
#[cfg_attr(not(bun_asan), inline)]
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T: PartialEq, const N: usize> PartialEq for SmallList<T, N> {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T: Eq, const N: usize> Eq for SmallList<T, N> {}
impl<T: core::fmt::Debug, const N: usize> core::fmt::Debug for SmallList<T, N> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
self.0.fmt(f)
}
}
impl<T, const N: usize> core::ops::Deref for SmallList<T, N> {
type Target = [T];
#[inline]
fn deref(&self) -> &[T] {
self.0.as_slice()
}
}
impl<T, const N: usize> core::ops::DerefMut for SmallList<T, N> {
#[inline]
fn deref_mut(&mut self) -> &mut [T] {
self.0.as_mut_slice()
}
}
impl<T, const N: usize> IntoIterator for SmallList<T, N> {
type Item = T;
type IntoIter = smallvec::IntoIter<[T; N]>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a, T, const N: usize> IntoIterator for &'a SmallList<T, N> {
type Item = &'a T;
type IntoIter = core::slice::Iter<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl<'a, T, const N: usize> IntoIterator for &'a mut SmallList<T, N> {
type Item = &'a mut T;
type IntoIter = core::slice::IterMut<'a, T>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.0.iter_mut()
}
}
impl<T, const N: usize> FromIterator<T> for SmallList<T, N> {
#[cfg_attr(bun_asan, inline(never))]
#[cfg_attr(not(bun_asan), inline)]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
Self(smallvec::SmallVec::from_iter(iter))
}
}
impl<T, const N: usize> Extend<T> for SmallList<T, N> {
#[cfg_attr(bun_asan, inline(never))]
#[cfg_attr(not(bun_asan), inline)]
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.0.extend(iter)
}
}
#[allow(clippy::len_without_is_empty)]
impl<T, const N: usize> SmallList<T, N> {
#[inline]
pub fn with_one(val: T) -> Self {
let mut v = smallvec::SmallVec::new();
v.push(val);
Self(v)
}
#[cfg_attr(bun_asan, inline(never))]
#[cfg_attr(not(bun_asan), inline)]
pub fn init_capacity(capacity: u32) -> Self {
Self(smallvec::SmallVec::with_capacity(capacity as usize))
}
#[inline]
pub fn init_inlined(values: &[T]) -> Self
where
T: Copy,
{
debug_assert!(values.len() <= N);
Self(smallvec::SmallVec::from_slice(values))
}
#[cfg_attr(bun_asan, inline(never))]
#[cfg_attr(not(bun_asan), inline)]
pub fn from_arena_iter<I>(arena: &bun_alloc::Arena, iter: I) -> Self
where
I: IntoIterator<Item = T>,
I::IntoIter: ExactSizeIterator,
{
let iter = iter.into_iter();
let len = iter.len();
if len <= N {
return Self(smallvec::SmallVec::from_iter(iter));
}
let slab = arena.alloc_slice_fill_iter(iter);
Self(unsafe { smallvec::SmallVec::from_raw_parts(slab.as_mut_ptr(), len, len) })
}
#[inline]
pub fn from_list(list: Vec<T>) -> Self {
Self(smallvec::SmallVec::from_vec(list))
}
#[inline]
pub fn len(&self) -> u32 {
self.0.len() as u32
}
#[inline]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[inline]
pub fn slice(&self) -> &[T] {
self.0.as_slice()
}
#[inline]
pub fn slice_mut(&mut self) -> &mut [T] {
self.0.as_mut_slice()
}
#[inline]
pub fn at(&self, idx: u32) -> &T {
&self.0[idx as usize]
}
#[inline]
pub fn r#mut(&mut self, idx: u32) -> &mut T {
&mut self.0[idx as usize]
}
#[inline]
pub fn last(&self) -> Option<&T> {
self.0.last()
}
#[inline]
pub fn last_mut(&mut self) -> Option<&mut T> {
self.0.last_mut()
}
#[cfg_attr(bun_asan, inline(never))]
#[cfg_attr(not(bun_asan), inline)]
pub fn append(&mut self, item: T) {
self.0.push(item)
}
#[cfg_attr(bun_asan, inline(never))]
#[cfg_attr(not(bun_asan), inline)]
pub fn append_assume_capacity(&mut self, item: T) {
self.0.push(item)
}
#[cfg_attr(bun_asan, inline(never))]
#[cfg_attr(not(bun_asan), inline)]
pub fn append_slice(&mut self, items: &[T])
where
T: Clone,
{
self.0.extend(items.iter().cloned())
}
#[cfg_attr(bun_asan, inline(never))]
#[cfg_attr(not(bun_asan), inline)]
pub fn append_slice_assume_capacity(&mut self, items: &[T])
where
T: Clone,
{
self.0.extend(items.iter().cloned())
}
#[inline]
pub fn insert(&mut self, index: u32, item: T) {
self.0.insert(index as usize, item)
}
#[inline]
pub fn insert_slice(&mut self, index: u32, items: &[T])
where
T: Clone,
{
self.0.insert_many(index as usize, items.iter().cloned())
}
#[inline]
pub fn insert_slice_assume_capacity(&mut self, index: u32, items: &[T])
where
T: Clone,
{
self.0.insert_many(index as usize, items.iter().cloned())
}
#[inline]
pub fn pop(&mut self) -> Option<T> {
self.0.pop()
}
#[inline]
pub fn ordered_remove(&mut self, idx: u32) -> T {
self.0.remove(idx as usize)
}
#[inline]
pub fn swap_remove(&mut self, idx: u32) -> T {
self.0.swap_remove(idx as usize)
}
#[inline]
pub fn clear_retaining_capacity(&mut self) {
self.0.clear()
}
#[inline]
pub fn reserve(&mut self, additional: u32) {
self.0.reserve(additional as usize)
}
#[inline]
pub fn ensure_total_capacity(&mut self, new_capacity: u32) {
let cur = self.0.capacity();
if (new_capacity as usize) > cur {
self.0.reserve_exact(new_capacity as usize - cur);
}
}
#[inline]
pub fn set_len(&mut self, new_len: u32) {
unsafe { self.0.set_len(new_len as usize) }
}
#[inline]
pub fn to_owned_slice(self) -> Box<[T]> {
self.0.into_vec().into_boxed_slice()
}
#[inline]
pub fn into_vec(self) -> Vec<T> {
self.0.into_vec()
}
#[inline]
pub fn shallow_clone(&self) -> Self
where
T: Copy,
{
Self(self.0.clone())
}
#[inline]
pub fn any(&self, predicate: impl Fn(&T) -> bool) -> bool {
self.0.iter().any(predicate)
}
#[inline]
pub fn map(&mut self, func: impl Fn(&mut T)) {
for item in self.0.iter_mut() {
func(item);
}
}
}
pub mod zig_hash_map;
pub use zig_hash_map::{AutoHashContext, HashContext, HashMap};
pub mod hash_map {
pub use crate::array_hash_map::{MapEntry as Entry, OccupiedEntry, VacantEntry};
pub struct GetOrPutResult<'a, V> {
pub found_existing: bool,
pub value_ptr: &'a mut V,
}
pub use crate::array_hash_map::KV;
}
pub mod array_list;
pub use array_list::ArrayList; pub use array_list::ArrayListAligned;
pub use array_list::ArrayListAlignedDefault;
pub use array_list::ArrayListDefault; pub use array_list::ArrayListIn;