sudachi/dic/lexicon/
word_id_table.rs1use std::iter::FusedIterator;
18use std::ptr::NonNull;
19
20pub struct WordIdTable<'a> {
21    bytes: &'a [u8],
22    size: u32,
23    offset: usize,
24}
25
26impl<'a> WordIdTable<'a> {
27    pub fn new(bytes: &'a [u8], size: u32, offset: usize) -> WordIdTable {
28        WordIdTable {
29            bytes,
30            size,
31            offset,
32        }
33    }
34
35    pub fn storage_size(&self) -> usize {
36        4 + self.size as usize
37    }
38
39    #[inline]
40    pub fn entries(&self, index: usize) -> WordIdIter {
41        debug_assert!(index < self.bytes.len());
42        let ptr = unsafe { self.bytes.as_ptr().add(index + self.offset) };
43        let cnt = unsafe { ptr.read() } as usize;
44        let data_ptr = unsafe { ptr.offset(1) } as *const u32;
45        debug_assert!(index + cnt * std::mem::size_of::<u32>() < self.bytes.len());
46        WordIdIter {
47            data: unsafe { NonNull::new_unchecked(data_ptr as _) },
48            remaining: cnt,
49        }
50    }
51}
52
53pub struct WordIdIter {
54    data: NonNull<u32>,
57    remaining: usize,
59}
60
61impl Iterator for WordIdIter {
62    type Item = u32;
63
64    #[inline]
65    fn next(&mut self) -> Option<Self::Item> {
66        if self.remaining == 0 {
67            return None;
68        }
69        let ptr = self.data.as_ptr();
70
71        let val = unsafe { ptr.read_unaligned() };
72        self.data = unsafe { NonNull::new_unchecked(ptr.offset(1)) };
73        self.remaining -= 1;
74        Some(val)
75    }
76}
77
78impl FusedIterator for WordIdIter {}