#slice #shared #lifetime #thread-safe #thread-local #data-structures #environments

nightly shared_slice

Thread-local and thread-safe shared slice types, like &[T] but without lifetimes. This library depends only on alloc and core, so can be used in environments without std.

4 releases

Uses old Rust 2015

0.0.4 May 19, 2015
0.0.3 Feb 2, 2015
0.0.2 Jan 9, 2015
0.0.1 Jan 2, 2015

#716 in Memory management

MIT/Apache

24KB
457 lines

shared_slice

Build Status

Thread-local and thread-safe shared slice types, like &[T] but without lifetimes. This library depends only on alloc and core, so can be used in environments without std.

Documentation

Package listing


lib.rs:

Thread-local and thread-safe shared slice types, like &[T] but without lifetimes.

This library depends only on alloc and core, so can be used in environments without std.

Examples

Alice has a long list of numbers which she needs to sum up before she's allowed to enter Wonderland. She's impatient to get there and she has a computer with many cores so she wants to use all of them.

Using a ArcSlice, she can manually divide up the numbers into chunks and distribute them across some threads.

#![feature(std_misc)]
extern crate shared_slice;
extern crate rand;

use shared_slice::arc::ArcSlice;
use std::{cmp, sync};


// Alice's numbers (the Mad Hatter doesn't care which numbers,
// just that they've been summed up).
let numbers = (0..10_000)
    .map(|_| rand::random::<u64>() % 100)
    .collect::<Vec<_>>();


const NTHREADS: usize = 10;

let numbers = ArcSlice::new(numbers.into_boxed_slice());

// number of elements per thread (rounded up)
let per_thread = (numbers.len() + NTHREADS - 1) / NTHREADS;

let mut futures = (0..NTHREADS).map(|i| {
    // compute the bounds
    let lo = i * per_thread;
    let hi = cmp::min(numbers.len(), lo + per_thread);

    // extract the subsection of the vector that we care about,
    // note that the `clone` (which just increases the reference
    // counts) is necessary because `ArcSlice::slice` consumes
    // the receiver (in order to minimise unnecessary reference
    // count modifications).
    let my_numbers: ArcSlice<_> = numbers.clone().slice(lo, hi);

    // do this part of the sum:
    sync::Future::spawn(move || {
        my_numbers.iter().fold(0, |a, &b| a + b)
    })
}).collect::<Vec<sync::Future<u64>>>();

// sum up the results from each subsum.
let sum = futures.iter_mut().fold(0, |a, b| a + b.get());

println!("the sum is {}", sum);

(NB. ArcSlice may become unnecessary for situations like this if Send stops implying 'static, since it is likely that one will be able to use conventional borrowed &[T] slices directly.)

No runtime deps