snaplock 0.0.5

RwLock with lock-free Reads and sequential Writes
Documentation
# Snapshot Lock | [snaplock]https://crates.io/crates/snaplock

*Harness MVCC-lock performance in-memory*
[crates.io](https://crates.io/crates/snaplock)

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:

```rust
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`]https://docs.rs/crossbeam/latest/crossbeam/sync/struct.ShardedLock.html - A sharded
  reader-writer lock.
- [vlock]https://crates.io/crates/vlock - A fast and scalable multi-version shared state lock with wait-free read
  access.
- [parking_lot]https://crates.io/crates/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`

<details>
<summary>Dev Profile</summary>

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       |

</details>
<details>
<summary>Release Profile</summary>

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              |

</details>