diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/document/file.rs | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/src/document/file.rs b/src/document/file.rs index 54ab9af..a21aa17 100644 --- a/src/document/file.rs +++ b/src/document/file.rs @@ -1,7 +1,7 @@ //! The document file (`--document-file`): this node's document on disk, so a restart //! resumes with it instead of starting empty. //! -//! Format: the line `continuum-document/2`, a header line (JSON: the actor IDs this +//! Format: the line `continuum-document/3`, a header line (JSON: the actor IDs this //! node wrote with, so a later rejoin replays those writes as its own, and the one it //! writes with, `current`), then records, each a little-endian `u32` length and that //! many bytes, the first of them its kind (`Record`): first a full save of the document, @@ -11,8 +11,10 @@ //! holds everything the node wrote, so it may resume as `current` (`--keep-actor`); and //! as a node starts on the file, before it writes anything, an empty `Opened` record, //! which undoes that mark. A record cut short by a crash is dropped when reading; one of -//! a kind this version doesn't know (a later version's) makes the file unusable. A file of `continuum-document/1` has records of the document alone, -//! without their kind: a full save, then increments. +//! a kind this version doesn't know (a later version's) makes the file unusable. A file +//! of `continuum-document/2` is read as one of 3 (it has the same records, `Closed` and +//! `Opened` where a version knowing them wrote it); one of `continuum-document/1` has +//! records of the document alone, without their kind: a full save, then increments. //! //! Written by a worker (`swarm::document_file`), only while the node is ready and not //! rejoining (a rejoin keeps the old file until it is done): @@ -37,7 +39,9 @@ use crate::document::replica::Epoch; use crate::files::{FileKind, Files}; use crate::locks::MutexExt; -const MAGIC: &[u8] = b"continuum-document/2\n"; +const MAGIC: &[u8] = b"continuum-document/3\n"; +/// The format before `Closed` and `Opened`, still read as `MAGIC`. +const MAGIC_2: &[u8] = b"continuum-document/2\n"; /// The format before signatures, still read. const MAGIC_1: &[u8] = b"continuum-document/1\n"; @@ -100,7 +104,10 @@ pub(crate) fn load(path: &Path, files: &Files) -> Result<Option<Loaded>> { /// The file's content, and how many bytes at its end were cut short. fn parse(bytes: &[u8]) -> Result<(Loaded, usize)> { - let (rest, kinds) = match bytes.strip_prefix(MAGIC) { + let (rest, kinds) = match bytes + .strip_prefix(MAGIC) + .or_else(|| bytes.strip_prefix(MAGIC_2)) + { Some(rest) => (rest, true), None => ( bytes @@ -537,6 +544,9 @@ mod tests { assert!(loaded.doc.get(ROOT, "b").unwrap().is_some()); assert!(parse(b"something else").is_err()); + let mut two = MAGIC_2.to_vec(); + two.extend_from_slice(&bytes[MAGIC.len()..]); + assert!(parse(&two).unwrap().0.doc.get(ROOT, "b").unwrap().is_some()); assert!(parse(&bytes[..MAGIC.len() + 3]).is_err()); } |
