taos_query/common/raw/views/
json_view.rs1use std::{ffi::c_void, fmt::Debug};
2
3use super::{IsColumnView, Offsets};
4use crate::{
5 common::{BorrowedValue, Ty},
6 prelude::InlinableWrite,
7 util::InlineJson,
8};
9
10use bytes::Bytes;
11use itertools::Itertools;
12
13#[derive(Debug, Clone)]
14pub struct JsonView {
15 pub offsets: Offsets,
17 pub data: Bytes,
18}
19
20type View = JsonView;
21
22impl IsColumnView for View {
23 fn ty(&self) -> Ty {
24 Ty::Json
25 }
26 fn from_borrowed_value_iter<'b>(iter: impl Iterator<Item = BorrowedValue<'b>>) -> Self {
27 Self::from_iter::<String, _, _, _>(
28 iter.map(|v| v.to_str().map(|v| v.into_owned()))
29 .collect_vec(),
30 )
31 }
32}
33
34impl JsonView {
35 pub fn len(&self) -> usize {
36 self.offsets.len()
37 }
38
39 pub fn is_null(&self, row: usize) -> bool {
41 if row < self.len() {
42 unsafe { self.is_null_unchecked(row) }
43 } else {
44 false
45 }
46 }
47
48 pub unsafe fn is_null_unchecked(&self, row: usize) -> bool {
50 self.offsets.get_unchecked(row) < 0
51 }
52
53 pub unsafe fn get_unchecked(&self, row: usize) -> Option<&InlineJson> {
54 let offset = self.offsets.get_unchecked(row);
55 if offset >= 0 {
56 Some(InlineJson::<u16>::from_ptr(
57 self.data.as_ptr().offset(offset as isize),
58 ))
59 } else {
60 None
61 }
62 }
63
64 pub unsafe fn get_value_unchecked(&self, row: usize) -> BorrowedValue {
65 self.get_unchecked(row)
67 .map(|s| BorrowedValue::Json(s.as_bytes().into()))
68 .unwrap_or(BorrowedValue::Null(Ty::Json))
69 }
70
71 pub unsafe fn get_raw_value_unchecked(&self, row: usize) -> (Ty, u32, *const c_void) {
72 match self.get_unchecked(row) {
73 Some(json) => (Ty::Json, json.len() as _, json.as_ptr() as _),
74 None => (Ty::Json, 0, std::ptr::null()),
75 }
76 }
77
78 #[inline]
79 pub unsafe fn get_length_unchecked(&self, row: usize) -> Option<usize> {
80 let offset = self.offsets.get_unchecked(row);
81 if offset >= 0 {
82 Some(InlineJson::<u16>::from_ptr(self.data.as_ptr().offset(offset as isize)).len())
83 } else {
84 None
85 }
86 }
87
88 #[inline]
89 pub fn lengths(&self) -> Vec<Option<usize>> {
90 (0..self.len())
91 .map(|i| unsafe { self.get_length_unchecked(i) })
92 .collect()
93 }
94
95 #[inline]
96 pub fn max_length(&self) -> usize {
97 (0..self.len())
98 .filter_map(|i| unsafe { self.get_length_unchecked(i) })
99 .min()
100 .unwrap_or(0)
101 }
102
103 pub fn slice(&self, mut range: std::ops::Range<usize>) -> Option<Self> {
104 if range.start >= self.len() {
105 return None;
106 }
107 if range.end > self.len() {
108 range.end = self.len();
109 }
110 if range.is_empty() {
111 return None;
112 }
113 let (offsets, range) = unsafe { self.offsets.slice_unchecked(range.clone()) };
114 if let Some(range) = range {
115 let range = range.0 as usize..range.1.map(|v| v as usize).unwrap_or(self.data.len());
116 let data = self.data.slice(range);
117 Some(Self { offsets, data })
118 } else {
119 let data = self.data.slice(0..0);
120 Some(Self { offsets, data })
121 }
122 }
123
124 pub fn iter(&self) -> VarCharIter {
125 VarCharIter { view: self, row: 0 }
126 }
127
128 pub fn to_vec(&self) -> Vec<Option<String>> {
129 (0..self.len())
130 .map(|row| unsafe { self.get_unchecked(row) }.map(|s| s.to_string()))
131 .collect()
132 }
133
134 pub(crate) fn write_raw_into<W: std::io::Write>(&self, mut wtr: W) -> std::io::Result<usize> {
136 let mut offsets = Vec::new();
137 let mut bytes: Vec<u8> = Vec::new();
138 for v in self.iter() {
139 if let Some(v) = v {
140 offsets.push(bytes.len() as i32);
141 bytes.write_inlined_str::<2>(v.as_str()).unwrap();
142 } else {
143 offsets.push(-1);
144 }
145 }
146 unsafe {
147 let offsets_bytes = std::slice::from_raw_parts(
149 offsets.as_ptr() as *const u8,
150 offsets.len() * std::mem::size_of::<i32>(),
151 );
152 wtr.write_all(offsets_bytes)?;
153 wtr.write_all(&bytes)?;
154 Ok(offsets_bytes.len() + bytes.len())
155 }
156 }
161
162 pub fn from_iter<
163 S: AsRef<str>,
164 T: Into<Option<S>>,
165 I: ExactSizeIterator<Item = T>,
166 V: IntoIterator<Item = T, IntoIter = I>,
167 >(
168 iter: V,
169 ) -> Self {
170 let iter = iter.into_iter();
171 let mut offsets = Vec::with_capacity(iter.len());
172 let mut data = Vec::new();
173
174 for i in iter.map(|v| v.into()) {
175 if let Some(s) = i {
176 let s: &str = s.as_ref();
177 offsets.push(data.len() as i32);
178 data.write_inlined_str::<2>(s).unwrap();
179 } else {
180 offsets.push(-1);
181 }
182 }
183 let offsets_bytes = unsafe {
185 Vec::from_raw_parts(
186 offsets.as_mut_ptr() as *mut u8,
187 offsets.len() * 4,
188 offsets.capacity() * 4,
189 )
190 };
191 std::mem::forget(offsets);
192 Self {
193 offsets: Offsets(offsets_bytes.into()),
194 data: data.into(),
195 }
196 }
197
198 pub fn concat(&self, rhs: &Self) -> Self {
199 Self::from_iter::<&InlineJson, _, _, _>(self.iter().chain(rhs.iter()).collect_vec())
200 }
201}
202
203pub struct VarCharIter<'a> {
204 view: &'a JsonView,
205 row: usize,
206}
207
208impl<'a> Iterator for VarCharIter<'a> {
209 type Item = Option<&'a InlineJson>;
210
211 fn next(&mut self) -> Option<Self::Item> {
212 if self.row < self.view.len() {
213 let row = self.row;
214 self.row += 1;
215 Some(unsafe { self.view.get_unchecked(row) })
216 } else {
217 None
218 }
219 }
220
221 #[inline]
222 fn size_hint(&self) -> (usize, Option<usize>) {
223 if self.row < self.view.len() {
224 let len = self.view.len() - self.row;
225 (len, Some(len))
226 } else {
227 (0, Some(0))
228 }
229 }
230}
231
232impl<'a> ExactSizeIterator for VarCharIter<'a> {
233 fn len(&self) -> usize {
234 self.view.len() - self.row
235 }
236}
237
238#[test]
239fn test_slice() {
240 let data = [None, Some(""), Some("abc"), Some("中文"), None, None, Some("a loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog string")];
241 let view = JsonView::from_iter::<&str, _, _, _>(data);
242 let slice = view.slice(0..0);
243 assert!(slice.is_none());
244 let slice = view.slice(100..1000);
245 assert!(slice.is_none());
246
247 for start in 0..data.len() {
248 let end = start + 1;
249 for end in end..data.len() {
250 let slice = view.slice(start..end).unwrap();
251 assert_eq!(
252 slice.to_vec().as_slice(),
253 &itertools::Itertools::collect_vec(
254 data[start..end].iter().map(|s| s.map(ToString::to_string))
255 )
256 );
257 }
258 }
259}