1use core::hash::Hash;
4
5use osom_lib_alloc::traits::Allocator;
6use osom_lib_primitives::length::Length;
7use osom_lib_reprc::{macros::reprc, traits::ReprC};
8
9use crate::{
10 bytell::{defaults::DefaultBytellConfig, errors::BytellError, hash_table::BytellHashTable},
11 traits::{ImmutableHashTable, MutableHashTable},
12};
13
14#[reprc]
16#[repr(u8)]
17#[must_use]
18pub enum DefaultHashTableError {
19 AllocationError = 0,
21
22 TableTooBigError = 1,
24}
25
26impl From<BytellError> for DefaultHashTableError {
27 fn from(error: BytellError) -> Self {
28 match error {
29 BytellError::AllocationError => DefaultHashTableError::AllocationError,
30 BytellError::TableTooBigError => DefaultHashTableError::TableTooBigError,
31 }
32 }
33}
34
35#[derive(PartialEq, Eq, Hash, Clone)]
42#[repr(transparent)]
43#[must_use]
44pub struct DefaultHashTable<TKey, TValue, TAllocator>
45where
46 TKey: Eq + Hash,
47 TAllocator: Allocator,
48{
49 inner: BytellHashTable<TKey, TValue, DefaultBytellConfig<TAllocator>>,
50}
51
52unsafe impl<TKey, TValue, TAllocator> ReprC for DefaultHashTable<TKey, TValue, TAllocator>
53where
54 TKey: Eq + Hash + ReprC,
55 TValue: ReprC,
56 TAllocator: Allocator + ReprC,
57{
58 const CHECK: () = const {
59 let () = <BytellHashTable<TKey, TValue, DefaultBytellConfig<TAllocator>> as ReprC>::CHECK;
60 };
61}
62
63impl<TKey, TValue, TAllocator> DefaultHashTable<TKey, TValue, TAllocator>
64where
65 TKey: Eq + Hash,
66 TAllocator: Allocator,
67{
68 #[inline(always)]
70 pub fn new() -> Self {
71 Self::with_allocator(TAllocator::default())
72 }
73
74 #[inline(always)]
76 pub fn with_allocator(allocator: TAllocator) -> Self {
77 Self {
78 inner: BytellHashTable::with_config(DefaultBytellConfig::with_allocator(allocator)),
79 }
80 }
81
82 #[inline(always)]
90 pub fn with_capacity(capacity: Length) -> Result<Self, DefaultHashTableError> {
91 Self::with_capacity_and_allocator(capacity, TAllocator::default())
92 }
93
94 #[inline(always)]
102 pub fn with_capacity_and_allocator(capacity: Length, allocator: TAllocator) -> Result<Self, DefaultHashTableError> {
103 let inner = BytellHashTable::with_capacity_and_config(
104 capacity.as_u32(),
105 DefaultBytellConfig::with_allocator(allocator),
106 )?;
107 Ok(Self { inner })
108 }
109}
110
111impl<TKey, TValue, TAllocator> ImmutableHashTable<TKey, TValue> for DefaultHashTable<TKey, TValue, TAllocator>
112where
113 TKey: Eq + Hash,
114 TAllocator: Allocator,
115{
116 #[inline(always)]
117 fn length(&self) -> Length {
118 self.inner.length()
119 }
120
121 #[inline(always)]
122 fn contains<Q>(&self, key: &Q) -> bool
123 where
124 TKey: core::borrow::Borrow<Q>,
125 Q: Eq + Hash + ?Sized,
126 {
127 self.inner.contains(key)
128 }
129
130 #[inline(always)]
131 fn get<Q>(&self, key: &Q) -> Option<&TValue>
132 where
133 TKey: core::borrow::Borrow<Q>,
134 Q: Eq + Hash + ?Sized,
135 {
136 self.inner.get(key)
137 }
138
139 #[inline(always)]
140 fn get_key_value<Q>(&self, key: &Q) -> Option<(&TKey, &TValue)>
141 where
142 TKey: core::borrow::Borrow<Q>,
143 Q: Eq + Hash + ?Sized,
144 {
145 self.inner.get_key_value(key)
146 }
147
148 #[inline(always)]
149 fn iter<'a>(&'a self) -> impl Iterator<Item = (&'a TKey, &'a TValue)>
150 where
151 TKey: 'a,
152 TValue: 'a,
153 Self: 'a,
154 {
155 self.inner.iter()
156 }
157}
158
159impl<TKey, TValue, TAllocator> MutableHashTable<TKey, TValue> for DefaultHashTable<TKey, TValue, TAllocator>
160where
161 TKey: Eq + Hash,
162 TAllocator: Allocator,
163{
164 #[inline(always)]
165 fn insert(&mut self, key: TKey, value: TValue) -> Option<TValue> {
166 self.inner.insert(key, value)
167 }
168
169 #[inline(always)]
170 fn remove_entry<Q>(&mut self, key: &Q) -> Option<(TKey, TValue)>
171 where
172 TKey: core::borrow::Borrow<Q>,
173 Q: Eq + Hash + ?Sized,
174 {
175 self.inner.remove_entry(key)
176 }
177
178 #[inline(always)]
179 fn insert_or_update_with<FAdd, FUpdate>(&mut self, key: TKey, adder: FAdd, updater: FUpdate) -> &mut TValue
180 where
181 FAdd: FnOnce() -> TValue,
182 FUpdate: FnOnce(&mut TValue),
183 {
184 self.inner.insert_or_update_with(key, adder, updater)
185 }
186
187 #[inline(always)]
188 fn iter_mut<'a>(&'a mut self) -> impl Iterator<Item = (&'a TKey, &'a mut TValue)>
189 where
190 TKey: 'a,
191 TValue: 'a,
192 Self: 'a,
193 {
194 self.inner.iter_mut()
195 }
196}
197
198impl<TKey, TValue, TAllocator> Default for DefaultHashTable<TKey, TValue, TAllocator>
199where
200 TKey: Eq + Hash,
201 TAllocator: Allocator,
202{
203 #[inline(always)]
204 fn default() -> Self {
205 Self::new()
206 }
207}
208
209#[cfg(feature = "std")]
210use osom_lib_alloc::std_allocator::StdAllocator;
211
212#[cfg(feature = "std")]
213#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
214pub type StdHashTable<TKey, TValue> = DefaultHashTable<TKey, TValue, StdAllocator>;