Creating an Arc<[T]> from a VecDeque<T>


#1

Hello Rustaceans,
I am implementing code that keeps track of a sliding window of Ts, for which I’m using a VecDeque<T>. I’d like to be able to periodically clone/copy the contents of the VecDeque<T> into an Arc<[T]>, so that I can efficiently share the window with multiple threads and minimal indirection. My current best guess is to copy the VecDeque<T> into a Vec<T>, and then use .into_boxed_slice(), but even then, I’m not sure that there’s a way to go from there to Arc<[T]>. Any ideas on how to do this?

Thank you for your help!


#2

I don’t think you can create (without using unsafe) an Arc<[T]> from a slice. However, it looks like https://github.com/rust-lang/rfcs/blob/master/text/1845-shared-from-slice.md is aimed at addressing that. Given that, the easiest would be to settle for Arc<Box<[T]>>, and take an extra indirection hit.

There may be better ways (i.e. avoiding copies, possibly avoiding Arc altogether, etc) to achieve your goal, but it would depend on how you’re sharing the data amongst threads and the general flow of your app.


#3

VecDeque<T> can be converted to Vec<T> by using Vec::from method. This isn’t a free conversion as those types have different internal representation, but Rust tries to not do too much work while doing this conversion (there is special code for it).

I don’t think it’s currently possible to convert Box<Unsized> into Arc<Unsized> however at this point ([T] is unsized type).


#4

Box<[T]> and Vec<T> are (partially) representation compatible, so it’s possible to convert between them without copying; this is not possible with Arc<[T]>, it has a different representation, and yes, the API to create it is still missing anyway.

You could use Arc around any of the other types instead, once you deref it once in another thread the indirection is gone (if that helps).

Scoped threads also allow you to share with minimal indirection (no need for Arc).


#5

I actually 100% need to copy my data out of the VecDeque<T> and into the Arc<[T]>–does an API exist to create Arc<[T]>, even one that uses some unsafe code? I can’t use scoped threads for this problem, unfortunately.


#6

And Arc<Box<[T]>> won’t cut it for you?

If you’re set on going the unsafe route, the RFC link I pasted above has an proposed implementation (for Rc, but it mentions what’s needed for Arc) - here’s the exact location https://github.com/rust-lang/rfcs/blob/master/text/1845-shared-from-slice.md#suggested-implementation.


#7

The API for creating a (dynamic length) Arc<[T]> does not exist, so it’s a lot more convenient to not need it.

Static length is simple. For example from an array of 3 elements: Arc::new([1, 2, 3]) as Arc<[i32]>.


#8

One solution would be to implement FromIterator<I> for Arc<[I]>.