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::NodeId(vec), Value::Int64(i)) => vec.push(NodeId::new(*i as u64)),
203 (VectorData::EdgeId(vec), Value::Int64(i)) => vec.push(EdgeId::new(*i as u64)),
205 (VectorData::Generic(vec), _) => vec.push(value),
206 _ => {
207 match &mut self.data {
209 VectorData::Bool(vec) => vec.push(false),
210 VectorData::Int64(vec) => vec.push(0),
211 VectorData::Float64(vec) => vec.push(0.0),
212 VectorData::String(vec) => vec.push("".into()),
213 VectorData::NodeId(vec) => vec.push(NodeId::new(0)),
214 VectorData::EdgeId(vec) => vec.push(EdgeId::new(0)),
215 VectorData::Generic(vec) => vec.push(value),
216 }
217 }
218 }
219 self.len += 1;
220 }
221
222 #[must_use]
224 pub fn get_bool(&self, index: usize) -> Option<bool> {
225 if self.is_null(index) {
226 return None;
227 }
228 if let VectorData::Bool(vec) = &self.data {
229 vec.get(index).copied()
230 } else {
231 None
232 }
233 }
234
235 #[must_use]
237 pub fn get_int64(&self, index: usize) -> Option<i64> {
238 if self.is_null(index) {
239 return None;
240 }
241 if let VectorData::Int64(vec) = &self.data {
242 vec.get(index).copied()
243 } else {
244 None
245 }
246 }
247
248 #[must_use]
250 pub fn get_float64(&self, index: usize) -> Option<f64> {
251 if self.is_null(index) {
252 return None;
253 }
254 if let VectorData::Float64(vec) = &self.data {
255 vec.get(index).copied()
256 } else {
257 None
258 }
259 }
260
261 #[must_use]
263 pub fn get_string(&self, index: usize) -> Option<&str> {
264 if self.is_null(index) {
265 return None;
266 }
267 if let VectorData::String(vec) = &self.data {
268 vec.get(index).map(|s| s.as_ref())
269 } else {
270 None
271 }
272 }
273
274 #[must_use]
276 pub fn get_node_id(&self, index: usize) -> Option<NodeId> {
277 if self.is_null(index) {
278 return None;
279 }
280 match &self.data {
281 VectorData::NodeId(vec) => vec.get(index).copied(),
282 VectorData::Generic(vec) => match vec.get(index) {
284 Some(Value::Int64(i)) => Some(NodeId::new(*i as u64)),
285 _ => None,
286 },
287 _ => None,
288 }
289 }
290
291 #[must_use]
293 pub fn get_edge_id(&self, index: usize) -> Option<EdgeId> {
294 if self.is_null(index) {
295 return None;
296 }
297 match &self.data {
298 VectorData::EdgeId(vec) => vec.get(index).copied(),
299 VectorData::Generic(vec) => match vec.get(index) {
301 Some(Value::Int64(i)) => Some(EdgeId::new(*i as u64)),
302 _ => None,
303 },
304 _ => None,
305 }
306 }
307
308 #[must_use]
310 pub fn get_value(&self, index: usize) -> Option<Value> {
311 if self.is_null(index) {
312 return Some(Value::Null);
313 }
314
315 match &self.data {
316 VectorData::Bool(vec) => vec.get(index).map(|&v| Value::Bool(v)),
317 VectorData::Int64(vec) => vec.get(index).map(|&v| Value::Int64(v)),
318 VectorData::Float64(vec) => vec.get(index).map(|&v| Value::Float64(v)),
319 VectorData::String(vec) => vec.get(index).map(|v| Value::String(v.clone())),
320 VectorData::NodeId(vec) => vec.get(index).map(|&v| Value::Int64(v.as_u64() as i64)),
321 VectorData::EdgeId(vec) => vec.get(index).map(|&v| Value::Int64(v.as_u64() as i64)),
322 VectorData::Generic(vec) => vec.get(index).cloned(),
323 }
324 }
325
326 #[must_use]
328 pub fn get(&self, index: usize) -> Option<Value> {
329 self.get_value(index)
330 }
331
332 pub fn push(&mut self, value: Value) {
334 self.push_value(value);
335 }
336
337 #[must_use]
339 pub fn as_bool_slice(&self) -> Option<&[bool]> {
340 if let VectorData::Bool(vec) = &self.data {
341 Some(vec)
342 } else {
343 None
344 }
345 }
346
347 #[must_use]
349 pub fn as_int64_slice(&self) -> Option<&[i64]> {
350 if let VectorData::Int64(vec) = &self.data {
351 Some(vec)
352 } else {
353 None
354 }
355 }
356
357 #[must_use]
359 pub fn as_float64_slice(&self) -> Option<&[f64]> {
360 if let VectorData::Float64(vec) = &self.data {
361 Some(vec)
362 } else {
363 None
364 }
365 }
366
367 #[must_use]
369 pub fn as_node_id_slice(&self) -> Option<&[NodeId]> {
370 if let VectorData::NodeId(vec) = &self.data {
371 Some(vec)
372 } else {
373 None
374 }
375 }
376
377 #[must_use]
379 pub fn as_edge_id_slice(&self) -> Option<&[EdgeId]> {
380 if let VectorData::EdgeId(vec) = &self.data {
381 Some(vec)
382 } else {
383 None
384 }
385 }
386
387 #[must_use]
389 pub fn logical_type(&self) -> LogicalType {
390 self.data_type.clone()
391 }
392
393 pub fn copy_row_to(&self, row: usize, dest: &mut ValueVector) {
398 if self.is_null(row) {
399 dest.push_value(Value::Null);
400 return;
401 }
402
403 match &self.data {
404 VectorData::Bool(vec) => {
405 if let Some(&v) = vec.get(row) {
406 dest.push_bool(v);
407 }
408 }
409 VectorData::Int64(vec) => {
410 if let Some(&v) = vec.get(row) {
411 dest.push_int64(v);
412 }
413 }
414 VectorData::Float64(vec) => {
415 if let Some(&v) = vec.get(row) {
416 dest.push_float64(v);
417 }
418 }
419 VectorData::String(vec) => {
420 if let Some(v) = vec.get(row) {
421 dest.push_string(v.clone());
422 }
423 }
424 VectorData::NodeId(vec) => {
425 if let Some(&v) = vec.get(row) {
426 dest.push_node_id(v);
427 }
428 }
429 VectorData::EdgeId(vec) => {
430 if let Some(&v) = vec.get(row) {
431 dest.push_edge_id(v);
432 }
433 }
434 VectorData::Generic(vec) => {
435 if let Some(v) = vec.get(row) {
436 dest.push_value(v.clone());
437 }
438 }
439 }
440 }
441
442 pub fn clear(&mut self) {
444 match &mut self.data {
445 VectorData::Bool(vec) => vec.clear(),
446 VectorData::Int64(vec) => vec.clear(),
447 VectorData::Float64(vec) => vec.clear(),
448 VectorData::String(vec) => vec.clear(),
449 VectorData::NodeId(vec) => vec.clear(),
450 VectorData::EdgeId(vec) => vec.clear(),
451 VectorData::Generic(vec) => vec.clear(),
452 }
453 self.len = 0;
454 self.validity = None;
455 }
456}
457
458impl Default for ValueVector {
459 fn default() -> Self {
460 Self::new()
461 }
462}
463
464#[cfg(test)]
465mod tests {
466 use super::*;
467
468 #[test]
469 fn test_int64_vector() {
470 let mut vec = ValueVector::with_type(LogicalType::Int64);
471
472 vec.push_int64(1);
473 vec.push_int64(2);
474 vec.push_int64(3);
475
476 assert_eq!(vec.len(), 3);
477 assert_eq!(vec.get_int64(0), Some(1));
478 assert_eq!(vec.get_int64(1), Some(2));
479 assert_eq!(vec.get_int64(2), Some(3));
480 }
481
482 #[test]
483 fn test_string_vector() {
484 let mut vec = ValueVector::with_type(LogicalType::String);
485
486 vec.push_string("hello");
487 vec.push_string("world");
488
489 assert_eq!(vec.len(), 2);
490 assert_eq!(vec.get_string(0), Some("hello"));
491 assert_eq!(vec.get_string(1), Some("world"));
492 }
493
494 #[test]
495 fn test_null_values() {
496 let mut vec = ValueVector::with_type(LogicalType::Int64);
497
498 vec.push_int64(1);
499 vec.push_int64(2);
500 vec.push_int64(3);
501
502 assert!(!vec.is_null(1));
503 vec.set_null(1);
504 assert!(vec.is_null(1));
505
506 assert_eq!(vec.get_int64(0), Some(1));
507 assert_eq!(vec.get_int64(1), None); assert_eq!(vec.get_int64(2), Some(3));
509 }
510
511 #[test]
512 fn test_get_value() {
513 let mut vec = ValueVector::with_type(LogicalType::Int64);
514 vec.push_int64(42);
515
516 let value = vec.get_value(0);
517 assert_eq!(value, Some(Value::Int64(42)));
518 }
519
520 #[test]
521 fn test_slice_access() {
522 let mut vec = ValueVector::with_type(LogicalType::Int64);
523 vec.push_int64(1);
524 vec.push_int64(2);
525 vec.push_int64(3);
526
527 let slice = vec.as_int64_slice().unwrap();
528 assert_eq!(slice, &[1, 2, 3]);
529 }
530
531 #[test]
532 fn test_clear() {
533 let mut vec = ValueVector::with_type(LogicalType::Int64);
534 vec.push_int64(1);
535 vec.push_int64(2);
536
537 vec.clear();
538
539 assert!(vec.is_empty());
540 assert_eq!(vec.len(), 0);
541 }
542}