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
use core::ptr;
use super::helpers;

#[allow(dead_code)]
pub struct HashMap<const KEY_SIZE: usize, const VALUE_SIZE: usize, const MAX_ENTRIES: usize> {
    ty__: *mut [u32; 1],
    key_size: *mut [u32; KEY_SIZE],
    value_size: *mut [u32; VALUE_SIZE],
    max_entries: *mut [u32; MAX_ENTRIES],
}

impl<const K: usize, const V: usize, const M: usize> HashMap<K, V, M> {
    pub const fn new() -> Self {
        HashMap {
            ty__: ptr::null_mut(),
            key_size: ptr::null_mut(),
            value_size: ptr::null_mut(),
            max_entries: ptr::null_mut(),
        }
    }
}

pub struct HashMapRef<const K: usize, const V: usize> {
    inner: usize,
}

impl<const K: usize, const V: usize> HashMapRef<K, V> {
    #[inline(always)]
    pub fn new<const M: usize>(inner: &mut HashMap<K, V, M>) -> Self {
        HashMapRef {
            inner: inner as *mut _ as usize,
        }
    }

    #[inline(always)]
    fn inner(&self) -> *mut cty::c_void {
        self.inner as *mut _
    }

    #[inline(always)]
    pub fn insert(&mut self, key: [u8; K], value: [u8; V]) -> Result<(), i32> {
        let c = unsafe {
            helpers::map_update_elem(
                self.inner(),
                key.as_ptr() as _,
                value.as_ptr() as _,
                0,
            )
        };
        if c >= 0 {
            Ok(())
        } else {
            Err(c as _)
        }
    }

    #[inline(always)]
    pub fn get(&self, key: &[u8; K]) -> Option<&[u8; V]> {
        unsafe {
            let v = helpers::map_lookup_elem(self.inner(), key.as_ptr() as _);
            if v.is_null() {
                None
            } else {
                Some(&*(v as *const [u8; V]))
            }
        }
    }

    #[inline(always)]
    pub fn get_mut(&mut self, key: &[u8; K]) -> Option<&mut [u8; V]> {
        unsafe {
            let v = helpers::map_lookup_elem(self.inner(), key.as_ptr() as _);
            if v.is_null() {
                None
            } else {
                Some(&mut *(v as *mut [u8; V]))
            }
        }
    }

    #[inline(always)]
    pub fn remove(&mut self, key: &[u8; K]) -> Result<Option<[u8; V]>, i32> {
        match self.get(key) {
            Some(v) => {
                let c = unsafe {
                    helpers::map_delete_elem(self.inner(), key.as_ptr() as _)
                };
                if c >= 0 {
                    Ok(Some(v.clone()))
                } else {
                    Err(c as _)
                }
            },
            None => Ok(None),
        }
    }
}