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