akar_storage/
local_storage.rs1use crate::table::{NodeTable, RelTable, TableCatalog};
9use akar_common::error::StorageError;
10use akar_transaction::UndoRecord;
11use std::collections::HashMap;
12use std::sync::Arc;
13
14#[derive(Debug, Default)]
20pub struct LocalTableData {
21 inserted_rows: Vec<Vec<u8>>,
22 deleted_row_ids: Vec<u64>,
23 updated_rows: HashMap<u64, Vec<u8>>,
24}
25
26impl LocalTableData {
27 pub fn new() -> Self {
28 Self::default()
29 }
30
31 pub fn insert(&mut self, row_data: Vec<u8>) {
32 self.inserted_rows.push(row_data);
33 }
34
35 pub fn delete(&mut self, row_id: u64) {
36 self.deleted_row_ids.push(row_id);
37 }
38
39 pub fn update(&mut self, row_id: u64, row_data: Vec<u8>) {
40 self.updated_rows.insert(row_id, row_data);
41 }
42
43 pub fn inserted_rows(&self) -> &[Vec<u8>] {
44 &self.inserted_rows
45 }
46
47 pub fn deleted_row_ids(&self) -> &[u64] {
48 &self.deleted_row_ids
49 }
50
51 pub fn updated_rows(&self) -> &HashMap<u64, Vec<u8>> {
52 &self.updated_rows
53 }
54
55 pub fn len(&self) -> usize {
57 self.inserted_rows.len() + self.deleted_row_ids.len() + self.updated_rows.len()
58 }
59
60 pub fn is_empty(&self) -> bool {
61 self.inserted_rows.is_empty() && self.deleted_row_ids.is_empty() && self.updated_rows.is_empty()
62 }
63
64 pub fn flush_to_node_table(
71 &self,
72 table_id: u64,
73 node_table: &mut NodeTable,
74 txn_id: Option<u64>,
75 ) -> Result<Vec<UndoRecord>, StorageError> {
76 use crate::column::Column;
77 let mut undo_records = Vec::new();
78
79 for row_bytes in &self.inserted_rows {
80 let values = crate::deserialize_values_from_bytes(row_bytes, node_table.columns.len());
81 let row_id = node_table.insert_row_with_txn(values, txn_id)?;
82 if txn_id.is_some() {
83 undo_records.push(UndoRecord::insert(table_id, row_id));
84 }
85 }
86
87 for row_id in &self.deleted_row_ids {
88 let num_cols = node_table.columns.len();
89 let mut old_row_data = Vec::new();
90 for col_idx in 0..num_cols {
91 let val = node_table
92 .get_value(*row_id as usize, col_idx)
93 .cloned()
94 .unwrap_or(akar_common::types::Value::Null);
95 old_row_data.extend_from_slice(&Column::serialize_value(&val));
96 }
97 node_table.delete_row_with_txn(*row_id, txn_id)?;
98 if txn_id.is_some() {
99 undo_records.push(UndoRecord::delete(table_id, *row_id, old_row_data));
100 }
101 }
102
103 for (row_id, row_bytes) in &self.updated_rows {
104 let values = crate::deserialize_values_from_bytes(row_bytes, node_table.columns.len());
105 for (col_idx, val) in values.into_iter().enumerate() {
106 node_table.update_cell(*row_id, col_idx, val)?;
107 }
108 }
109
110 Ok(undo_records)
111 }
112
113 pub fn flush_to_rel_table(&self, rel_table: &mut RelTable) -> Result<(), StorageError> {
115 for row_bytes in &self.inserted_rows {
116 let values = crate::deserialize_values_from_bytes(row_bytes, rel_table.columns.len());
117 rel_table.insert_row(values)?;
118 }
119
120 for (row_id, row_bytes) in &self.updated_rows {
121 let values = crate::deserialize_values_from_bytes(row_bytes, rel_table.columns.len());
122 for (col_idx, val) in values.into_iter().enumerate() {
123 rel_table.update_cell(*row_id as usize, col_idx, val)?;
124 }
125 }
126
127 for row_id in &self.deleted_row_ids {
128 rel_table.delete_edge(*row_id as usize)?;
129 }
130
131 Ok(())
132 }
133
134 pub fn clear(&mut self) {
135 self.inserted_rows.clear();
136 self.deleted_row_ids.clear();
137 self.updated_rows.clear();
138 }
139}
140
141#[derive(Debug, Default)]
143pub struct LocalStorage {
144 tables: HashMap<u64, LocalTableData>,
145}
146
147impl LocalStorage {
148 pub fn new() -> Self {
149 Self::default()
150 }
151
152 pub fn get_or_create_table(&mut self, table_id: u64) -> &mut LocalTableData {
153 self.tables.entry(table_id).or_default()
154 }
155
156 pub fn get_table(&self, table_id: u64) -> Option<&LocalTableData> {
157 self.tables.get(&table_id)
158 }
159
160 pub fn len(&self) -> usize {
162 self.tables.len()
163 }
164
165 pub fn is_empty(&self) -> bool {
166 self.tables.is_empty()
167 }
168
169 pub fn flush_to_tables(
176 &self,
177 catalog: &Arc<TableCatalog>,
178 txn_id: Option<u64>,
179 ) -> Result<Vec<UndoRecord>, StorageError> {
180 let mut all_undo_records = Vec::new();
181 for (&table_id, table_data) in &self.tables {
182 if table_data.is_empty() {
183 continue;
184 }
185 if let Some(mut node_table) = catalog.get_node_table_mut(table_id) {
186 let undo_records = table_data.flush_to_node_table(table_id, &mut node_table, txn_id)?;
187 all_undo_records.extend(undo_records);
188 } else if let Some(mut rel_table) = catalog.get_rel_table_mut(table_id) {
189 table_data.flush_to_rel_table(&mut rel_table)?;
190 }
191 }
192 Ok(all_undo_records)
193 }
194
195 pub fn clear(&mut self) {
197 self.tables.clear();
198 }
199}