taos_query/common/raw/views/
big_int_unsigned_view.rs1use std::ffi::c_void;
2
3use crate::common::{BorrowedValue, Ty};
4
5use super::{IsColumnView, NullBits, NullsIter};
6
7use bytes::Bytes;
8
9#[derive(Debug, Clone)]
10pub struct UBigIntView {
11 pub(crate) nulls: NullBits,
12 pub(crate) data: Bytes,
13}
14
15type Item = u64;
16type View = UBigIntView;
17const ITEM_SIZE: usize = std::mem::size_of::<Item>();
18
19impl IsColumnView for View {
20 fn ty(&self) -> Ty {
21 Ty::UBigInt
22 }
23 fn from_borrowed_value_iter<'b>(iter: impl Iterator<Item = BorrowedValue<'b>>) -> Self {
24 Self::from_iter(iter.map(|v| v.to_u64()))
25 }
26}
27
28impl std::ops::Add for View {
29 type Output = Self;
30
31 fn add(self, rhs: Self) -> Self::Output {
32 &self + &rhs
33 }
34}
35impl std::ops::Add for &View {
36 type Output = View;
37
38 fn add(self, rhs: Self) -> Self::Output {
39 let nulls = NullBits::from_iter(
40 self.nulls
41 .iter()
42 .take(self.len())
43 .chain(rhs.nulls.iter().take(rhs.len())),
44 );
45 let data: Bytes = self
46 .data
47 .as_ref()
48 .iter()
49 .chain(rhs.data.as_ref().iter())
50 .copied()
51 .collect();
52
53 View { nulls, data }
54 }
55}
56
57impl std::ops::Add<View> for &View {
58 type Output = View;
59
60 fn add(self, rhs: View) -> Self::Output {
61 self + &rhs
62 }
63}
64
65impl std::ops::Add<&View> for View {
66 type Output = View;
67
68 fn add(self, rhs: &View) -> Self::Output {
69 &self + rhs
70 }
71}
72
73impl UBigIntView {
74 pub fn len(&self) -> usize {
76 self.data.len() / std::mem::size_of::<Item>()
77 }
78
79 pub fn as_raw_slice(&self) -> &[Item] {
81 unsafe { std::slice::from_raw_parts(self.data.as_ptr() as *const Item, self.len()) }
82 }
83
84 pub fn as_raw_ptr(&self) -> *const Item {
86 self.data.as_ptr() as *const Item
87 }
88
89 pub fn to_nulls_vec(&self) -> Vec<bool> {
91 self.is_null_iter().collect()
92 }
93
94 pub fn is_null_iter(&self) -> NullsIter {
96 NullsIter {
97 nulls: &self.nulls,
98 row: 0,
99 len: self.len(),
100 }
101 }
102
103 pub fn is_null(&self, row: usize) -> bool {
105 if row < self.len() {
106 unsafe { self.is_null_unchecked(row) }
107 } else {
108 false
109 }
110 }
111
112 pub unsafe fn is_null_unchecked(&self, row: usize) -> bool {
114 self.nulls.is_null_unchecked(row)
115 }
116
117 pub fn get(&self, row: usize) -> Option<Item> {
119 if row < self.len() {
120 unsafe { self.get_unchecked(row) }
121 } else {
122 None
123 }
124 }
125
126 #[inline(always)]
127 unsafe fn get_raw_at(&self, index: usize) -> *const Item {
128 self.data.as_ptr().add(index * ITEM_SIZE) as _
129 }
130
131 pub unsafe fn get_unchecked(&self, row: usize) -> Option<Item> {
133 if self.nulls.is_null_unchecked(row) {
134 None
135 } else {
136 Some(self.get_raw_at(row).read_unaligned())
137 }
138 }
139
140 pub unsafe fn get_ref_unchecked(&self, row: usize) -> Option<*const Item> {
141 if self.nulls.is_null_unchecked(row) {
142 None
143 } else {
144 Some(self.get_raw_at(row))
145 }
146 }
147
148 pub unsafe fn get_value_unchecked(&self, row: usize) -> BorrowedValue {
149 self.get_unchecked(row)
150 .map(BorrowedValue::UBigInt)
151 .unwrap_or(BorrowedValue::Null(Ty::UBigInt))
152 }
153
154 pub unsafe fn get_raw_value_unchecked(&self, row: usize) -> (Ty, u32, *const c_void) {
155 if self.nulls.is_null_unchecked(row) {
156 (
157 Ty::UBigInt,
158 std::mem::size_of::<Item>() as _,
159 std::ptr::null(),
160 )
161 } else {
162 (
163 Ty::UBigInt,
164 std::mem::size_of::<Item>() as _,
165 self.get_raw_at(row) as *const Item as _,
166 )
167 }
168 }
169
170 pub fn slice(&self, mut range: std::ops::Range<usize>) -> Option<Self> {
172 if range.start >= self.len() {
173 return None;
174 }
175 if range.end >= self.len() {
176 range.end = self.len();
177 }
178 if range.is_empty() {
179 return None;
180 }
181
182 let nulls = unsafe { self.nulls.slice(range.clone()) };
183 let data = self
184 .data
185 .slice(range.start * ITEM_SIZE..range.end * ITEM_SIZE);
186 Some(Self { nulls, data })
187 }
188
189 pub fn iter(&self) -> UBigIntViewIter {
191 UBigIntViewIter { view: self, row: 0 }
192 }
193
194 pub fn to_vec(&self) -> Vec<Option<Item>> {
196 self.iter().collect()
197 }
198
199 pub(crate) fn write_raw_into<W: std::io::Write>(&self, mut wtr: W) -> std::io::Result<usize> {
201 let nulls = self.nulls.0.as_ref();
202 debug_assert_eq!(nulls.len(), (self.len() + 7) / 8);
203 wtr.write_all(nulls)?;
204 wtr.write_all(&self.data)?;
205 Ok(nulls.len() + self.data.len())
206 }
207
208 pub fn concat(&self, rhs: &View) -> View {
209 let nulls = NullBits::from_iter(
210 self.nulls
211 .iter()
212 .take(self.len())
213 .chain(rhs.nulls.iter().take(rhs.len())),
214 );
215 let data: Bytes = self
216 .data
217 .as_ref()
218 .iter()
219 .chain(rhs.data.as_ref().iter())
220 .copied()
221 .collect();
222
223 View { nulls, data }
224 }
225}
226
227pub struct UBigIntViewIter<'a> {
228 view: &'a UBigIntView,
229 row: usize,
230}
231
232impl<'a> Iterator for UBigIntViewIter<'a> {
233 type Item = Option<Item>;
234
235 fn next(&mut self) -> Option<Self::Item> {
236 if self.row < self.view.len() {
237 let row = self.row;
238 self.row += 1;
239 Some(unsafe { self.view.get_unchecked(row) })
240 } else {
241 None
242 }
243 }
244
245 #[inline]
246 fn size_hint(&self) -> (usize, Option<usize>) {
247 if self.row < self.view.len() {
248 let len = self.view.len() - self.row;
249 (len, Some(len))
250 } else {
251 (0, Some(0))
252 }
253 }
254}
255
256impl<'a> ExactSizeIterator for UBigIntViewIter<'a> {
257 fn len(&self) -> usize {
258 self.view.len() - self.row
259 }
260}
261
262impl<A: Into<Option<Item>>> FromIterator<A> for UBigIntView {
263 fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
264 let (nulls, mut values): (Vec<bool>, Vec<_>) = iter
265 .into_iter()
266 .map(|v| match v.into() {
267 Some(v) => (false, v),
268 None => (true, Item::default()),
269 })
270 .unzip();
271 Self {
272 nulls: NullBits::from_iter(nulls),
273 data: Bytes::from({
274 let (ptr, len, cap) = (values.as_mut_ptr(), values.len(), values.capacity());
275 std::mem::forget(values);
276 unsafe { Vec::from_raw_parts(ptr as *mut u8, len * ITEM_SIZE, cap * ITEM_SIZE) }
277 }),
278 }
279 }
280}
281
282#[test]
283fn test_slice() {
284 let data = [0, 1, Item::MIN, Item::MAX];
285 let view = UBigIntView::from_iter(data);
286 dbg!(&view);
287 let slice = view.slice(1..3);
288 dbg!(&slice);
289
290 let data = [None, Some(Item::MIN), Some(Item::MAX), None];
291 let view = UBigIntView::from_iter(data);
292 dbg!(&view);
293 let range = 1..4;
294 let slice = view.slice(range.clone()).unwrap();
295 for (v, i) in slice.iter().zip(range) {
296 assert_eq!(v, data[i]);
297 }
298}