xdb_parse/
xdb.rs

1use std::{
2    fmt::Debug,
3    net::{IpAddr, Ipv4Addr, Ipv6Addr},
4    ops::{Deref, DerefMut}, str::FromStr,
5};
6
7use crate::{VECTOR_ROW_SIZE, error::XdbError};
8
9///Header
10#[derive(Debug, Default)]
11pub struct Header {
12    pub xdb_version: u16,
13    pub cache_type: u16,
14    pub generat_time: u32,
15    pub index_base_address: u32,
16    pub index_end_address: u32,
17}
18
19impl Header {
20    pub fn new() -> Self {
21        Header {
22            xdb_version: 0,
23            cache_type: 0,
24            generat_time: 0,
25            index_base_address: 0,
26            index_end_address: 0,
27        }
28    }
29    pub fn try_parse(data: &[u8]) -> Result<Self, XdbError> {
30        Ok(Header {
31            xdb_version: u16::from_ne_bytes(data[0..2].try_into()?),
32            cache_type: u16::from_ne_bytes(data[2..4].try_into()?),
33            generat_time: u32::from_ne_bytes(data[4..8].try_into()?),
34            index_base_address: u32::from_ne_bytes(data[8..12].try_into()?),
35            index_end_address: u32::from_ne_bytes(data[12..16].try_into()?),
36        })
37    }
38}
39
40///VectorIndex block struct
41#[derive(Debug, Default)]
42pub struct IndexBlock {
43    pub index_start_address: u32,
44    pub index_end_address: u32,
45}
46
47impl IndexBlock {
48    pub fn new() -> Self {
49        IndexBlock {
50            index_start_address: 0,
51            index_end_address: 0,
52        }
53    }
54    pub fn try_parse(data: &[u8]) -> Result<Self, XdbError> {
55        Ok(IndexBlock {
56            index_start_address: u32::from_ne_bytes(data[0..4].try_into()?),
57            index_end_address: u32::from_ne_bytes(data[4..8].try_into()?),
58        })
59    }
60}
61
62///Vector index segment struct
63#[derive(Debug, Default)]
64pub struct VectorIndex(pub Vec<IndexBlock>);
65
66impl VectorIndex {
67    pub fn new() -> Self {
68        VectorIndex(Vec::with_capacity(VECTOR_ROW_SIZE * VECTOR_ROW_SIZE))
69    }
70    pub fn try_parse(data: &[u8]) -> Result<Self, XdbError> {
71        let mut vec_index = VectorIndex::new();
72        for i in 0..(VECTOR_ROW_SIZE * VECTOR_ROW_SIZE) {
73            //parse each index block , everyone is 8 bytes
74            let start = i * 8;
75            let end = start + 8;
76            let index_block = IndexBlock::try_parse(&data[start..end])?;
77            vec_index.push(index_block);
78        }
79        Ok(vec_index)
80    }
81}
82
83impl Deref for VectorIndex {
84    type Target = Vec<IndexBlock>;
85    fn deref(&self) -> &Self::Target {
86        &self.0
87    }
88}
89impl DerefMut for VectorIndex {
90    fn deref_mut(&mut self) -> &mut Self::Target {
91        &mut self.0
92    }
93}
94
95///Binary index segment struct
96#[derive(Default)]
97pub struct SegmentIndex<T: FromLeBytes> {
98    pub ip_start: T,
99    pub ip_end: T,
100    pub data_len: u16,
101    pub data_ptr: u32,
102}
103
104impl<T> SegmentIndex<T>
105where
106    T: Default + Debug + FromLeBytes,
107{
108    pub fn new() -> Self {
109        SegmentIndex {
110            ip_start: T::default(),
111            ip_end: T::default(),
112            data_len: 0,
113            data_ptr: 0,
114        }
115    }
116    pub fn try_parse(data: &[u8]) -> Result<Self, XdbError> {
117        let size_of_val = size_of::<T>();
118        Ok(SegmentIndex {
119            ip_start: T::from_le_bytes(data[0..size_of_val].try_into()?)?,
120            ip_end: T::from_le_bytes(data[size_of_val..size_of_val * 2].try_into()?)?,
121            data_len: u16::from_ne_bytes(
122                data[(size_of_val * 2)..(size_of_val * 2) + 2].try_into()?,
123            ),
124            data_ptr: u32::from_ne_bytes(
125                data[(size_of_val * 2) + 2..((size_of_val * 2) + 2) + 4].try_into()?,
126            ),
127        })
128    }
129}
130
131impl std::fmt::Debug for SegmentIndex<u32> {
132    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133        write!(
134            f,
135            "ip_start:{}, ip_end:{}, data_len:{}, data_ptr:{}",
136            IpAddr::V4(Ipv4Addr::from(self.ip_start)).to_string(),
137            IpAddr::V4(Ipv4Addr::from(self.ip_end)).to_string(),
138            self.data_len,
139            self.data_ptr
140        )
141    }
142}
143
144impl std::fmt::Debug for SegmentIndex<u128> {
145    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146        write!(
147            f,
148            "ip_start:{}, ip_end:{}, data_len:{}, data_ptr:{}",
149            IpAddr::V6(Ipv6Addr::from(self.ip_start)).to_string(),
150            IpAddr::V6(Ipv6Addr::from(self.ip_end)).to_string(),
151            self.data_len,
152            self.data_ptr
153        )
154    }
155}
156
157pub trait FromLeBytes: Sized {
158    fn from_le_bytes(bytes: &[u8]) -> Result<Self, XdbError>;
159}
160
161impl FromLeBytes for u32 {
162    fn from_le_bytes(bytes: &[u8]) -> Result<Self, XdbError> {
163        Ok(u32::from_ne_bytes(bytes.try_into()?))
164    }
165}
166
167impl FromLeBytes for u128 {
168    fn from_le_bytes(bytes: &[u8]) -> Result<Self, XdbError> {
169        Ok(u128::from_ne_bytes(bytes.try_into()?))
170    }
171}
172
173pub trait ToUSizeIp{
174    fn to_usize_ip(&self) -> Result<u128, XdbError>;
175}
176impl ToUSizeIp for Ipv4Addr {
177    fn to_usize_ip(&self) -> Result<u128,XdbError> {
178        Ok(u32::from(*self) as u128)
179    }
180}
181
182impl ToUSizeIp for &str {
183    fn to_usize_ip(&self) -> Result<u128, XdbError> {
184        // 优先尝试解析 IPv6
185        if let Ok(ipv6) = Ipv6Addr::from_str(self) {
186            return Ok(u128::from(ipv6));
187        }
188        // 再尝试解析 IPv4
189        if let Ok(ipv4) = Ipv4Addr::from_str(self) {
190            return Ok(u32::from(ipv4) as u128);
191        }
192        // 最后直接解析数字
193        Ok(self.parse::<u128>()?)
194    }
195}
196
197
198#[cfg(test)]
199mod tests {
200    use std::net::Ipv4Addr;
201
202    use anyhow::Result;
203    #[test]
204    fn test_parse_ip_and_calculate_index() -> Result<()> {
205        /*
206            Index: 152552
207            il0: 74, il1: 125
208            ip: 1249717091        
209         */
210        // let ip = "2001:0db8:85a3:0000:0000:8a2e:0370:7334".to_usize_ip().unwrap();
211        let ip = "74.125.43.99".parse::<Ipv4Addr>()?.to_bits();
212        let il0 = ((ip >> 24) & 0xFF) as usize;
213        let il1 = ((ip >> 16) & 0xFF) as usize;
214        let idx = il0 * 256 * 8 + il1 * 8;
215        println!("Index: {}", idx);
216        println!("il0: {}, il1: {}", il0, il1);
217        println!("ip: {}", ip);
218        Ok(())
219    }
220}