Skip to main content

sudachi/dic/lexicon/
word_params.rs

1/*
2 * Copyright (c) 2021-2026 Works Applications Co., Ltd.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17use crate::dic::word_id::EntryId;
18use crate::util::cow_array::CowArray;
19
20/// A word paratemter, used in the analysis.
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22#[repr(transparent)]
23pub struct WordParameter(u64);
24
25impl WordParameter {
26    /// The left connection cost id.
27    #[inline]
28    pub fn left_id(&self) -> i16 {
29        (self.0 & 0xffff) as i16
30    }
31
32    /// The right connection cost id.
33    #[inline]
34    pub fn right_id(&self) -> i16 {
35        ((self.0 >> 16) & 0xffff) as i16
36    }
37
38    /// The cost of the word.
39    #[inline]
40    pub fn cost(&self) -> i16 {
41        ((self.0 >> 32) & 0xffff) as i16
42    }
43
44    /// Return a new parameters with the given cost.
45    #[inline]
46    pub fn with_cost(&self, cost: i16) -> WordParameter {
47        WordParameter((cost as u64) << 32 | (self.0 & 0xffffffff))
48    }
49}
50
51pub struct WordParams<'a> {
52    // word parameters are placed at the beginning of eash word info and word infos are aligned per 8 bytes (see WordInfos::WORD_INFO_OFFSET_ALIGNMENT).
53    // Thus handling this block as u64 array is safe.
54    data: CowArray<'a, u64>,
55}
56
57impl<'a> WordParams<'a> {
58    pub fn from_bytes(bytes: &'a [u8]) -> WordParams<'a> {
59        Self {
60            data: CowArray::from_bytes(bytes, 0, bytes.len() / std::mem::size_of::<u64>()),
61        }
62    }
63
64    #[inline]
65    pub fn get_params(&self, entry_id: EntryId) -> WordParameter {
66        // offset in u64 array equals to the byte_offset >> 3, and byte_offset in V1 format is entry_id << 3.
67        // Thus we can skip conversion
68        let offset = entry_id.as_raw() as usize;
69        WordParameter(self.data[offset])
70    }
71
72    #[inline]
73    pub fn get_params_checked(&self, entry_id: EntryId) -> Option<WordParameter> {
74        let offset = entry_id.as_raw() as usize;
75        self.data.get(offset).copied().map(WordParameter)
76    }
77
78    #[inline]
79    pub fn get_cost(&self, entry_id: EntryId) -> i16 {
80        self.get_params(entry_id).cost()
81    }
82
83    pub fn set_cost(&mut self, entry_id: EntryId, cost: i16) {
84        let offset = entry_id.as_raw() as usize;
85        let params = self.get_params(entry_id);
86        self.data.set(offset, params.with_cost(cost).0);
87    }
88}