snaplock

Crates.iosnaplock
lib.rssnaplock
version0.0.5
created_at2025-10-30 00:23:54.369509+00
updated_at2025-11-02 01:16:48.465747+00
descriptionRwLock with lock-free Reads and sequential Writes
homepage
repositoryhttps://github.com/ReDestroyDeR/snaplock
max_upload_size
id1907537
size53,466
Daniil (ReDestroyDeR)

documentation

https://docs.rs/snaplock/latest/snaplock/

README

Snapshot Lock | snaplock

Harness MVCC-lock performance in-memory crates.io

This library provides ReadWriteLock - SnapshotLock, which has lock-free reads powered by Reference Counted clone that is stored near the locked value.

Choose SnapshotLock if:

  • Reads vastly outnumber writes (10:1 ratio or higher)
  • You need predictable read latency (scales linearly with minimal memory footprint)
  • Application is read-performance critical
  • You can tolerate slightly slower writes

Writes are protected by std::sync::RwLock. It also provides tokio::sync::RwLock implementation under the async feature.

Features:

  • async : Adds new_async constructor. .write() method becomes async

Example:

use snaplock::SnapshotLock;

fn main() {
    let lock = SnapshotLock::new(String::from("Hello"));

    // Multiple readers can access the data concurrently
    let reader1 = lock.read();
    let reader2 = lock.read();
    assert_eq!(*reader1, "Hello");
    assert_eq!(*reader2, "Hello");

    // Writers have exclusive access
    {
        let mut writer = lock.write();
        writer.push_str(", World!");

        // During write readers see old values
        let reader = lock.read();
        assert_eq!(*reader, "Hello");
    }

    // When write is finished, new readers see the updated value
    let reader3 = lock.read();
    assert_eq!(*reader3, "Hello, World!");

    // Old readers still see their old value
    assert_eq!(*reader1, "Hello");
    assert_eq!(*reader2, "Hello");
}

MSRV Policy:

There is none. Current Minimum Supported Rust Version is 1.85.0

Alternatives:

  • crossbeam::sync::SharedLock - A sharded reader-writer lock.
  • vlock - A fast and scalable multi-version shared state lock with wait-free read access.
  • parking_lot - More compact and efficient implementations of the standard synchronization primitives.

Benchmark:

Benchmark data was collected on:

  • Windows 10 Version 10.0.19045 Build 19045
  • AMD Ryzen 9 7900X3D 12-Core Processor

Results may vary based on hardware architecture and workload characteristics.

To run benchmarks use cargo run --release --example rwlock

Dev Profile

Write-Heavy Workload (50 writers, 5 readers)

Lock Type Writer Iterations Reader Iterations Writer/Reader
parking_lot::RwLock 2646 - 2655 2583 - 2615 1.02:1
std::sync::RwLock 2860 - 2888 755 - 765 3.78:1
seqlock::SeqLock 1313 - 1315 33621 - 33690 1:25.61
snaplock::SnapshotLock 2532 - 2635 100910 - 102094 1:39.29
crossbeam::sync::ShardedLock 2822 - 2854 1287 - 1318 2.18:1
SrwLock 2331 - 2672 1448 - 1544 1.67:1

Balanced Workload (10 writers, 10 readers)

Lock Type Writer Iterations Reader Iterations Writer/Reader
parking_lot::RwLock 8721 - 8728 8543 - 8588 1.02:1
std::sync::RwLock 14329 - 14415 966 - 984 14.74:1
seqlock::SeqLock 3056 - 3058 20560 - 21255 1:6.84
snaplock::SnapshotLock 12794 - 12928 89615 - 93864 1:7.13
crossbeam::sync::ShardedLock 6102 - 6132 1419 - 66331 1:5.54
SrwLock 9384 - 10271 5427 - 6365 1.67:1

Read-Heavy Workload (5 writers, 50 readers)

Lock Type Writer Iterations Reader Iterations Writer/Reader
parking_lot::RwLock 11175 - 11186 11127 - 11157 1:1
std::sync::RwLock 16772 - 16902 8715 - 12010 1.62:1
seqlock::SeqLock 5505 - 5516 13228 - 29256 1:3.85
snaplock::SnapshotLock 10821 - 13468 17427 - 67536 1:3.5
crossbeam::sync::ShardedLock 1 - 1202 237 - 63322 1:52.83
SrwLock 293 - 435 25271 - 31891 1:78.52
Release Profile

Write-Heavy Workload (50 writers, 5 readers)

Lock Type Writer Iterations Reader Iterations Writer/Reader Ratio
parking_lot::RwLock 36971 - 37016 37212 - 42922 1:1.08
std::sync::RwLock 169 - 233 101781 - 164053 1:661.28
seqlock::SeqLock 125082 - 125938 101491 - 268350 1:1.47
snaplock::SnapshotLock 49484 - 68635 54255 - 277519 1:2.81
crossbeam::sync::ShardedLock 1 - 784 2115 - 253801 1:326.01
SrwLock 1805 - 2032 172679 - 247496 1:109.51

Balanced Workload (10 writers, 10 readers)

Lock Type Writer Iterations Reader Iterations Writer/Reader Ratio
parking_lot::RwLock 35748 - 35892 34653 - 34855 1.03:1
std::sync::RwLock 7899 - 8752 148495 - 148745 1:17.85
seqlock::SeqLock 53776 - 53913 511459 - 515983 1:9.54
snaplock::SnapshotLock 53785 - 54012 272401 - 276799 1:5.09
crossbeam::sync::ShardedLock 4050 - 4244 9438 - 258410 1:32.29
SrwLock 30869 - 31200 48836 - 49830 1:1.59

Read-Heavy Workload (5 writers, 50 readers)

Lock Type Writer Iterations Reader Iterations Writer/Reader Ratio
parking_lot::RwLock 10693 - 10801 10223 - 10261 1.05:1
std::sync::RwLock 9467 - 9982 47042 - 47212 1:4.85
seqlock::SeqLock 10639 - 10738 532480 - 532875 1:49.84
snaplock::SnapshotLock 10964 - 11185 280155 - 280390 1:25.31
crossbeam::sync::ShardedLock 9035 - 9446 50122 - 50711 1:5.46
SrwLock 11366 - 12109 12864 - 13396 1:1.12
Commit count: 0

cargo fmt