Skip to main content

noxu_rep/
commit_token.rs

1//! Commit tokens for commit-point read consistency.
2//!
3//! Port of `com.sleepycat.je.CommitToken` and `MasterTxn.getCommitToken`.
4//!
5//! A `CommitToken` is a bookmark into the master's serialized transaction
6//! schedule: the VLSN of a committed transaction, tagged with the identity of
7//! the replication environment that produced it.  A client that performs a
8//! write on the master receives the token (`Transaction.getCommitToken`) and
9//! can hand it to a replica read via
10//! [`crate::ConsistencyPolicy::CommitPointConsistency`]; the replica then
11//! blocks the read until it has replayed up to that VLSN (see
12//! [`crate::ConsistencyTracker`]).
13//!
14//! JE keys the token on the replication-environment UUID
15//! (`CommitToken.repenvUUID`) so a token minted by one group is rejected by
16//! another.  We use the replication *group name* as the stable rep-env
17//! identity for that same mismatch check (Noxu identifies a group by name; it
18//! has no per-env UUID).
19
20/// A bookmark identifying a specific committed transaction in the master's
21/// replication stream.
22///
23/// Port of `com.sleepycat.je.CommitToken` (`{ repenvUUID, vlsn }`).
24#[derive(Debug, Clone, PartialEq, Eq, Hash)]
25pub struct CommitToken {
26    /// Identity of the replication environment that produced this token.
27    ///
28    /// Port of `CommitToken.repenvUUID`; here the replication group name.
29    group: String,
30    /// The commit VLSN this token marks.
31    ///
32    /// Port of `CommitToken.vlsn`.
33    vlsn: u64,
34}
35
36impl CommitToken {
37    /// Create a commit token for `vlsn` produced by replication `group`.
38    ///
39    /// Port of `new CommitToken(envUUID, commitVLSN.getSequence())`
40    /// (`MasterTxn.getCommitToken`).  Mirrors JE's invariant that the VLSN
41    /// must not be NULL (0): a token with no commit VLSN is meaningless, so
42    /// returns `None` rather than minting a bogus bookmark.
43    pub fn new(group: impl Into<String>, vlsn: u64) -> Option<Self> {
44        if vlsn == 0 {
45            // CommitToken ctor: "the vlsn must not be null".
46            return None;
47        }
48        Some(Self { group: group.into(), vlsn })
49    }
50
51    /// The replication-group identity that produced this token.
52    ///
53    /// Port of `CommitToken.getRepenvUUID`.
54    pub fn group(&self) -> &str {
55        &self.group
56    }
57
58    /// The commit VLSN this token marks.
59    ///
60    /// Port of `CommitToken.getVLSN`.
61    pub fn vlsn(&self) -> u64 {
62        self.vlsn
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_new_token() {
72        let t = CommitToken::new("g1", 42).unwrap();
73        assert_eq!(t.group(), "g1");
74        assert_eq!(t.vlsn(), 42);
75    }
76
77    #[test]
78    fn test_null_vlsn_rejected() {
79        // CommitToken ctor rejects a NULL (0) VLSN.
80        assert!(CommitToken::new("g1", 0).is_none());
81    }
82
83    #[test]
84    fn test_eq_and_clone() {
85        let a = CommitToken::new("g1", 7).unwrap();
86        let b = a.clone();
87        assert_eq!(a, b);
88        let c = CommitToken::new("g2", 7).unwrap();
89        assert_ne!(a, c);
90    }
91}