nodedb_lite/engine/columnar/store/
read.rs1use super::decode::decoded_column_value;
6use super::segments::load_segment_bytes;
7use super::state::{ColumnarEngine, SegmentMeta};
8use crate::error::LiteError;
9use crate::storage::engine::StorageEngine;
10use nodedb_columnar::delete_bitmap::DeleteBitmap;
11use nodedb_types::value::Value;
12
13impl<S: StorageEngine> ColumnarEngine<S> {
14 pub async fn list_rows(&self, collection: &str) -> Result<Vec<Vec<Value>>, LiteError> {
19 let state_arc = self.lookup(collection)?;
20
21 struct Snapshot {
23 memtable_rows: Vec<Vec<Value>>,
24 seg_metas: Vec<SegmentMeta>,
25 col_count: usize,
26 }
27 let snap = {
28 let s = Self::lock_state(&state_arc)?;
29 let memtable_rows: Vec<Vec<Value>> = s
31 .mutation
32 .memtable()
33 .iter_rows()
34 .collect::<Result<_, _>>()
35 .map_err(|e| LiteError::Storage {
36 detail: format!("read memtable row of '{collection}': {e}"),
37 })?;
38 Snapshot {
39 memtable_rows,
40 seg_metas: s.segments.clone(),
41 col_count: s.mutation.schema().columns.len(),
42 }
43 };
44
45 let mut all_rows: Vec<Vec<Value>> = Vec::new();
46 all_rows.extend(snap.memtable_rows);
47
48 for seg_meta in &snap.seg_metas {
52 if seg_meta.fully_deleted_at_ms.is_some() {
53 continue;
54 }
55 let seg_bytes =
56 match load_segment_bytes(&*self.storage, collection, seg_meta.segment_id).await? {
57 Some(b) => b,
58 None => continue,
59 };
60
61 let reader = nodedb_columnar::reader::SegmentReader::open(&seg_bytes).map_err(|e| {
62 LiteError::Storage {
63 detail: format!("open segment {}: {e}", seg_meta.segment_id),
64 }
65 })?;
66
67 let row_count = reader.row_count() as usize;
68 if row_count == 0 {
69 continue;
70 }
71
72 let mut decoded: Vec<nodedb_columnar::reader::DecodedColumn> =
74 Vec::with_capacity(snap.col_count);
75 for col_idx in 0..snap.col_count {
76 let col = reader
77 .read_column(col_idx)
78 .map_err(|e| LiteError::Storage {
79 detail: format!(
80 "read column {col_idx} of segment {}: {e}",
81 seg_meta.segment_id
82 ),
83 })?;
84 decoded.push(col);
85 }
86
87 for row_idx in 0..row_count {
89 let row: Vec<Value> = decoded
90 .iter()
91 .map(|col| decoded_column_value(col, row_idx))
92 .collect();
93 all_rows.push(row);
94 }
95 }
96
97 Ok(all_rows)
98 }
99
100 pub async fn read_segments(&self, collection: &str) -> Result<Vec<(u32, Vec<u8>)>, LiteError> {
102 let state_arc = self.lookup(collection)?;
103 let seg_metas: Vec<SegmentMeta> = {
104 let s = Self::lock_state(&state_arc)?;
105 s.segments.clone()
106 };
107
108 let mut segments = Vec::with_capacity(seg_metas.len());
109 for seg_meta in &seg_metas {
110 if seg_meta.fully_deleted_at_ms.is_some() {
111 continue;
112 }
113 if let Some(bytes) =
114 load_segment_bytes(&*self.storage, collection, seg_meta.segment_id).await?
115 {
116 segments.push((seg_meta.segment_id, bytes));
117 }
118 }
119
120 Ok(segments)
121 }
122
123 pub fn delete_bitmap(&self, collection: &str, segment_id: u32) -> Option<DeleteBitmap> {
125 let guard = self.collections.read().ok()?;
126 let state_arc = guard.get(collection)?;
127 let s = state_arc.lock().ok()?;
128 s.mutation.delete_bitmap(segment_id as u64).cloned()
129 }
130
131 pub fn row_count(&self, collection: &str) -> usize {
133 let Ok(guard) = self.collections.read() else {
134 return 0;
135 };
136 let Some(state_arc) = guard.get(collection) else {
137 return 0;
138 };
139 let Ok(s) = state_arc.lock() else {
140 return 0;
141 };
142 let seg_rows: u64 = s
143 .segments
144 .iter()
145 .filter(|m| m.fully_deleted_at_ms.is_none())
146 .map(|m| m.row_count)
147 .sum();
148 seg_rows as usize + s.mutation.memtable().row_count()
149 }
150
151 pub fn is_bitemporal(&self, collection: &str) -> bool {
153 let Ok(guard) = self.collections.read() else {
154 return false;
155 };
156 let Some(state_arc) = guard.get(collection) else {
157 return false;
158 };
159 let Ok(s) = state_arc.lock() else {
160 return false;
161 };
162 s.bitemporal
163 }
164}