Struct range_lock::RepVecRangeLock[][src]

pub struct RepVecRangeLock<T> { /* fields omitted */ }
Expand description

Interleaved multi-thread range lock for Vec<T>.

Each thread can lock a set of repeating slices of the data. The slices are interleaved with each other and the slice pattern cyclically repeats at cycle_len rate.

Offsets are not bound to one specific thread.

Please see the example below.

Example

use range_lock::RepVecRangeLock;
use std::sync::Arc;
use std::thread;

let data = vec![1, 2,  3, 4,   5,  6,   // <- cycle 0
                7, 8,  9, 10,  11, 12]; // <- cycle 1
//              ^--^   ^---^   ^----^
//                |      |      |
//          offset-0  offset-1  offset-2

let lock = Arc::new(RepVecRangeLock::new(data,
                                         2,    // slice_len: Each slice has 2 elements.
                                         3));  // cycle_len: Each cycle has 3 slices (offsets).
let lock0 = Arc::clone(&lock);
let lock1 = Arc::clone(&lock);
let lock2 = Arc::clone(&lock);

let thread0 = thread::spawn(move || {
    // Lock slice offset 0:
    let mut guard = lock0.try_lock(0).expect("Failed to lock offset.");

    // Read:
    assert_eq!(guard[0][0], 1);     // Cycle 0, Slice element 0
    assert_eq!(guard[0][1], 2);     // Cycle 0, Slice element 1
    // let _ = guard[0][2];         // Would panic. Slice len is only 2.
    assert_eq!(guard[1][0], 7);     // Cycle 1, Slice element 0
    assert_eq!(guard[1][1], 8);     // Cycle 1, Slice element 1
    // let _ = guard[2][0];         // Would panic: The data vec is only 2 repeat cycles long.

    // Write:
    guard[0][0] = 10;               // Cycle 0, Slice element 0
    guard[0][1] = 20;               // Cycle 0, Slice element 1
    // guard[0][2] = 42;            // Would panic: Slice len is only 2.
    guard[1][0] = 30;               // Cycle 1, Slice element 0
    guard[1][1] = 40;               // Cycle 1, Slice element 1
    // guard[2][0] = 42;            // Would panic: The data vec is only 2 repeat cycles long.
});

let thread1 = thread::spawn(move || {
    // Lock slice offset 1:
    let mut guard = lock1.try_lock(1).expect("Failed to lock offset.");

    guard[0][0] = 100;              // Cycle 0, Slice element 0
    guard[0][1] = 200;              // Cycle 0, Slice element 1
    guard[1][0] = 300;              // Cycle 1, Slice element 0
    guard[1][1] = 400;              // Cycle 1, Slice element 1
});

let thread2 = thread::spawn(move || {
    // Lock slice offset 2:
    let mut guard = lock2.try_lock(2).expect("Failed to lock offset.");

    guard[0][0] = 1000;             // Cycle 0, Slice element 0
    guard[0][1] = 2000;             // Cycle 0, Slice element 1
    guard[1][0] = 3000;             // Cycle 1, Slice element 0
    guard[1][1] = 4000;             // Cycle 1, Slice element 1
});

thread0.join();
thread1.join();
thread2.join();

// Get the data that has been modified by the threads.
let data = Arc::try_unwrap(lock).expect("Thread is still using data.").into_inner();

assert_eq!(data,
           vec![10, 20, 100, 200, 1000, 2000,
                30, 40, 300, 400, 3000, 4000]);

Implementations

Construct a new RepVecRangeLock.

  • data: The data Vec to protect.
  • slice_len: The length of the slices, in number of elements. Must be >0.
  • cycle_len: The length of the repeat cycle, in number of slices. Must be >0 and <=usize::MAX-31.

Get the length (in number of elements) of the embedded Vec.

Unwrap the VecRangeLock into the contained data. This method consumes self.

Try to lock the given data slice at ‘cycle_offset’.

  • On success: Returns a RepVecRangeLockGuard that can be used to access the locked region. Indexing RepVecRangeLockGuard yields a slice of the data.
  • On failure: Returns TryLockError::WouldBlock, if the slice is contended. The locking attempt may be retried by the caller upon contention. Returns TryLockError::Poisoned, if the lock is poisoned.

Trait Implementations

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.