[][src]Crate cow_vec_item

This is the documentation for cow_vec_item.

Introduction to cow_vec_item

This is small wrapper crate which implements a copy-on-write version of Vec: CowVec.

This means CowVec is constructed from a reference to some shared Vec. The CowVec can then be used just as if it was a mutable Vec, but will copy the contents of the referenced Vec on demand, if needed.

The extra value it brings over an std::borrow::Cow is that it allows starting a mutable iteration over the wrapped Vec, but delaying cloning until an actual mutation occurs (or skipping the clone completely if no iterated value is actually mutated).

An example:

extern crate cow_vec_item;
use cow_vec_item::CowVec;


let mut big_vec = vec!["lion", "tiger", "dragon"];

let mut copy_on_write_ref = CowVec::from(&big_vec);

// Just ensure there are no dragons, then print stuff
for mut item in copy_on_write_ref.iter_mut() {
    // Do lots of stuff
    if *item == "dragon" { //Dragons are not allowed here.
        *item = "sparrow"; // The entire big_vec will be cloned here
    }
}

for item in copy_on_write_ref.iter() {
    println!("Animal: {}", *item); //Don't worry, no dragons here
}

// Iterating over a CowVec using a mutable iterator has some overhead. If you don't absolutely need an
// actual iterator, the fast_for_each_mut method can beused.
copy_on_write_ref.fast_for_each_mut(|item|{
    println!("Animal: {}", **item)
});

// You can also get an owned vector, in this example only when changes were detected
if copy_on_write_ref.is_owned() {
    let my_private_vec : Vec<&str> = copy_on_write_ref.to_owned();
}

Details

For the sake of this document, the term "taking ownership" means to ensure that the contents of the CowVec is owned. When taking ownership, the borrowed Vec is cloned.

CowVec is basically an enum with two variants, Owned and Borrowed. The Owned variant owns a Vec, whereas the Borrowed variant has a shared reference to some other Vec. The typical use case is to create an instance of CowVec borrowing another Vec, only taking ownership if necessary.

CowVec implements both Deref and DerefMut, allowing access to all the standard methods on Vec.

Using DerefMut immediately ensures the contents are owned. For maximum efficiency, make sure not to use mutating methods unless needed.

To be able to iterate mutably without eagerly cloning the underlying Vec, a special iter_mut implementation is provided by CowVec. When using this method on CowVec, the returned values are not the actual contained items T, but rather a wrapper which dereferences to T. This means you can iterate mutably over a CowVec just as if it were a regular Vec. Only if you actually mutate the T, will the ownership be taken. (Ownership is also taken if deref_mut() is called without any actual write to the underlying T, CowVec does not detect this case so be sure to only obtain mutable references to T if you are actually going to write to them).

Multithreading

CowVec is Send and Sync if its contents are.

This is thought to be safe, only because it is not possible to have multiple iterated values alive. Otherwise, different values could be sent to different threads, and simultaneously attempt to take ownership.

Since only one value can be alive at the same time, it should be safe to create an iterator, get a value, send the value to another thread, and take ownership in this other thread.

Performance

As long as the fast_for_each_mut method is used to iterate, the performance overhead is negligible. If a real mutable iterator is needed, there is significant overhead. This is because of the safety checks cow_vec_item does in order to ensure safety.

Unsafe code

cow_vec_item uses a lot of unsafe code, mostly for performance reasons. There is a test suite with reasonable performance, and running 'cargo miri test' does not detect any errors.

The intent is for the end result to be sound according to the rust rules for unsafe code. Bugs are always a possibility.

Structs

BorrowedFastForeachItem

Internal helper struct. Concrete type of argument to user supplied closure in fast_for_each.

CowVec

A copy-on-write wrapper around a Vec.

CowVecItemWrapper

A placeholder representing a value being iterated over - the return value of the next() function on CowVecIter

CowVecIter

Mutable smart iterator over a CowVec. This is an internal detail that shouldn't be used directly.

CowVecMain

An internal helper class

OwnedForEachItem

Internal helper struct. Concrete type of argument to user supplied closure in fast_for_each.

Traits

FastForeachItem

Internal helper trait, argument to use supplied closure in fast_for_each