loro_internal/
change_meta.rs

1use std::{cmp::Ordering, sync::Arc};
2
3use loro_common::HasLamport;
4use rle::HasLength;
5
6use crate::{
7    change::{Change, Lamport, Timestamp},
8    id::ID,
9    version::Frontiers,
10};
11
12/// `Change` is a grouped continuous operations that share the same id, timestamp, commit message.
13///
14/// - The id of the `Change` is the id of its first op.
15/// - The second op's id is `{ peer: change.id.peer, counter: change.id.counter + 1 }`
16///
17/// The same applies on `Lamport`:
18///
19/// - The lamport of the `Change` is the lamport of its first op.
20/// - The second op's lamport is `change.lamport + 1`
21///
22/// The length of the `Change` is how many operations it contains
23#[derive(Debug, Clone)]
24pub struct ChangeMeta {
25    /// Lamport timestamp of the Change
26    pub lamport: Lamport,
27    /// The first Op id of the Change
28    pub id: ID,
29    /// [Unix time](https://en.wikipedia.org/wiki/Unix_time)
30    /// It is the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970.
31    pub timestamp: Timestamp,
32    /// The commit message of the change
33    pub message: Option<Arc<str>>,
34    /// The dependencies of the first op of the change
35    pub deps: Frontiers,
36    /// The total op num inside this change
37    pub len: usize,
38}
39
40impl PartialEq for ChangeMeta {
41    fn eq(&self, other: &Self) -> bool {
42        self.lamport == other.lamport && self.id == other.id
43    }
44}
45
46impl Eq for ChangeMeta {}
47
48impl PartialOrd for ChangeMeta {
49    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
50        Some(self.cmp(other))
51    }
52}
53
54impl Ord for ChangeMeta {
55    fn cmp(&self, other: &Self) -> Ordering {
56        (self.lamport + self.len as Lamport)
57            .cmp(&(other.lamport + other.len as Lamport))
58            .then(self.id.peer.cmp(&other.id.peer))
59    }
60}
61
62impl HasLamport for ChangeMeta {
63    fn lamport(&self) -> loro_common::Lamport {
64        self.lamport
65    }
66}
67
68impl HasLength for ChangeMeta {
69    fn content_len(&self) -> usize {
70        self.len
71    }
72}
73
74impl ChangeMeta {
75    pub fn from_change(c: &Change) -> Self {
76        Self {
77            id: c.id(),
78            lamport: c.lamport(),
79            timestamp: c.timestamp(),
80            message: c.message().cloned(),
81            deps: c.deps().clone(),
82            len: c.len(),
83        }
84    }
85
86    /// Get the commit message in &str
87    pub fn message(&self) -> &str {
88        match self.message.as_ref() {
89            Some(m) => m,
90            None => "",
91        }
92    }
93
94    /// Get the commit timestamp in seconds since Unix epoch.
95    pub fn timestamp(&self) -> crate::change::Timestamp {
96        self.timestamp
97    }
98}