diff --git a/src/gtree.rs b/src/gtree.rs index ba69ecd..401767c 100644 --- a/src/gtree.rs +++ b/src/gtree.rs @@ -142,7 +142,7 @@ impl InodeIdx { /// /// 2. For the root node, to indicate that it has no parent. #[inline] - const fn dangling() -> Self { + pub(crate) const fn dangling() -> Self { Self(usize::MAX) } @@ -182,10 +182,15 @@ impl LeafIdx { /// Returns a "dangling" index which doesn't point to any leaf of the /// Gtree. #[inline] - pub const fn dangling() -> Self { + pub(crate) const fn dangling() -> Self { Self::new(usize::MAX) } + #[inline] + pub(crate) fn into_usize(self) -> usize { + self.idx + } + #[inline] const fn new(idx: usize) -> Self { Self { idx, _pd: PhantomData } diff --git a/src/run_tree.rs b/src/run_tree.rs index d19d4f7..be23e7d 100644 --- a/src/run_tree.rs +++ b/src/run_tree.rs @@ -1129,6 +1129,18 @@ mod encode { use crate::gtree::{encode::InodeDecodeError, Inode, InodeIdx, Lnode}; use crate::run_indices::{Fragment, Fragments, ReplicaIndices}; + impl EditRun { + #[inline(always)] + fn dummy() -> Self { + Self { + text: Text::new(0, 0..0), + run_ts: 0, + lamport_ts: 0, + is_deleted: false, + } + } + } + impl Encode for RunTree { #[inline] fn encode(&self, buf: &mut Vec) { @@ -1136,6 +1148,8 @@ mod encode { (indices.len() as u64).encode(buf); + (self.gtree.num_leaves() as u64).encode(buf); + for (&replica_id, indices) in indices { ReplicaRuns::new(replica_id, indices, &self.gtree).encode(buf); } @@ -1210,10 +1224,17 @@ mod encode { #[inline] fn decode(buf: &[u8]) -> Result<(Self, &[u8]), Self::Error> { - let (num_replicas, mut buf) = u64::decode(buf)?; + let (num_replicas, buf) = u64::decode(buf)?; + + let (num_leaves, mut buf) = u64::decode(buf)?; let mut ctx = RunTreeDecodeCtx::default(); + let dummy_lnode = + Lnode::new(EditRun::dummy(), InodeIdx::dangling()); + + ctx.lnodes.resize(num_leaves as usize, dummy_lnode); + for _ in 0..num_replicas { ((), buf) = ReplicaRuns::decode(buf, &mut ctx)?; ctx.replica_indices.clear(); @@ -1411,7 +1432,8 @@ mod encode { let edit_run = EditRun::new(text, ctx.run_ts, lamport_ts, is_deleted); - ctx.lnodes.push(Lnode::new(edit_run, parent_idx)); + ctx.lnodes[leaf_idx.into_usize()] = + Lnode::new(edit_run, parent_idx); Ok(((), buf)) }