1use std::sync::Arc;
4
5use grafeo_common::types::{EdgeId, LogicalType, NodeId, Value};
6
7pub const DEFAULT_VECTOR_CAPACITY: usize = 2048;
9
10#[derive(Debug, Clone)]
15pub struct ValueVector {
16 data_type: LogicalType,
18 data: VectorData,
20 len: usize,
22 validity: Option<Vec<bool>>,
24}
25
26#[derive(Debug, Clone)]
28enum VectorData {
29 Bool(Vec<bool>),
31 Int64(Vec<i64>),
33 Float64(Vec<f64>),
35 String(Vec<Arc<str>>),
37 NodeId(Vec<NodeId>),
39 EdgeId(Vec<EdgeId>),
41 Generic(Vec<Value>),
43}
44
45impl ValueVector {
46 #[must_use]
48 pub fn new() -> Self {
49 Self::with_capacity(LogicalType::Any, DEFAULT_VECTOR_CAPACITY)
50 }
51
52 #[must_use]
54 pub fn with_type(data_type: LogicalType) -> Self {
55 Self::with_capacity(data_type, DEFAULT_VECTOR_CAPACITY)
56 }
57
58 pub fn from_values(values: &[Value]) -> Self {
60 let mut vec = Self::new();
61 for value in values {
62 vec.push_value(value.clone());
63 }
64 vec
65 }
66
67 #[must_use]
69 pub fn with_capacity(data_type: LogicalType, capacity: usize) -> Self {
70 let data = match &data_type {
71 LogicalType::Bool => VectorData::Bool(Vec::with_capacity(capacity)),
72 LogicalType::Int8 | LogicalType::Int16 | LogicalType::Int32 | LogicalType::Int64 => {
73 VectorData::Int64(Vec::with_capacity(capacity))
74 }
75 LogicalType::Float32 | LogicalType::Float64 => {
76 VectorData::Float64(Vec::with_capacity(capacity))
77 }
78 LogicalType::String => VectorData::String(Vec::with_capacity(capacity)),
79 LogicalType::Node => VectorData::NodeId(Vec::with_capacity(capacity)),
80 LogicalType::Edge => VectorData::EdgeId(Vec::with_capacity(capacity)),
81 _ => VectorData::Generic(Vec::with_capacity(capacity)),
82 };
83
84 Self {
85 data_type,
86 data,
87 len: 0,
88 validity: None,
89 }
90 }
91
92 #[must_use]
94 pub fn data_type(&self) -> &LogicalType {
95 &self.data_type
96 }
97
98 #[must_use]
100 pub fn len(&self) -> usize {
101 self.len
102 }
103
104 #[must_use]
106 pub fn is_empty(&self) -> bool {
107 self.len == 0
108 }
109
110 #[must_use]
112 pub fn is_null(&self, index: usize) -> bool {
113 self.validity
114 .as_ref()
115 .map_or(false, |v| !v.get(index).copied().unwrap_or(true))
116 }
117
118 pub fn set_null(&mut self, index: usize) {
120 if self.validity.is_none() {
121 self.validity = Some(vec![true; self.len]);
122 }
123 if let Some(validity) = &mut self.validity {
124 if index < validity.len() {
125 validity[index] = false;
126 }
127 }
128 }
129
130 pub fn push_bool(&mut self, value: bool) {
132 if let VectorData::Bool(vec) = &mut self.data {
133 vec.push(value);
134 self.len += 1;
135 }
136 }
137
138 pub fn push_int64(&mut self, value: i64) {
140 if let VectorData::Int64(vec) = &mut self.data {
141 vec.push(value);
142 self.len += 1;
143 }
144 }
145
146 pub fn push_float64(&mut self, value: f64) {
148 if let VectorData::Float64(vec) = &mut self.data {
149 vec.push(value);
150 self.len += 1;
151 }
152 }
153
154 pub fn push_string(&mut self, value: impl Into<Arc<str>>) {
156 if let VectorData::String(vec) = &mut self.data {
157 vec.push(value.into());
158 self.len += 1;
159 }
160 }
161
162 pub fn push_node_id(&mut self, value: NodeId) {
164 if let VectorData::NodeId(vec) = &mut self.data {
165 vec.push(value);
166 self.len += 1;
167 }
168 }
169
170 pub fn push_edge_id(&mut self, value: EdgeId) {
172 if let VectorData::EdgeId(vec) = &mut self.data {
173 vec.push(value);
174 self.len += 1;
175 }
176 }
177
178 pub fn push_value(&mut self, value: Value) {
180 if matches!(value, Value::Null) {
182 match &mut self.data {
183 VectorData::Bool(vec) => vec.push(false),
184 VectorData::Int64(vec) => vec.push(0),
185 VectorData::Float64(vec) => vec.push(0.0),
186 VectorData::String(vec) => vec.push("".into()),
187 VectorData::NodeId(vec) => vec.push(NodeId::new(0)),
188 VectorData::EdgeId(vec) => vec.push(EdgeId::new(0)),
189 VectorData::Generic(vec) => vec.push(Value::Null),
190 }
191 self.len += 1;
192 self.set_null(self.len - 1);
193 return;
194 }
195
196 match (&mut self.data, &value) {
197 (VectorData::Bool(vec), Value::Bool(b)) => vec.push(*b),
198 (VectorData::Int64(vec), Value::Int64(i)) => vec.push(*i),
199 (VectorData::Float64(vec), Value::Float64(f)) => vec.push(*f),
200 (VectorData::String(vec), Value::String(s)) => vec.push(s.clone()),
201 (VectorData::Generic(vec), _) => vec.push(value),
202 _ => {
203 match &mut self.data {
205 VectorData::Bool(vec) => vec.push(false),
206 VectorData::Int64(vec) => vec.push(0),
207 VectorData::Float64(vec) => vec.push(0.0),
208 VectorData::String(vec) => vec.push("".into()),
209 VectorData::NodeId(vec) => vec.push(NodeId::new(0)),
210 VectorData::EdgeId(vec) => vec.push(EdgeId::new(0)),
211 VectorData::Generic(vec) => vec.push(value),
212 }
213 }
214 }
215 self.len += 1;
216 }
217
218 #[must_use]
220 pub fn get_bool(&self, index: usize) -> Option<bool> {
221 if self.is_null(index) {
222 return None;
223 }
224 if let VectorData::Bool(vec) = &self.data {
225 vec.get(index).copied()
226 } else {
227 None
228 }
229 }
230
231 #[must_use]
233 pub fn get_int64(&self, index: usize) -> Option<i64> {
234 if self.is_null(index) {
235 return None;
236 }
237 if let VectorData::Int64(vec) = &self.data {
238 vec.get(index).copied()
239 } else {
240 None
241 }
242 }
243
244 #[must_use]
246 pub fn get_float64(&self, index: usize) -> Option<f64> {
247 if self.is_null(index) {
248 return None;
249 }
250 if let VectorData::Float64(vec) = &self.data {
251 vec.get(index).copied()
252 } else {
253 None
254 }
255 }
256
257 #[must_use]
259 pub fn get_string(&self, index: usize) -> Option<&str> {
260 if self.is_null(index) {
261 return None;
262 }
263 if let VectorData::String(vec) = &self.data {
264 vec.get(index).map(|s| s.as_ref())
265 } else {
266 None
267 }
268 }
269
270 #[must_use]
272 pub fn get_node_id(&self, index: usize) -> Option<NodeId> {
273 if self.is_null(index) {
274 return None;
275 }
276 if let VectorData::NodeId(vec) = &self.data {
277 vec.get(index).copied()
278 } else {
279 None
280 }
281 }
282
283 #[must_use]
285 pub fn get_edge_id(&self, index: usize) -> Option<EdgeId> {
286 if self.is_null(index) {
287 return None;
288 }
289 if let VectorData::EdgeId(vec) = &self.data {
290 vec.get(index).copied()
291 } else {
292 None
293 }
294 }
295
296 #[must_use]
298 pub fn get_value(&self, index: usize) -> Option<Value> {
299 if self.is_null(index) {
300 return Some(Value::Null);
301 }
302
303 match &self.data {
304 VectorData::Bool(vec) => vec.get(index).map(|&v| Value::Bool(v)),
305 VectorData::Int64(vec) => vec.get(index).map(|&v| Value::Int64(v)),
306 VectorData::Float64(vec) => vec.get(index).map(|&v| Value::Float64(v)),
307 VectorData::String(vec) => vec.get(index).map(|v| Value::String(v.clone())),
308 VectorData::NodeId(vec) => vec.get(index).map(|&v| Value::Int64(v.as_u64() as i64)),
309 VectorData::EdgeId(vec) => vec.get(index).map(|&v| Value::Int64(v.as_u64() as i64)),
310 VectorData::Generic(vec) => vec.get(index).cloned(),
311 }
312 }
313
314 #[must_use]
316 pub fn get(&self, index: usize) -> Option<Value> {
317 self.get_value(index)
318 }
319
320 pub fn push(&mut self, value: Value) {
322 self.push_value(value);
323 }
324
325 #[must_use]
327 pub fn as_bool_slice(&self) -> Option<&[bool]> {
328 if let VectorData::Bool(vec) = &self.data {
329 Some(vec)
330 } else {
331 None
332 }
333 }
334
335 #[must_use]
337 pub fn as_int64_slice(&self) -> Option<&[i64]> {
338 if let VectorData::Int64(vec) = &self.data {
339 Some(vec)
340 } else {
341 None
342 }
343 }
344
345 #[must_use]
347 pub fn as_float64_slice(&self) -> Option<&[f64]> {
348 if let VectorData::Float64(vec) = &self.data {
349 Some(vec)
350 } else {
351 None
352 }
353 }
354
355 #[must_use]
357 pub fn as_node_id_slice(&self) -> Option<&[NodeId]> {
358 if let VectorData::NodeId(vec) = &self.data {
359 Some(vec)
360 } else {
361 None
362 }
363 }
364
365 #[must_use]
367 pub fn as_edge_id_slice(&self) -> Option<&[EdgeId]> {
368 if let VectorData::EdgeId(vec) = &self.data {
369 Some(vec)
370 } else {
371 None
372 }
373 }
374
375 #[must_use]
377 pub fn logical_type(&self) -> LogicalType {
378 self.data_type.clone()
379 }
380
381 pub fn copy_row_to(&self, row: usize, dest: &mut ValueVector) {
386 if self.is_null(row) {
387 dest.push_value(Value::Null);
388 return;
389 }
390
391 match &self.data {
392 VectorData::Bool(vec) => {
393 if let Some(&v) = vec.get(row) {
394 dest.push_bool(v);
395 }
396 }
397 VectorData::Int64(vec) => {
398 if let Some(&v) = vec.get(row) {
399 dest.push_int64(v);
400 }
401 }
402 VectorData::Float64(vec) => {
403 if let Some(&v) = vec.get(row) {
404 dest.push_float64(v);
405 }
406 }
407 VectorData::String(vec) => {
408 if let Some(v) = vec.get(row) {
409 dest.push_string(v.clone());
410 }
411 }
412 VectorData::NodeId(vec) => {
413 if let Some(&v) = vec.get(row) {
414 dest.push_node_id(v);
415 }
416 }
417 VectorData::EdgeId(vec) => {
418 if let Some(&v) = vec.get(row) {
419 dest.push_edge_id(v);
420 }
421 }
422 VectorData::Generic(vec) => {
423 if let Some(v) = vec.get(row) {
424 dest.push_value(v.clone());
425 }
426 }
427 }
428 }
429
430 pub fn clear(&mut self) {
432 match &mut self.data {
433 VectorData::Bool(vec) => vec.clear(),
434 VectorData::Int64(vec) => vec.clear(),
435 VectorData::Float64(vec) => vec.clear(),
436 VectorData::String(vec) => vec.clear(),
437 VectorData::NodeId(vec) => vec.clear(),
438 VectorData::EdgeId(vec) => vec.clear(),
439 VectorData::Generic(vec) => vec.clear(),
440 }
441 self.len = 0;
442 self.validity = None;
443 }
444}
445
446impl Default for ValueVector {
447 fn default() -> Self {
448 Self::new()
449 }
450}
451
452#[cfg(test)]
453mod tests {
454 use super::*;
455
456 #[test]
457 fn test_int64_vector() {
458 let mut vec = ValueVector::with_type(LogicalType::Int64);
459
460 vec.push_int64(1);
461 vec.push_int64(2);
462 vec.push_int64(3);
463
464 assert_eq!(vec.len(), 3);
465 assert_eq!(vec.get_int64(0), Some(1));
466 assert_eq!(vec.get_int64(1), Some(2));
467 assert_eq!(vec.get_int64(2), Some(3));
468 }
469
470 #[test]
471 fn test_string_vector() {
472 let mut vec = ValueVector::with_type(LogicalType::String);
473
474 vec.push_string("hello");
475 vec.push_string("world");
476
477 assert_eq!(vec.len(), 2);
478 assert_eq!(vec.get_string(0), Some("hello"));
479 assert_eq!(vec.get_string(1), Some("world"));
480 }
481
482 #[test]
483 fn test_null_values() {
484 let mut vec = ValueVector::with_type(LogicalType::Int64);
485
486 vec.push_int64(1);
487 vec.push_int64(2);
488 vec.push_int64(3);
489
490 assert!(!vec.is_null(1));
491 vec.set_null(1);
492 assert!(vec.is_null(1));
493
494 assert_eq!(vec.get_int64(0), Some(1));
495 assert_eq!(vec.get_int64(1), None); assert_eq!(vec.get_int64(2), Some(3));
497 }
498
499 #[test]
500 fn test_get_value() {
501 let mut vec = ValueVector::with_type(LogicalType::Int64);
502 vec.push_int64(42);
503
504 let value = vec.get_value(0);
505 assert_eq!(value, Some(Value::Int64(42)));
506 }
507
508 #[test]
509 fn test_slice_access() {
510 let mut vec = ValueVector::with_type(LogicalType::Int64);
511 vec.push_int64(1);
512 vec.push_int64(2);
513 vec.push_int64(3);
514
515 let slice = vec.as_int64_slice().unwrap();
516 assert_eq!(slice, &[1, 2, 3]);
517 }
518
519 #[test]
520 fn test_clear() {
521 let mut vec = ValueVector::with_type(LogicalType::Int64);
522 vec.push_int64(1);
523 vec.push_int64(2);
524
525 vec.clear();
526
527 assert!(vec.is_empty());
528 assert_eq!(vec.len(), 0);
529 }
530}