Initial commit

This commit is contained in:
Aleksandr 2024-10-15 19:03:39 +03:00
commit 9282b8565d
24 changed files with 599 additions and 0 deletions

8
crates/std/Cargo.toml Normal file
View file

@ -0,0 +1,8 @@
[package]
name = "shiny-std"
version = "0.1.0"
edition = "2021"
[dependencies]
fxhash.workspace = true
hashbrown.workspace = true

View file

@ -0,0 +1,73 @@
//! # Interning arena.
use std::{hash::Hash, num::NonZeroU32};
use hashbrown::hash_map::RawEntryMut;
use crate::collections::HashMap;
use super::wonly;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
struct Mapping<P> {
hash: u64,
key: P,
}
#[derive(Clone)]
pub struct Arena<T, P> {
objects: wonly::Arena<T, P>,
// No raw_entry API on hashset.
bi: HashMap<Mapping<P>, ()>,
}
impl<T, P> Default for Arena<T, P> {
fn default() -> Self {
Self {
objects: wonly::Arena::new(),
bi: HashMap::default(),
}
}
}
impl<T, P> Arena<T, P> {
pub fn get(&self, ptr: P) -> Option<&T>
where
NonZeroU32: From<P>,
{
self.objects.get(ptr)
}
pub fn insert(&mut self, object: T) -> P
where
P: From<NonZeroU32> + Hash + Clone,
NonZeroU32: From<P>,
T: Hash + Eq,
{
let hash = fxhash::hash64(&object);
match self.bi.raw_entry_mut().from_hash(hash, |m| {
self.objects
.get(m.key.clone())
.map_or(false, |lhs| lhs == &object)
}) {
RawEntryMut::Occupied(occup) => occup.into_key().key.clone(),
RawEntryMut::Vacant(vacant) => {
let key = self.objects.insert(object);
vacant.insert(
Mapping {
hash,
key: key.clone(),
},
(),
);
key
}
}
}
pub fn new() -> Self {
Self::default()
}
}

View file

@ -0,0 +1,20 @@
/// Combination of pointers.
#[macro_export]
#[doc(hidden)]
macro_rules! _make_comb {
($(
$item:item
)*) => {$(
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
)]
$item
)*};
}

View file

@ -0,0 +1,8 @@
pub mod intern;
pub mod wonly;
pub mod ptr;
pub use crate::_make_comb as make_comb;
mod macros;

View file

@ -0,0 +1,59 @@
use std::num::NonZeroU32;
#[macro_export]
#[doc(hidden)]
macro_rules! _ptrs {
($(
$(#[$outer:meta])*
$vis:vis struct $name:ident;
)*) => {$(
$(#[$outer])*
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
)]
$vis struct $name(::core::num::NonZeroU32);
impl $name {
/// Create instance of the pointer.
pub const fn new(v: ::core::num::NonZeroU32) -> Self {
Self(v)
}
pub const fn get(&self) -> ::core::num::NonZeroU32 {
self.0
}
}
impl From<$name> for ::core::num::NonZeroU32 {
fn from(value: $name) -> Self {
value.get()
}
}
impl From<::core::num::NonZeroU32> for $name {
fn from(value: ::core::num::NonZeroU32) -> Self {
Self::new(value)
}
}
impl $crate::ptr::Ptr for $name {
fn get(&self) -> ::core::num::NonZeroU32 {
self.0
}
}
)*};
}
/// Pointer in arena.
pub trait Ptr {
fn get(&self) -> NonZeroU32;
}
pub use crate::_ptrs as define;

View file

@ -0,0 +1,52 @@
//! # Write-only arena, without deletion
use std::{marker::PhantomData, num::NonZeroU32};
#[derive(Clone)]
pub struct Arena<T, P> {
mem: Vec<T>,
_ptr_ty: PhantomData<P>,
}
impl<T, P> Arena<T, P> {
pub fn get(&self, ptr: P) -> Option<&T>
where
P: Into<NonZeroU32>,
{
let index = ptr.into().get() as usize - 1;
self.mem.get(index)
}
pub fn insert(&mut self, obj: T) -> P
where
NonZeroU32: Into<P>,
{
let idx = self.mem.len();
self.mem.push(obj);
let ptr = idx
.checked_add(1)
.and_then(|v| v.try_into().ok())
.and_then(NonZeroU32::new)
.expect("shit happens")
.into();
ptr
}
}
impl<T, P> Default for Arena<T, P> {
fn default() -> Self {
Self::new()
}
}
impl<T, P> Arena<T, P> {
pub const fn new() -> Self {
Self {
mem: Vec::new(),
_ptr_ty: PhantomData,
}
}
}

View file

@ -0,0 +1,6 @@
use std::hash::BuildHasherDefault;
use fxhash::FxHasher;
pub type HashMap<K, V> = hashbrown::HashMap<K, V, BuildHasherDefault<FxHasher>>;
pub type HashSet<V> = hashbrown::HashSet<V, BuildHasherDefault<FxHasher>>;

3
crates/std/src/lib.rs Normal file
View file

@ -0,0 +1,3 @@
pub mod collections;
pub mod arena;