Skip to main content

reifydb_core/value/batch/
mod.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Copyright (c) 2025 ReifyDB
3
4pub mod lazy;
5
6use lazy::LazyBatch;
7use reifydb_type::{util::bitvec::BitVec, value::Value};
8
9use crate::value::column::columns::Columns;
10
11/// A batch of rows that can be lazy (encoded) or materialized (decoded).
12///
13/// This enables operators to work with data in the most efficient form:
14/// - Lazy batches keep data encoded, enabling filters without materialization
15/// - Materialized batches have decoded columnar data ready for computation
16#[derive(Debug, Clone)]
17pub enum Batch {
18	/// Fully lazy batch - all data remains encoded
19	Lazy(LazyBatch),
20
21	/// Fully materialized batch - all columns decoded
22	FullyMaterialized(Columns),
23}
24
25impl Batch {
26	/// Create a lazy batch
27	pub fn lazy(lazy: LazyBatch) -> Self {
28		Batch::Lazy(lazy)
29	}
30
31	/// Create a materialized batch
32	pub fn fully_materialized(columns: Columns) -> Self {
33		Batch::FullyMaterialized(columns)
34	}
35
36	/// Get the number of rows in this batch
37	pub fn row_count(&self) -> usize {
38		match self {
39			Batch::Lazy(lazy) => lazy.valid_row_count(),
40			Batch::FullyMaterialized(columns) => columns.row_count(),
41		}
42	}
43
44	/// Get the number of columns
45	pub fn column_count(&self) -> usize {
46		match self {
47			Batch::Lazy(lazy) => lazy.column_count(),
48			Batch::FullyMaterialized(columns) => columns.len(),
49		}
50	}
51
52	/// Get a value from the batch
53	pub fn get_value(&self, row_idx: usize, col_idx: usize) -> Value {
54		match self {
55			Batch::Lazy(lazy) => lazy.get_value(row_idx, col_idx),
56			Batch::FullyMaterialized(columns) => columns[col_idx].data().get_value(row_idx),
57		}
58	}
59
60	/// Convert to fully materialized Columns
61	pub fn into_columns(self) -> Columns {
62		match self {
63			Batch::Lazy(lazy) => lazy.into_columns(),
64			Batch::FullyMaterialized(columns) => columns,
65		}
66	}
67
68	/// Try to get as lazy batch reference
69	pub fn as_lazy(&self) -> Option<&LazyBatch> {
70		match self {
71			Batch::Lazy(lazy) => Some(lazy),
72			_ => None,
73		}
74	}
75
76	/// Try to get as mutable lazy batch reference
77	pub fn as_lazy_mut(&mut self) -> Option<&mut LazyBatch> {
78		match self {
79			Batch::Lazy(lazy) => Some(lazy),
80			_ => None,
81		}
82	}
83
84	/// Apply a filter mask to the batch
85	///
86	/// For lazy batches: updates validity bitmap without materialization
87	/// For materialized batches: filters columns
88	pub fn apply_filter(&mut self, filter: &BitVec) -> reifydb_type::Result<()> {
89		match self {
90			Batch::Lazy(lazy) => {
91				lazy.apply_filter(filter);
92				Ok(())
93			}
94			Batch::FullyMaterialized(columns) => columns.filter(filter),
95		}
96	}
97
98	/// Extract rows by indices, creating a new batch
99	pub fn extract_by_indices(&self, indices: &[usize]) -> Batch {
100		match self {
101			Batch::Lazy(lazy) => {
102				// For lazy batches, we need to create a new lazy batch with only selected rows
103				// For now, materialize then extract
104				// TODO: Implement true lazy extraction
105				let columns = lazy.clone().into_columns();
106				Batch::FullyMaterialized(columns.extract_by_indices(indices))
107			}
108			Batch::FullyMaterialized(columns) => {
109				Batch::FullyMaterialized(columns.extract_by_indices(indices))
110			}
111		}
112	}
113}