use crate::entities::{BlockPB, RepeatedBlockPB, RowPB}; use flowy_error::FlowyResult; use flowy_grid_data_model::revision::RowRevision; use std::collections::HashMap; use std::sync::Arc; pub struct GridBlockSnapshot { pub(crate) block_id: String, pub row_revs: Vec>, } pub(crate) fn block_from_row_orders(row_orders: Vec) -> Vec { let mut map: HashMap = HashMap::new(); row_orders.into_iter().for_each(|row_info| { // Memory Optimization: escape clone block_id let block_id = row_info.block_id().to_owned(); let cloned_block_id = block_id.clone(); map.entry(block_id) .or_insert_with(|| BlockPB::new(&cloned_block_id, vec![])) .rows .push(row_info); }); map.into_values().collect::>() } // // #[inline(always)] // fn make_cell_by_field_id( // field_map: &HashMap<&String, &FieldRevision>, // field_id: String, // cell_rev: CellRevision, // ) -> Option<(String, Cell)> { // let field_rev = field_map.get(&field_id)?; // let data = decode_cell_data(cell_rev.data, field_rev).data; // let cell = Cell::new(&field_id, data); // Some((field_id, cell)) // } pub(crate) fn make_row_orders_from_row_revs(row_revs: &[Arc]) -> Vec { row_revs.iter().map(RowPB::from).collect::>() } pub(crate) fn make_row_from_row_rev(row_rev: Arc) -> Option { make_rows_from_row_revs(&[row_rev]).pop() } pub(crate) fn make_rows_from_row_revs(row_revs: &[Arc]) -> Vec { let make_row = |row_rev: &Arc| RowPB { block_id: row_rev.block_id.clone(), id: row_rev.id.clone(), height: row_rev.height, }; row_revs.iter().map(make_row).collect::>() } pub(crate) fn make_grid_blocks( block_ids: Option>, block_snapshots: Vec, ) -> FlowyResult { match block_ids { None => Ok(block_snapshots .into_iter() .map(|snapshot| { let row_orders = make_row_orders_from_row_revs(&snapshot.row_revs); BlockPB::new(&snapshot.block_id, row_orders) }) .collect::>() .into()), Some(block_ids) => { let block_meta_data_map: HashMap<&String, &Vec>> = block_snapshots .iter() .map(|data| (&data.block_id, &data.row_revs)) .collect(); let mut grid_blocks = vec![]; for block_id in block_ids { match block_meta_data_map.get(&block_id) { None => {} Some(row_revs) => { let row_orders = make_row_orders_from_row_revs(row_revs); grid_blocks.push(BlockPB::new(&block_id, row_orders)); } } } Ok(grid_blocks.into()) } } }