Skip to content

Commit 6e4c7ee

Browse files
authored
Merge pull request #799 from rust-ndarray/owned-repr
Make OwnedRepr an "aliasable owner" instead of using Vec
2 parents 6fea7aa + c4b562d commit 6e4c7ee

File tree

4 files changed

+118
-25
lines changed

4 files changed

+118
-25
lines changed

src/data_repr.rs

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
2+
use std::mem;
3+
use std::ptr::NonNull;
4+
use std::slice;
5+
use crate::extension::nonnull;
6+
7+
/// Array's representation.
8+
///
9+
/// *Don’t use this type directly—use the type alias
10+
/// [`Array`](type.Array.html) for the array type!*
11+
// Like a Vec, but with non-unique ownership semantics
12+
#[derive(Debug)]
13+
pub struct OwnedRepr<A> {
14+
ptr: NonNull<A>,
15+
len: usize,
16+
capacity: usize,
17+
}
18+
19+
impl<A> OwnedRepr<A> {
20+
pub(crate) fn from(mut v: Vec<A>) -> Self {
21+
let len = v.len();
22+
let capacity = v.capacity();
23+
let ptr = nonnull::nonnull_from_vec_data(&mut v);
24+
mem::forget(v);
25+
Self {
26+
ptr,
27+
len,
28+
capacity,
29+
}
30+
}
31+
32+
pub(crate) fn into_vec(mut self) -> Vec<A> {
33+
let v = self.take_as_vec();
34+
mem::forget(self);
35+
v
36+
}
37+
38+
pub(crate) fn as_slice(&self) -> &[A] {
39+
unsafe {
40+
slice::from_raw_parts(self.ptr.as_ptr(), self.len)
41+
}
42+
}
43+
44+
pub(crate) fn len(&self) -> usize { self.len }
45+
46+
pub(crate) fn as_ptr(&self) -> *const A {
47+
self.ptr.as_ptr()
48+
}
49+
50+
pub(crate) fn as_nonnull_mut(&mut self) -> NonNull<A> {
51+
self.ptr
52+
}
53+
54+
fn take_as_vec(&mut self) -> Vec<A> {
55+
let capacity = self.capacity;
56+
let len = self.len;
57+
self.len = 0;
58+
self.capacity = 0;
59+
unsafe {
60+
Vec::from_raw_parts(self.ptr.as_ptr(), len, capacity)
61+
}
62+
}
63+
}
64+
65+
impl<A> Clone for OwnedRepr<A>
66+
where A: Clone
67+
{
68+
fn clone(&self) -> Self {
69+
Self::from(self.as_slice().to_owned())
70+
}
71+
72+
fn clone_from(&mut self, other: &Self) {
73+
let mut v = self.take_as_vec();
74+
let other = other.as_slice();
75+
76+
if v.len() > other.len() {
77+
v.truncate(other.len());
78+
}
79+
let (front, back) = other.split_at(v.len());
80+
v.clone_from_slice(front);
81+
v.extend_from_slice(back);
82+
*self = Self::from(v);
83+
}
84+
}
85+
86+
impl<A> Drop for OwnedRepr<A> {
87+
fn drop(&mut self) {
88+
if self.capacity > 0 {
89+
// drop as a Vec.
90+
self.take_as_vec();
91+
}
92+
}
93+
}
94+
95+
unsafe impl<A> Sync for OwnedRepr<A> where A: Sync { }
96+
unsafe impl<A> Send for OwnedRepr<A> where A: Send { }
97+

src/data_traits.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
//! The data (inner representation) traits for ndarray
1010
11-
use crate::extension::nonnull::nonnull_from_vec_data;
1211
use rawpointer::PointerExt;
1312
use std::mem::{self, size_of};
1413
use std::ptr::NonNull;
@@ -188,7 +187,7 @@ unsafe impl<A> RawDataClone for RawViewRepr<*mut A> {
188187
unsafe impl<A> RawData for OwnedArcRepr<A> {
189188
type Elem = A;
190189
fn _data_slice(&self) -> Option<&[A]> {
191-
Some(&self.0)
190+
Some(self.0.as_slice())
192191
}
193192
private_impl! {}
194193
}
@@ -226,7 +225,7 @@ where
226225
};
227226
let rvec = Arc::make_mut(rcvec);
228227
unsafe {
229-
self_.ptr = nonnull_from_vec_data(rvec).offset(our_off);
228+
self_.ptr = rvec.as_nonnull_mut().offset(our_off);
230229
}
231230
}
232231

@@ -242,7 +241,7 @@ unsafe impl<A> Data for OwnedArcRepr<A> {
242241
D: Dimension,
243242
{
244243
Self::ensure_unique(&mut self_);
245-
let data = OwnedRepr(Arc::try_unwrap(self_.data.0).ok().unwrap());
244+
let data = Arc::try_unwrap(self_.data.0).ok().unwrap();
246245
ArrayBase {
247246
data,
248247
ptr: self_.ptr,
@@ -264,7 +263,7 @@ unsafe impl<A> RawDataClone for OwnedArcRepr<A> {
264263
unsafe impl<A> RawData for OwnedRepr<A> {
265264
type Elem = A;
266265
fn _data_slice(&self) -> Option<&[A]> {
267-
Some(&self.0)
266+
Some(self.as_slice())
268267
}
269268
private_impl! {}
270269
}
@@ -303,10 +302,10 @@ where
303302
{
304303
unsafe fn clone_with_ptr(&self, ptr: NonNull<Self::Elem>) -> (Self, NonNull<Self::Elem>) {
305304
let mut u = self.clone();
306-
let mut new_ptr = nonnull_from_vec_data(&mut u.0);
305+
let mut new_ptr = u.as_nonnull_mut();
307306
if size_of::<A>() != 0 {
308307
let our_off =
309-
(ptr.as_ptr() as isize - self.0.as_ptr() as isize) / mem::size_of::<A>() as isize;
308+
(ptr.as_ptr() as isize - self.as_ptr() as isize) / mem::size_of::<A>() as isize;
310309
new_ptr = new_ptr.offset(our_off);
311310
}
312311
(u, new_ptr)
@@ -318,12 +317,12 @@ where
318317
ptr: NonNull<Self::Elem>,
319318
) -> NonNull<Self::Elem> {
320319
let our_off = if size_of::<A>() != 0 {
321-
(ptr.as_ptr() as isize - other.0.as_ptr() as isize) / mem::size_of::<A>() as isize
320+
(ptr.as_ptr() as isize - other.as_ptr() as isize) / mem::size_of::<A>() as isize
322321
} else {
323322
0
324323
};
325-
self.0.clone_from(&other.0);
326-
nonnull_from_vec_data(&mut self.0).offset(our_off)
324+
self.clone_from(&other);
325+
self.as_nonnull_mut().offset(our_off)
327326
}
328327
}
329328

@@ -413,16 +412,16 @@ unsafe impl<'a, A> DataShared for ViewRepr<&'a A> {}
413412

414413
unsafe impl<A> DataOwned for OwnedRepr<A> {
415414
fn new(elements: Vec<A>) -> Self {
416-
OwnedRepr(elements)
415+
OwnedRepr::from(elements)
417416
}
418417
fn into_shared(self) -> OwnedRcRepr<A> {
419-
OwnedArcRepr(Arc::new(self.0))
418+
OwnedArcRepr(Arc::new(self))
420419
}
421420
}
422421

423422
unsafe impl<A> DataOwned for OwnedArcRepr<A> {
424423
fn new(elements: Vec<A>) -> Self {
425-
OwnedArcRepr(Arc::new(elements))
424+
OwnedArcRepr(Arc::new(OwnedRepr::from(elements)))
426425
}
427426

428427
fn into_shared(self) -> OwnedRcRepr<A> {

src/impl_owned_array.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,22 @@ impl<A> Array<A, Ix0> {
2323
/// let scalar: Foo = array.into_scalar();
2424
/// assert_eq!(scalar, Foo);
2525
/// ```
26-
pub fn into_scalar(mut self) -> A {
26+
pub fn into_scalar(self) -> A {
2727
let size = ::std::mem::size_of::<A>();
2828
if size == 0 {
2929
// Any index in the `Vec` is fine since all elements are identical.
30-
self.data.0.remove(0)
30+
self.data.into_vec().remove(0)
3131
} else {
3232
// Find the index in the `Vec` corresponding to `self.ptr`.
3333
// (This is necessary because the element in the array might not be
3434
// the first element in the `Vec`, such as if the array was created
3535
// by `array![1, 2, 3, 4].slice_move(s![2])`.)
3636
let first = self.ptr.as_ptr() as usize;
37-
let base = self.data.0.as_ptr() as usize;
37+
let base = self.data.as_ptr() as usize;
3838
let index = (first - base) / size;
3939
debug_assert_eq!((first - base) % size, 0);
4040
// Remove the element at the index and return it.
41-
self.data.0.remove(index)
41+
self.data.into_vec().remove(index)
4242
}
4343
}
4444
}
@@ -58,7 +58,7 @@ where
5858
/// If the array is in standard memory layout, the logical element order
5959
/// of the array (`.iter()` order) and of the returned vector will be the same.
6060
pub fn into_raw_vec(self) -> Vec<A> {
61-
self.data.0
61+
self.data.into_vec()
6262
}
6363
}
6464

src/lib.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ mod arraytraits;
152152
mod argument_traits;
153153
pub use crate::argument_traits::AssignElem;
154154
mod data_traits;
155+
mod data_repr;
155156

156157
pub use crate::aliases::*;
157158

@@ -1388,12 +1389,8 @@ pub type RawArrayView<A, D> = ArrayBase<RawViewRepr<*const A>, D>;
13881389
/// [`from_shape_ptr`](#method.from_shape_ptr) for details.
13891390
pub type RawArrayViewMut<A, D> = ArrayBase<RawViewRepr<*mut A>, D>;
13901391

1391-
/// Array's representation.
1392-
///
1393-
/// *Don’t use this type directly—use the type alias
1394-
/// [`Array`](type.Array.html) for the array type!*
1395-
#[derive(Clone, Debug)]
1396-
pub struct OwnedRepr<A>(Vec<A>);
1392+
pub use data_repr::OwnedRepr;
1393+
13971394

13981395
/// RcArray's representation.
13991396
///
@@ -1407,7 +1404,7 @@ pub use self::OwnedArcRepr as OwnedRcRepr;
14071404
/// *Don’t use this type directly—use the type alias
14081405
/// [`ArcArray`](type.ArcArray.html) for the array type!*
14091406
#[derive(Debug)]
1410-
pub struct OwnedArcRepr<A>(Arc<Vec<A>>);
1407+
pub struct OwnedArcRepr<A>(Arc<OwnedRepr<A>>);
14111408

14121409
impl<A> Clone for OwnedArcRepr<A> {
14131410
fn clone(&self) -> Self {

0 commit comments

Comments
 (0)