A concurrent, append-only vector

Related tags

Command-line boxcar
Overview

Boxcar

Crate Github Docs

A concurrent, append-only vector.

The vector provided by this crate suports concurrent get and push operations. Reads are always lock-free, as are writes except when resizing is required.

Examples

Appending an element to a vector and retrieving it:

let vec = boxcar::Vec::new();
vec.push(42);
assert_eq!(vec[0], 42);

The vector can be shared across threads with an Arc:

use std::sync::Arc;

fn main() {
    let vec = Arc::new(boxcar::Vec::new());

    // spawn 6 threads that append to the vec
    let threads = (0..6)
        .map(|i| {
            let vec = vec.clone();

            std::thread::spawn(move || {
                vec.push(i); // push through `&Vec`
            })
        })
        .collect::<Vec<_>>();

    // wait for the threads to finish
    for thread in threads {
        thread.join().unwrap();
    }

    for i in 0..6 {
        assert!(vec.iter().any(|&x| x == i));
    }
}

Elements can be mutated through fine-grained locking:

use std::sync::{Mutex, Arc};

fn main() {
    let vec = Arc::new(boxcar::Vec::new());

    // insert an element
    vec.push(Mutex::new(1));

    let thread = std::thread::spawn({
        let vec = vec.clone();
        move || {
            // mutate through the mutex
            *vec[0].lock().unwrap() += 1;
        }
    });

    thread.join().unwrap();

    let x = vec[0].lock().unwrap();
    assert_eq!(*x, 2);
}

Details

A concurrent vector is represented as an array of lazily allocated buckets, of sizes 1, 1, 2, 4 .. 2^63:

______________________________________
|  |  |    |        |                |
|  |  |    |        |                |
--------------------------------------

A buckets holds a number entries, as well as a lock to guard againt concurrent initialization:

_____________
|  |  |  |  |
|  |  |  |  |
-------------
| UNLOCKED  |
-------------

An entry holds a slot for a value along with a flag indicating whether the slot is active:

_____________________
| ACTIVE | INACTIVE |
|   42   |   NULL   |
---------------------

Writes acquire a unique index into the vector. The bucket holding the given entry is calculated using the leading zeros instruction. If the bucket is already initialized, the value is written to the slot, and the slot is marked as active. If the bucket has not been initialized, the thread acquires the initialization lock, allocates the bucket, and then writes the value. Note that in the general case, writes are lock-free.

Reads use the same calculation to find the entry mapped to the given index, reading the value from the slot if the flag indicates the slot is active. All reads are guaranteed to be lock-free.

Performance

Below is a benchmark in which an increasing number of elements are pushed and read from the vector by 12 threads, comparing boxcar::Vec to RwLock :

Benchmark

The results show that boxcar::Vec scales very well under load, performing significantly better than lock-based solutions.

You might also like...
Boxxy puts bad Linux applications in a box with only their files.

boxxy is a tool for boxing up misbehaving Linux applications and forcing them to put their files and directories in the right place, without symlinks!

Shell Escape for Typst typesetting system. Linux Only.

Shell Escape for Typst This is a simple shell escape for Typst. It allows you to run shell commands directly from Typst compiler. That said, it does n

Prisma2D - Fast, API agnostic, software only 2D graphics crate in pure Rust.

Prisma2D: Ultra-fast CPU 2D graphics Prisma2D is a blazingly fast, efficient yet minimal crate for basic 2D graphics on the CPU. for Rust. With Prisma

A super simple /sbin/init for Linux which allows running one and only one program

Summary High-performance /sbin/init program for Linux This is designed to do literally nothing but accept binaries over the network and run them as a

Tumour-only somatic mutation calling using long reads

smrest smrest is a prototype somatic mutation caller for single molecule long reads. It uses haplotype phasing patterns for tumour samples that have a

A minimal file exchange server designed for clients with browsers only.

XIAO-Files Xiao-Files is a minimal file exchange server designed for clients with browsers only. Example Let's say we have a host with IP 10.8.20.1, a

Log structured append-only key-value store from Rust In Action with some enhancements.

riakv Log structured, append only, key value store implementation from Rust In Action with some enhancements. Features Persistent key value store with

A pure Rust database implementation using an append-only B-Tree file format.

nebari nebari - noun - the surface roots that flare out from the base of a bonsai tree Warning: This crate is early in development. The format of the

An implementation of the append-only log described in the Certificate Transparency specification (RFC 6962)

CT Merkle This is an implementation of the append-only log described in the Certificate Transparency specification (RFC 6962). The log is a Merkle tre

A lock-free, append-only atomic pool.

A lock-free, append-only atomic pool. This library implements an atomic, append-only collection of items, where individual items can be acquired and r

A simple key-value store with a log-structured, append-only storage architecture where data is encrypted with AES GCM.

akvdb A simple key-value store with a log-structured, append-only storage architecture where data is encrypted with AES GCM. Modified from the actionk

Lane-Associated Vector (LAV): Portable SIMD vector trait as GAT of SIMD lane trait.

lav Lane-Associated Vector (LAV): Portable SIMD vector trait as GAT of SIMD lane trait. NOTE: This crate requires nightly Rust. Provides SIMD lane tra

Linked Atomic Random Insert Vector: a thread-safe, self-memory-managed vector with no guaranteed sequential insert.
Linked Atomic Random Insert Vector: a thread-safe, self-memory-managed vector with no guaranteed sequential insert.

Linked Atomic Random Insert Vector Lariv is a thread-safe, self-memory-managed vector with no guaranteed sequential insert. It internally uses a linke

The core innovation of EinsteinDB is its merge-append-commit protocol

The core innovation of EinsteinDB is its merge-append-commit protocol. The protocol is friendly and does not require more than two parties to agree on the order of events. It is also relativistic and can tolerate clock and network lag and drag.

Tools for concurrent programming in Rust

Crossbeam This crate provides a set of tools for concurrent programming: Atomics AtomicCell, a thread-safe mutable memory location.(no_std) AtomicCons

An Extensible, Concurrent Web Framework for Rust

Iron Extensible, Concurrency Focused Web Development in Rust. Response Timer Example Note: This example works with the current iron code in this repos

Shuttle is a library for testing concurrent Rust code

Shuttle Shuttle is a library for testing concurrent Rust code. It is an implementation of a number of randomized concurrency testing techniques, inclu

Spawn multiple concurrent unix terminals in Discord

Using this bot can be exceedingly dangerous since you're basically granting people direct access to your shell.

A Rust synchronisation primitive for "Multiplexed Concurrent Single-Threaded Read" access

exit-left verb; 1. To exit or disappear in a quiet, non-dramatic fashion, making way for more interesting events. 2. (imperative) Leave the scene, and

Comments
  • Avoid contention when allocating buckets

    Avoid contention when allocating buckets

    Currently threads allocate the next bucket when the last bucket is full, we can instead allocate at half-way/three-quarters into the last bucket to avoid contention. This may make it more feasible for threads to race to allocate instead of locking.

    opened by ibraheemdev 0
Releases(v0.1.0)
Owner
Ibraheem Ahmed
Freelance software developer interested in concurrency, systems programming, and web servers.
Ibraheem Ahmed
A Rust synchronisation primitive for "Multiplexed Concurrent Single-Threaded Read" access

exit-left verb; 1. To exit or disappear in a quiet, non-dramatic fashion, making way for more interesting events. 2. (imperative) Leave the scene, and

Jonathan de Jong 0 Dec 5, 2021
Concurrent and multi-stage data ingestion and data processing with Rust+Tokio

TokioSky Build concurrent and multi-stage data ingestion and data processing pipelines with Rust+Tokio. TokioSky allows developers to consume data eff

DanyalMh 29 Dec 11, 2022
Implementation of CSP for concurrent programming.

CSPLib Communicating Sequential Processes (CSP) Background Communicating Sequential Processes (CSP) is a way of writing a concurrent application using

Akira Hayakawa 4 Nov 9, 2022
A lightweight async Web crawler in Rust, optimized for concurrent scraping while respecting `robots.txt` rules.

??️ crawly A lightweight and efficient web crawler in Rust, optimized for concurrent scraping while respecting robots.txt rules. ?? Features Concurren

CrystalSoft 5 Aug 29, 2023
Rust Statistics and Vector Algebra Library

Rstats Usage Insert rstats = "^1" in the Cargo.toml file, under [dependencies]. Use in source files any of the following structs, as needed: use rstat

null 16 Oct 9, 2022
Check the reproducibility status of your Arch Linux packages (read-only mirror)

arch-repro-status A CLI tool for querying the reproducibility status of the Arch Linux packages using data from a rebuilderd instance such as reproduc

Arch Linux 12 Nov 16, 2022
Work-in-progress Rust application that converts C++ header-only libraries to single self-contained headers.

unosolo Work-in-progress Rust application that converts C++ header-only libraries to single self-contained headers. Disclaimer This is my first Rust p

Vittorio Romeo 26 Jul 9, 2021
Answering the question nobody asked: what if you wanted to text your friends using only ARP?

arpchat so... you know arp? the protocol your computer uses to find the mac addresses of other computers on your network? yeah. that. i thought it wou

Kognise 1.3k Jan 1, 2023
try to find the correct word with only first letter and unknown letter count.

MOTUS Current dictionaries are provided in french and can contain some words not included in the official Motus dictionary. Additionally, dictionaries

Alexandre 6 Apr 11, 2022
A complete imgui-rs example using dependencies only from crates.io.

Dear imgui-rs, hello. This is a fairly basic, but complete and standalone example application for the Rust version of dear imgui (https://github.com/o

null 0 Nov 30, 2022