1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! helpers and type for the HAMT bitmap
//!
//! The bitmap map a index into the sparse array index
//!
//! The number of bits set represent the number of elements
//! currently present in the array
//!
//! e.g for the following elements and their indices:
//!
//! ```text
//!     [ (0b0010_0000, x) ]
//! ```
//!
//! will map into this bitmap:
//!
//! ```text
//!     0b0010_0000 (1 bit set)
//! ```
//!
//! and a vector of 1 element containing x
//!
//! ```text
//!     | x |
//! ```
//!
//! or the following elements and their indices:
//!
//! ```text
//!     [ (0b0010_0000, x), (0b1000_0000, y), (0b0000_0010, z) ]
//! ```
//!
//! will map into this bitmap:
//!
//! ```text
//!     0b1010_0010 (3 bit set)
//! ```
//!
//! and a vector of 3 elements containing x, y, z in the following order:
//!
//! ```text
//!     | z | x | y |
//! ```
//!
//!

use super::hash::LevelIndex;
use std::fmt;

/// This is a node size bitmap to allow to find element
/// in the node's array
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct SmallBitmap(u32);

impl fmt::Debug for SmallBitmap {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "SmallBitmap {:032b}", self.0)
    }
}

impl SmallBitmap {
    /// Create a new bitmap with no element
    pub const fn new() -> Self {
        SmallBitmap(0u32)
    }

    #[inline]
    pub fn is_empty(self) -> bool {
        self.0 == 0
    }

    #[inline]
    pub fn present(self) -> usize {
        self.0.count_ones() as usize
    }

    #[inline]
    /// Create a new bitmap with 1 element set
    pub const fn once(b: LevelIndex) -> Self {
        SmallBitmap(b.mask())
    }

    /// Get the sparse array index from a level index
    #[inline]
    pub fn get_index_sparse(self, b: LevelIndex) -> ArrayIndex {
        let mask = b.mask();
        if self.0 & mask == 0 {
            ArrayIndex::not_found()
        } else {
            ArrayIndex::create((self.0 & (mask - 1)).count_ones() as usize)
        }
    }

    /// Get the position of a level index in the sparse array for insertion
    #[inline]
    pub fn get_sparse_pos(self, b: LevelIndex) -> ArrayIndex {
        let mask = b.mask();
        ArrayIndex::create((self.0 & (mask - 1)).count_ones() as usize)
    }

    /// Check if the element exist
    pub fn is_set(self, b: LevelIndex) -> bool {
        (self.0 & b.mask()) != 0
    }

    #[inline]
    pub fn set_index(self, b: LevelIndex) -> Self {
        SmallBitmap(self.0 | b.mask())
    }
    #[inline]
    pub fn clear_index(self, b: LevelIndex) -> Self {
        SmallBitmap(self.0 & !b.mask())
    }
}

/// Sparse index in the array.
///
/// The array elements are allocated on demand,
/// and their presence is indicated by the bitmap
#[derive(Debug, Clone, Copy)]
pub struct ArrayIndex(usize);

impl ArrayIndex {
    pub fn is_not_found(self) -> bool {
        self.0 == 0xff
    }

    pub fn get_found(self) -> usize {
        assert!(!self.is_not_found());
        self.0
    }

    pub fn not_found() -> Self {
        ArrayIndex(0xff)
    }

    pub fn create(s: usize) -> Self {
        ArrayIndex(s)
    }
}