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#[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#[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#[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 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#[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 if let Ok(ipv6) = Ipv6Addr::from_str(self) {
186 return Ok(u128::from(ipv6));
187 }
188 if let Ok(ipv4) = Ipv4Addr::from_str(self) {
190 return Ok(u32::from(ipv4) as u128);
191 }
192 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 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}