Skip to content

TheDhejavu/logical-clocks-rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

logical-clocks-rs

A logical clock is a mechanism for capturing chronological and causal relationships in a distributed system. This crate provides an implementation of Lamport Clock, Vector Clock, which are a type of logical clock used to order events in a distributed system.

Usage

Add to your Cargo.toml

Add the following to your Cargo.toml to include the logical-clocks-rs crate:

[dependencies]
logical-clocks-rs = { git =  "https://github.com/TheDhejavu/logical-clocks-rs.git" }

Lamport Clock

Lamport timestamps are used to capture the order of events in a distributed system. They follow these simple rules:

  1. A process increments its counter before each event in that process.
  2. When a process sends a message, it includes its counter value with the message.
  3. On receiving a message, the receiver process sets its counter to be greater than the maximum of its own value and the received value before it considers the message received.

Source: Lamport & Vector Clocks

Examples

Using Default Identifier

use logical_clocks_rs::{LamportClock, LamportTime, Identifier};

fn main() {
    // Create a new Lamport clock with a default identifier
    let clock = LamportClock::new();

    // Increment the clock and print the time
    let time1 = clock.increment();
    println!("Time after increment: {:?}", time1);

    // Get the current time and print it
    let time2 = clock.time();
    println!("Current time: {:?}", time2);

    // Compare a higher Lamport time from another process
    clock.compare(LamportTime(10, Identifier::default()));
    let time3 = clock.time();
    println!("Current time after witness: {:?}", time3);
}

Using Custom Identifier

use logical_clocks_rs::{LamportClock, Identifier};
use uuid::Uuid;

fn main() {
    // Create a new Lamport clock with a custom identifier
    let custom_identifier = Uuid::new_v4().as_bytes().to_vec();
    let custom_clock = LamportClock::with_custom_identifier(custom_identifier);

    // Increment the custom clock and print the time
    let custom_time1 = custom_clock.increment();
    println!("Custom clock time after increment: {:?}", custom_time1);

    // Get the current time of the custom clock and print it
    let custom_time2 = custom_clock.time();
    println!("Custom clock current time: {:?}", custom_time2);
}

Vector Clock

A vector clock is an array of logical clocks, each representing a node in a distributed system. Each node maintains a vector of counters, where each counter corresponds to another node.

Examples

use logical_clocks_rs::{Identifier, VClock, Vector};

extern crate logical_clocks_rs;

fn main() {
    // === 
    // Create identifiers for nodes/processes
    let id1 = Identifier::new();
    let id2 = Identifier::new();

    // Create vector clocks for two nodes
    let mut vclock1 = VClock::new();
    let mut vclock2 = VClock::new();

    // Increment the clocks
    vclock1.increment(&id1);
    vclock1.increment(&id1);
    vclock2.increment(&id2);

    println!("VClock 1: {:?}", vclock1.time());
    println!("VClock 2: {:?}", vclock2.time());

    // Merge the second clock into the first
    vclock1.merge(&vclock2);
    println!("After merging VClock 2 into VClock 1: {:?}", vclock1.time());

    // ====  WITH VECTOR === 
    // Create a Vector and initialize it
    let mut vector = Vector::new();
    vector.add(id1.clone()).add(id2.clone());

    //  Initialize VClock with the vector
    let mut vclock4 = VClock::with_vector(vector);
    vclock4.increment(&id1);
    vclock4.increment(&id2);
}

API Documentation

LamportClock

Methods

  • new() -> Self: Creates a new Lamport clock with a default identifier.
  • with_new_identifier(id: Identifier) -> Self: Creates a new Lamport clock with a specified identifier.
  • with_custom_identifier(bytes: Vec<u8>) -> Self: Creates a new Lamport clock with a custom identifier.
  • time(&self) -> LamportTime: Returns the current value of the Lamport clock.
  • increment(&self) -> LamportTime: Increments the Lamport clock and returns the new value.
  • compare(&self, v: LamportTime): Updates the local clock if necessary after witnessing a clock value from another process.
  • to_bytes(&self) -> Vec<u8>: Serializes the Lamport clock to bytes.
  • from_bytes(data: &[u8]) -> Option<Self>: Deserializes the Lamport clock from bytes.

VectorClock

Methods

  • new() -> Self: Creates a new empty vector clock.
  • with_vector(vector: Vector) -> Self: Creates a new vector clock with the given vector.
  • increment(&mut self, node_id: &Identifier): Increments the logical clock for the current node.
  • merge(&mut self, other: &VClock): Merges another vector clock into this one.
  • happened_before(&self, other: &VClock) -> bool: Checks if this vector clock happened before another vector clock.
  • time(&self) -> VClockTime: Returns the current vector clock time.

Vector

Methods

  • new() -> Self: Creates a new empty vector.
  • add(&mut self, id: Identifier) -> &mut Self: Adds an identifier to the vector and initializes it to zero.

References

About

Rust Implementation of various logical clocks in the ordering of system events.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages