1use crate::database::block_offset_index::BlockOffsetIndex;
11use crate::entities::*;
12use crate::format_runs::{FootnoteRefAnchor, FormatRun, ImageAnchor};
13use crate::snapshot::{StoreSnapshot, StoreSnapshotTrait};
14use crate::types::EntityId;
15use im::HashMap;
16use parking_lot::RwLock;
17use ropey::Rope;
18use std::collections::HashMap as StdHashMap;
19
20#[derive(Debug, Default)]
25pub struct RopeStore {
26 pub rope: RwLock<Rope>,
28
29 pub roots: RwLock<HashMap<EntityId, Root>>,
31 pub documents: RwLock<HashMap<EntityId, Document>>,
32 pub frames: RwLock<HashMap<EntityId, Frame>>,
33 pub blocks: RwLock<HashMap<EntityId, Block>>,
34 pub lists: RwLock<HashMap<EntityId, List>>,
35 pub resources: RwLock<HashMap<EntityId, Resource>>,
36 pub tables: RwLock<HashMap<EntityId, Table>>,
37 pub table_cells: RwLock<HashMap<EntityId, TableCell>>,
38
39 pub format_runs: RwLock<HashMap<EntityId, Vec<FormatRun>>>,
41 pub block_images: RwLock<HashMap<EntityId, Vec<ImageAnchor>>>,
42 pub block_footnote_refs: RwLock<HashMap<EntityId, Vec<FootnoteRefAnchor>>>,
49 pub footnote_markers: RwLock<StdHashMap<String, String>>,
61
62 pub block_offsets: RwLock<BlockOffsetIndex>,
64
65 pub counters: RwLock<StdHashMap<String, EntityId>>,
68
69 savepoints: RwLock<StdHashMap<u64, RopeStoreSnapshot>>,
71 next_savepoint_id: RwLock<u64>,
72}
73
74impl RopeStore {
75 pub fn new() -> Self {
76 Self::default()
77 }
78
79 pub fn snapshot(&self) -> RopeStoreSnapshot {
83 RopeStoreSnapshot {
84 rope: self.rope.read().clone(),
85 roots: self.roots.read().clone(),
86 documents: self.documents.read().clone(),
87 frames: self.frames.read().clone(),
88 blocks: self.blocks.read().clone(),
89 lists: self.lists.read().clone(),
90 resources: self.resources.read().clone(),
91 tables: self.tables.read().clone(),
92 table_cells: self.table_cells.read().clone(),
93 format_runs: self.format_runs.read().clone(),
94 block_images: self.block_images.read().clone(),
95 block_footnote_refs: self.block_footnote_refs.read().clone(),
96 footnote_markers: self.footnote_markers.read().clone(),
97 block_offsets: self.block_offsets.read().clone(),
98 counters: self.counters.read().clone(),
99 }
100 }
101
102 pub fn restore(&self, snap: &RopeStoreSnapshot) {
105 *self.rope.write() = snap.rope.clone();
106 *self.roots.write() = snap.roots.clone();
107 *self.documents.write() = snap.documents.clone();
108 *self.frames.write() = snap.frames.clone();
109 *self.blocks.write() = snap.blocks.clone();
110 *self.lists.write() = snap.lists.clone();
111 *self.resources.write() = snap.resources.clone();
112 *self.tables.write() = snap.tables.clone();
113 *self.table_cells.write() = snap.table_cells.clone();
114 *self.format_runs.write() = snap.format_runs.clone();
115 *self.block_images.write() = snap.block_images.clone();
116 *self.block_footnote_refs.write() = snap.block_footnote_refs.clone();
117 *self.footnote_markers.write() = snap.footnote_markers.clone();
118 *self.block_offsets.write() = snap.block_offsets.clone();
119 *self.counters.write() = snap.counters.clone();
120 }
121
122 pub fn restore_without_counters(&self, snap: &RopeStoreSnapshot) {
125 *self.rope.write() = snap.rope.clone();
126 *self.roots.write() = snap.roots.clone();
127 *self.documents.write() = snap.documents.clone();
128 *self.frames.write() = snap.frames.clone();
129 *self.blocks.write() = snap.blocks.clone();
130 *self.lists.write() = snap.lists.clone();
131 *self.resources.write() = snap.resources.clone();
132 *self.tables.write() = snap.tables.clone();
133 *self.table_cells.write() = snap.table_cells.clone();
134 *self.format_runs.write() = snap.format_runs.clone();
135 *self.block_images.write() = snap.block_images.clone();
136 *self.block_footnote_refs.write() = snap.block_footnote_refs.clone();
137 *self.footnote_markers.write() = snap.footnote_markers.clone();
138 *self.block_offsets.write() = snap.block_offsets.clone();
139 }
141
142 pub fn create_savepoint(&self) -> u64 {
143 let snap = self.snapshot();
144 let mut id_counter = self.next_savepoint_id.write();
145 let id = *id_counter;
146 *id_counter += 1;
147 self.savepoints.write().insert(id, snap);
148 id
149 }
150
151 pub fn restore_savepoint(&self, savepoint_id: u64) {
152 let snap = self
153 .savepoints
154 .read()
155 .get(&savepoint_id)
156 .expect("savepoint not found")
157 .clone();
158 self.restore(&snap);
159 }
160
161 pub fn discard_savepoint(&self, savepoint_id: u64) {
162 self.savepoints.write().remove(&savepoint_id);
163 }
164
165 pub(crate) fn next_id(&self, entity_name: &str) -> EntityId {
167 let mut counters = self.counters.write();
168 let counter = counters.entry(entity_name.to_string()).or_insert(1);
169 let id = *counter;
170 *counter += 1;
171 id
172 }
173
174 pub fn store_snapshot(&self) -> StoreSnapshot {
176 StoreSnapshot::new(self.snapshot())
177 }
178
179 pub fn restore_store_snapshot(&self, snap: &StoreSnapshot) {
182 let s = snap
183 .downcast_ref::<RopeStoreSnapshot>()
184 .expect("StoreSnapshot must contain RopeStoreSnapshot");
185 self.restore_without_counters(s);
186 }
187}
188
189#[derive(Debug, Clone, Default)]
196pub struct RopeStoreSnapshot {
197 pub(crate) rope: Rope,
198 pub(crate) roots: HashMap<EntityId, Root>,
199 pub(crate) documents: HashMap<EntityId, Document>,
200 pub(crate) frames: HashMap<EntityId, Frame>,
201 pub(crate) blocks: HashMap<EntityId, Block>,
202 pub(crate) lists: HashMap<EntityId, List>,
203 pub(crate) resources: HashMap<EntityId, Resource>,
204 pub(crate) tables: HashMap<EntityId, Table>,
205 pub(crate) table_cells: HashMap<EntityId, TableCell>,
206 pub(crate) format_runs: HashMap<EntityId, Vec<FormatRun>>,
207 pub(crate) block_images: HashMap<EntityId, Vec<ImageAnchor>>,
208 pub(crate) block_footnote_refs: HashMap<EntityId, Vec<FootnoteRefAnchor>>,
209 pub(crate) footnote_markers: StdHashMap<String, String>,
210 pub(crate) block_offsets: BlockOffsetIndex,
211 pub(crate) counters: StdHashMap<String, EntityId>,
212}
213
214impl StoreSnapshotTrait for RopeStoreSnapshot {
215 fn clone_box(&self) -> Box<dyn StoreSnapshotTrait> {
216 Box::new(self.clone())
217 }
218
219 fn as_any(&self) -> &dyn std::any::Any {
220 self
221 }
222}