chobitlibs/chobit_map.rs
1// Copyright (C) 2022 Hironori Ishibashi
2//
3// This work is free. You can redistribute it and/or modify it under the
4// terms of the Do What The Fuck You Want To Public License, Version 2,
5// as published by Sam Hocevar. See below for more details.
6//
7// --------------------------------------------------------------------
8//
9// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
10// Version 2, December 2004
11//
12// Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
13//
14// Everyone is permitted to copy and distribute verbatim or modified
15// copies of this license document, and changing it is allowed as long
16// as the name is changed.
17//
18// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
19// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
20//
21// 0. You just DO WHAT THE FUCK YOU WANT TO.
22
23#![allow(dead_code)]
24
25//! Hash table library.
26//!
27//! This library needs `alloc` crate.
28//!
29//! ```ignore
30//! extern crate alloc;
31//! ```
32
33use alloc::vec::Vec;
34
35use core::{fmt, iter::Iterator, slice::Iter as SIter};
36
37/// Error for [ChobitMap]
38#[derive(Debug, Clone, PartialEq)]
39pub enum ChobitMapError {
40 /// Key already exists.
41 ///
42 /// - `key` : Key.
43 AlreadyExists {key: u64},
44
45 /// Key is not found.
46 ///
47 /// - `key` : Key.
48 NotFound {key: u64}
49}
50
51impl fmt::Display for ChobitMapError {
52 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
53 write!(formatter, r#"{{"error":"ChobitMapError","#)?;
54
55 match self {
56 Self::AlreadyExists {key} => {
57 write!(
58 formatter,
59 r#""kind":"AlreadyExists","key":{}"#,
60 key
61 )?;
62 },
63
64 Self::NotFound {key} => {
65 write!(
66 formatter,
67 r#""kind":"NotFound","key":{}"#,
68 key
69 )?;
70 }
71 }
72
73 write!(formatter, "}}")
74 }
75}
76
77/// This is a so-called `HashMap`, but key is specialized by `u64`.
78///
79/// `ChobitMap` is the faster than Rust's `HashMap`.
80pub struct ChobitMap<T> {
81 key_table: Vec<Vec<u64>>,
82 value_table: Vec<Vec<T>>,
83
84 key_mask: u64
85}
86
87impl<T> ChobitMap<T> {
88 /// Creates ChobitMap.
89 ///
90 /// - `table_size` : Key-value table size. this is repaired into power of 2.
91 /// - _Return_ : Instance.
92 ///
93 /// ```ignore
94 /// use chobitlibs::chobit_map::ChobitMap;
95 ///
96 /// let map = ChobitMap::<i32>::new(200);
97 /// assert_eq!(map.table_size(), 128);
98 /// ```
99 #[inline]
100 pub fn new(table_size: usize) -> Self {
101 let table_size = Self::check_table_size(table_size);
102
103 Self {
104 key_table: Self::init_key_table(table_size),
105 value_table: Self::init_value_table(table_size),
106
107 key_mask: Self::init_key_mask(table_size)
108 }
109 }
110
111 fn check_table_size(table_size: usize) -> usize {
112 const MASK_1: u64 = 0xffffffff00000000;
113 const MASK_2: u64 = 0xffff0000ffff0000;
114 const MASK_3: u64 = 0xff00ff00ff00ff00;
115 const MASK_4: u64 = 0xf0f0f0f0f0f0f0f0;
116 const MASK_5: u64 = 0xcccccccccccccccc;
117 const MASK_6: u64 = 0xaaaaaaaaaaaaaaaa;
118
119 macro_rules! core {
120 ($variable:expr, $mask:expr) => {
121 match $variable & $mask {
122 0u64 => $variable,
123 masked_variable => masked_variable
124 }
125 };
126 }
127
128 let size = table_size as u64;
129
130 let size = core!(size, MASK_1);
131 let size = core!(size, MASK_2);
132 let size = core!(size, MASK_3);
133 let size = core!(size, MASK_4);
134 let size = core!(size, MASK_5);
135 let size = core!(size, MASK_6);
136
137 match size as usize{
138 0 => 1usize,
139 ret => ret
140 }
141 }
142
143 fn init_key_table(table_size: usize) -> Vec<Vec<u64>> {
144 let mut ret = Vec::<Vec<u64>>::with_capacity(table_size);
145
146 for _ in 0..table_size {
147 ret.push(Vec::<u64>::new());
148 }
149
150 ret
151 }
152
153 fn init_value_table(table_size: usize) -> Vec<Vec<T>> {
154 let mut ret = Vec::<Vec<T>>::with_capacity(table_size);
155
156 for _ in 0..table_size {
157 ret.push(Vec::<T>::new());
158 }
159
160 ret
161 }
162
163 #[inline]
164 fn init_key_mask(table_size: usize) -> u64 {
165 (table_size as u64) - 1
166 }
167
168 /// Gets key-value table size.
169 ///
170 /// - _Return_ : Key-value table size.
171 #[inline]
172 pub fn table_size(&self) -> usize {self.key_table.len()}
173
174 #[inline]
175 fn get_index(&self, key: u64) -> Option<(usize, usize)> {
176 let table_index = (key & self.key_mask) as usize;
177
178 debug_assert!(self.key_table.get(table_index).is_some());
179
180 match (unsafe{
181 self.key_table.get_unchecked(table_index)
182 }).binary_search(&key) {
183 Ok(record_index) => Some((table_index, record_index)),
184
185 Err(..) => None
186 }
187 }
188
189
190 /// Gets a value by `key`.
191 ///
192 /// - `key` : A key of the value.
193 /// - _Return_ : If `key` exists, returns the value. Otherwise, returns `None`.
194 ///
195 /// ```ignore
196 /// use chobitlibs::chobit_map::ChobitMap;
197 ///
198 /// let mut map = ChobitMap::<i32>::new(200);
199 ///
200 /// let key_1: u64 = 111;
201 /// let value_1: i32 = 100;
202 ///
203 /// let key_2: u64 = 222;
204 /// let value_2: i32 = 200;
205 ///
206 /// let key_3: u64 = 333;
207 /// let value_3: i32 = 300;
208 ///
209 /// assert!(map.add(key_1, value_1).is_ok());
210 /// assert!(map.add(key_2, value_2).is_ok());
211 /// assert!(map.add(key_3, value_3).is_ok());
212 ///
213 /// assert_eq!(*map.get(key_1).unwrap(), value_1);
214 /// assert_eq!(*map.get(key_2).unwrap(), value_2);
215 /// assert_eq!(*map.get(key_3).unwrap(), value_3);
216 /// ```
217 #[inline]
218 pub fn get(&self, key: u64) -> Option<&T> {
219 let (table_index, record_index) = self.get_index(key)?;
220
221 debug_assert!(
222 &self.value_table
223 .get(table_index)
224 .unwrap()
225 .get(record_index)
226 .is_some()
227 );
228
229 Some(unsafe {
230 self.value_table
231 .get_unchecked(table_index)
232 .get_unchecked(record_index)
233 })
234 }
235
236 /// Gets a mutable value by `key`.
237 ///
238 /// - `key` : A key of the value.
239 /// - _Return_ : If `key` exists, returns the mutable value. Otherwise, returns `None`.
240 ///
241 /// ```ignore
242 /// use chobitlibs::chobit_map::ChobitMap;
243 ///
244 /// let mut map = ChobitMap::<i32>::new(200);
245 ///
246 /// let key_1: u64 = 111;
247 /// let value_1: i32 = 100;
248 ///
249 /// let key_2: u64 = 222;
250 /// let value_2: i32 = 200;
251 ///
252 /// let key_3: u64 = 333;
253 /// let value_3: i32 = 300;
254 ///
255 /// assert!(map.add(key_1, value_1).is_ok());
256 /// assert!(map.add(key_2, value_2).is_ok());
257 /// assert!(map.add(key_3, value_3).is_ok());
258 ///
259 /// assert_eq!(*map.get(key_1).unwrap(), value_1);
260 /// assert_eq!(*map.get(key_2).unwrap(), value_2);
261 /// assert_eq!(*map.get(key_3).unwrap(), value_3);
262 ///
263 /// let value_1_2: i32 = 1000;
264 /// let value_2_2: i32 = 2000;
265 /// let value_3_2: i32 = 3000;
266 ///
267 /// *map.get_mut(key_1).unwrap() = value_1_2;
268 /// *map.get_mut(key_2).unwrap() = value_2_2;
269 /// *map.get_mut(key_3).unwrap() = value_3_2;
270 ///
271 /// assert_eq!(*map.get(key_1).unwrap(), value_1_2);
272 /// assert_eq!(*map.get(key_2).unwrap(), value_2_2);
273 /// assert_eq!(*map.get(key_3).unwrap(), value_3_2);
274 /// ```
275 #[inline]
276 pub fn get_mut(&mut self, key: u64) -> Option<&mut T> {
277 let (table_index, record_index) = self.get_index(key)?;
278
279 debug_assert!(
280 &self.value_table
281 .get(table_index)
282 .unwrap()
283 .get(record_index)
284 .is_some()
285 );
286
287 Some(unsafe {
288 self.value_table
289 .get_unchecked_mut(table_index)
290 .get_unchecked_mut(record_index)
291 })
292 }
293
294 /// Adds a value.
295 ///
296 /// - `key` : A key of the value.
297 /// - `value` : A value that you want to put into `ChobitMap`.
298 /// - _Return_ : If the key is conflicted, returns error. Otherwise, returns the value.
299 ///
300 /// ```ignore
301 /// use chobitlibs::chobit_map::ChobitMap;
302 ///
303 /// let mut map = ChobitMap::<i32>::new(200);
304 ///
305 /// let key_1: u64 = 111;
306 /// let value_1: i32 = 100;
307 ///
308 /// let key_2: u64 = 222;
309 /// let value_2: i32 = 200;
310 ///
311 /// let key_3: u64 = 333;
312 /// let value_3: i32 = 300;
313 ///
314 /// assert!(map.add(key_1, value_1).is_ok());
315 /// assert!(map.add(key_2, value_2).is_ok());
316 /// assert!(map.add(key_3, value_3).is_ok());
317 ///
318 /// assert_eq!(*map.get(key_1).unwrap(), value_1);
319 /// assert_eq!(*map.get(key_2).unwrap(), value_2);
320 /// assert_eq!(*map.get(key_3).unwrap(), value_3);
321 /// ```
322 pub fn add(
323 &mut self,
324 key: u64,
325 value: T
326 ) -> Result<(), ChobitMapError> {
327 let table_index = (key & self.key_mask) as usize;
328
329 debug_assert!(self.key_table.get(table_index).is_some());
330 let key_vec = unsafe {self.key_table.get_unchecked_mut(table_index)};
331
332 match key_vec.binary_search(&key) {
333 Ok(..) => Err(ChobitMapError::AlreadyExists {key: key}),
334
335 Err(record_index) => {
336 key_vec.insert(record_index, key);
337
338 debug_assert!(self.value_table.get(table_index).is_some());
339 (unsafe {
340 self.value_table.get_unchecked_mut(table_index)
341 }).insert(record_index, value);
342
343 Ok(())
344 }
345 }
346 }
347
348 /// Removes a value.
349 ///
350 /// - `key` : A key of the value.
351 /// - _Return_ : If `key` exists, returns the value. Otherwise, returns error.
352 ///
353 /// ```ignore
354 /// use chobitlibs::chobit_map::ChobitMap;
355 ///
356 /// let mut map = ChobitMap::<i32>::new(200);
357 ///
358 /// let key_1: u64 = 111;
359 /// let value_1: i32 = 100;
360 ///
361 /// let key_2: u64 = 222;
362 /// let value_2: i32 = 200;
363 ///
364 /// let key_3: u64 = 333;
365 /// let value_3: i32 = 300;
366 ///
367 /// assert!(map.add(key_1, value_1).is_ok());
368 /// assert!(map.add(key_2, value_2).is_ok());
369 /// assert!(map.add(key_3, value_3).is_ok());
370 ///
371 /// assert_eq!(*map.get(key_1).unwrap(), value_1);
372 /// assert_eq!(*map.get(key_2).unwrap(), value_2);
373 /// assert_eq!(*map.get(key_3).unwrap(), value_3);
374 ///
375 /// assert_eq!(map.remove(key_1).unwrap(), value_1);
376 /// assert_eq!(map.remove(key_2).unwrap(), value_2);
377 /// assert_eq!(map.remove(key_3).unwrap(), value_3);
378 ///
379 /// assert!(map.get(key_1).is_none());
380 /// assert!(map.get(key_2).is_none());
381 /// assert!(map.get(key_3).is_none());
382 /// ```
383 pub fn remove(&mut self, key: u64) -> Result<T, ChobitMapError> {
384 let table_index = (key & self.key_mask) as usize;
385
386 debug_assert!(self.key_table.get(table_index).is_some());
387 let key_vec = unsafe {self.key_table.get_unchecked_mut(table_index)};
388
389 match key_vec.binary_search(&key) {
390 Ok(record_index) => {
391 key_vec.remove(record_index);
392
393 debug_assert!(self.value_table.get(table_index).is_some());
394 Ok((unsafe {
395 self.value_table.get_unchecked_mut(table_index)
396 }).remove(record_index))
397 },
398
399 Err(..) => Err(ChobitMapError::NotFound {key: key})
400 }
401 }
402
403 /// Makes a iterator.
404 ///
405 /// - _Return_ : A iterator of `ChobitMap`.
406 ///
407 /// ```ignore
408 /// use chobitlibs::chobit_map::ChobitMap;
409 ///
410 /// let mut map = ChobitMap::<i32>::new(200);
411 ///
412 /// let key_1: u64 = 1;
413 /// let value_1: i32 = 100;
414 ///
415 /// let key_2: u64 = 2;
416 /// let value_2: i32 = 200;
417 ///
418 /// let key_3: u64 = 3;
419 /// let value_3: i32 = 300;
420 ///
421 /// assert!(map.add(key_1, value_1).is_ok());
422 /// assert!(map.add(key_2, value_2).is_ok());
423 /// assert!(map.add(key_3, value_3).is_ok());
424 ///
425 /// let mut iter = map.iter();
426 ///
427 /// assert_eq!(iter.next().unwrap(), (key_1, &value_1));
428 /// assert_eq!(iter.next().unwrap(), (key_2, &value_2));
429 /// assert_eq!(iter.next().unwrap(), (key_3, &value_3));
430 /// assert!(iter.next().is_none());
431 /// ```
432 pub fn iter(&self) -> Iter<'_, T> {
433 Iter::<'_, T> {
434 key_table_iter: self.key_table.iter(),
435 value_table_iter: self.value_table.iter(),
436
437 key_record_iter: None,
438 value_record_iter: None
439 }
440 }
441}
442
443/// A iterator of `ChobitMap`.
444pub struct Iter<'a, T> {
445 key_table_iter: SIter<'a, Vec<u64>>,
446 value_table_iter: SIter<'a, Vec<T>>,
447
448 key_record_iter: Option<SIter<'a, u64>>,
449 value_record_iter: Option<SIter<'a, T>>
450}
451
452impl <'a, T> Iterator for Iter<'a, T> {
453 type Item = (u64, &'a T);
454
455 fn next(&mut self) -> Option<(u64, &'a T)> {
456 match &mut self.key_record_iter {
457 Some(key_record_iter) => match &key_record_iter.next() {
458 Some(key) => Some((
459 **key,
460 self.value_record_iter.as_mut().unwrap().next().unwrap()
461 )),
462
463 None => {
464 self.key_record_iter = None;
465 self.value_record_iter = None;
466
467 self.next()
468 }
469 },
470
471 None => {
472 self.key_record_iter =
473 Some(self.key_table_iter.next()?.iter());
474 self.value_record_iter =
475 Some(self.value_table_iter.next()?.iter());
476
477 self.next()
478 }
479 }
480 }
481}