antecedent_data/
storage.rs1use std::sync::Arc;
6
7use antecedent_core::{CausalSchema, VariableId};
8
9use crate::column::{ColumnView, OwnedColumn};
10use crate::error::DataError;
11use crate::table::TableView;
12
13#[derive(Clone, Debug)]
15pub struct OwnedColumnarStorage {
16 schema: CausalSchema,
17 columns: Arc<[OwnedColumn]>,
18 row_count: usize,
19 analysis_mask: Option<crate::column::ValidityBitmap>,
21 weights: Option<Arc<[f64]>>,
23}
24
25impl OwnedColumnarStorage {
26 pub fn try_new(
32 schema: CausalSchema,
33 columns: Vec<OwnedColumn>,
34 analysis_mask: Option<crate::column::ValidityBitmap>,
35 weights: Option<Arc<[f64]>>,
36 ) -> Result<Self, DataError> {
37 if columns.len() != schema.len() {
38 return Err(DataError::LengthMismatch {
39 expected: schema.len(),
40 actual: columns.len(),
41 context: "column count vs schema",
42 });
43 }
44 let row_count = columns.first().map_or(0, OwnedColumn::len);
45 for (i, col) in columns.iter().enumerate() {
46 let expected_id = VariableId::from_raw(u32::try_from(i).map_err(|_| {
47 DataError::InvalidArgument { message: "schema exceeds VariableId range".into() }
48 })?);
49 if col.id() != expected_id {
50 return Err(DataError::UnknownVariable { id: col.id() });
51 }
52 if col.len() != row_count {
53 return Err(DataError::LengthMismatch {
54 expected: row_count,
55 actual: col.len(),
56 context: "column row count",
57 });
58 }
59 }
60 if let Some(mask) = &analysis_mask {
61 if mask.len() != row_count {
62 return Err(DataError::LengthMismatch {
63 expected: row_count,
64 actual: mask.len(),
65 context: "analysis mask",
66 });
67 }
68 }
69 if let Some(w) = &weights {
70 if w.len() != row_count {
71 return Err(DataError::LengthMismatch {
72 expected: row_count,
73 actual: w.len(),
74 context: "weights",
75 });
76 }
77 }
78 Ok(Self { schema, columns: Arc::from(columns), row_count, analysis_mask, weights })
79 }
80
81 #[must_use]
83 pub fn analysis_mask(&self) -> Option<&crate::column::ValidityBitmap> {
84 self.analysis_mask.as_ref()
85 }
86
87 #[must_use]
89 pub fn weights(&self) -> Option<&[f64]> {
90 self.weights.as_deref()
91 }
92
93 #[must_use]
95 pub fn columns(&self) -> &[OwnedColumn] {
96 &self.columns
97 }
98
99 #[must_use]
101 pub fn columns_arc(&self) -> &Arc<[OwnedColumn]> {
102 &self.columns
103 }
104}
105
106impl TableView for OwnedColumnarStorage {
107 fn schema(&self) -> &CausalSchema {
108 &self.schema
109 }
110
111 fn row_count(&self) -> usize {
112 self.row_count
113 }
114
115 fn column(&self, id: VariableId) -> Result<ColumnView<'_>, DataError> {
116 self.columns
117 .get(id.as_usize())
118 .map(OwnedColumn::as_view)
119 .ok_or(DataError::UnknownVariable { id })
120 }
121}