loro_internal/fork.rs
1//! The fork module provides functionality to create a new LoroDoc instance at a specified version
2//! (Frontiers) with minimal overhead.
3//!
4//! # Implementation Overview
5//!
6//! The `fork_at` function in this module allows for the creation of a new document that reflects
7//! the state of the original document at a given version. The function achieves this by:
8//!
9//! ## Exporting Necessary Data:
10//!
11//! - **Change Store Data**: Collects all changes up to the specified version from the change
12//! store's key-value (kv) data store. It includes the version vector and frontiers for accurate
13//! identification of the version.
14//!
15//! - **Container Store Data**: Exports the container store's kv data representing the document's
16//! state at the specified version. This involves checking out to the desired version, exporting
17//! the state, and efficiently checking back to the latest version.
18//!
19//! - **GC Store Data**: If applicable, exports the gc store's kv data, ensuring that version
20//! identifiers are included.
21//!
22//! ## Reconstructing the New Document:
23//!
24//! Imports the exported data into a new LoroDoc instance using optimized import mechanisms
25//! similar to those used in fast snapshot imports.
26//!
27//! By focusing on exporting only the necessary data and optimizing state transitions during
28//! version checkout, the `fork_at` function minimizes overhead and efficiently creates new
29//! document instances representing past versions.
30//!
31use std::borrow::Cow;
32
33use crate::{version::Frontiers, LoroDoc};
34
35impl LoroDoc {
36 /// Creates a new LoroDoc at a specified version (Frontiers)
37 pub fn fork_at(&self, frontiers: &Frontiers) -> Self {
38 let bytes = self
39 .export(crate::loro::ExportMode::SnapshotAt {
40 version: Cow::Borrowed(frontiers),
41 })
42 .unwrap();
43 let doc = LoroDoc::new();
44 doc.set_config(&self.config);
45 if self.auto_commit.load(std::sync::atomic::Ordering::Relaxed) {
46 doc.start_auto_commit();
47 }
48 doc.import(&bytes).unwrap();
49 doc
50 }
51}