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}