-
Notifications
You must be signed in to change notification settings - Fork 224
Added COW semantics to Buffer
, Bitmap
and some arrays
#794
Conversation
Codecov Report
@@ Coverage Diff @@
## main #794 +/- ##
==========================================
+ Coverage 71.08% 71.46% +0.38%
==========================================
Files 319 320 +1
Lines 16672 16731 +59
==========================================
+ Hits 11851 11957 +106
+ Misses 4821 4774 -47
Continue to review full report at Codecov.
|
Thanks!! Miri passed 🎉 . I cross-posted it here: https://users.rust-lang.org/t/add-cow-to-an-optional-foreign-pointer-soundness/71091 and will ping dark-arts folks for feedback. |
Could it make sense to add an API for |
I believe we have that. for Buffer /// Try to get a hold to the inner data as `&mut Vec`.
/// This will only succeed if the `reference count == 1` and the data
/// is allocated by this program.
pub fn get_vec(&mut self) -> Option<&mut Vec<T>> {
if self.offset != 0 {
None
} else {
Arc::get_mut(&mut self.data).map(|b| b.get_vec()).flatten()
}
} for Bitmap /// Try to convert this `Bitmap` to a `MutableBitmap`
pub fn into_mut(mut self) -> MaybeMut<Self, MutableBitmap> {
match (
self.offset,
Arc::get_mut(&mut self.bytes).map(|b| b.get_vec()).flatten(),
) {
(0, Some(v)) => {
let data = std::mem::take(v);
MaybeMut::Mutable(MutableBitmap::from_vec(data, self.length))
}
_ => MaybeMut::Immutable(self),
}
} The reason we take For this reason we return |
ccdbb1e
to
d256c61
Compare
d256c61
to
423935f
Compare
I went through this and looks great. Great work, @ritchie46 (and Imagine quite fun)! I want to give this a spin locally before merging, if that is ok for you. |
Awesome! This will open up really cool things! :) |
I went through the changes locally and dropped a PR to your branch. I would like to propose a further modification (separate from that PR). While reviewing, I noticed that we currently deref However, if we offer a One way to approach this to offer an Also, I would consider renaming What do you think, @ritchie46 ? |
Thank you! I will take a look. Regarding
This should not matter because we only share a
In that case a deallocation is completely safe. Even a reallocation is fine because In the case of a foreign allocated pointer you just cannot get a |
Sorry, the invariant that I am referring to is that An alternative behavior is to not allow |
Sorry, I now understand your suggestion. Agree! :)
Yes, I thought about this one. I will modify it and use |
Awesome. So we can even remove very hot a check by this. 🎉 |
26cf18f
to
5ed0c43
Compare
This is very cool, nice work @ritchie46 . Exactly what we needed in delta-rs :D |
PrimitiveArray -> MutableArray
Buffer
, Bitmap
and some arrays
This is awesome. As a Rust newbie, I'm struggling with fighting the borrow checker when attempting to go from a e.g. // This works
let arr = create_primitive_array_with_seed::<i64>(50, 0.0 as f32, 42);
let mut mut_arr = arr.into_mut().unwrap_right();
// This fails
let arr =
Box::new(create_primitive_array_with_seed::<i64>(50, 0.0 as f32, 42)) as Box<dyn Array>;
let mut mut_arr = arr
.as_any()
.downcast_ref::<PrimitiveArray<i64>>()
.unwrap()
.into_mut()
.unwrap_right();
/*
error[E0507]: cannot move out of a shared reference
|
191 | let mut mut_arr = arr
| _______________________^
192 | | .as_any()
193 | | .downcast_ref::<PrimitiveArray<i64>>()
194 | | .unwrap()
195 | | .into_mut()
| | ---------^
| |__________|________|
| | move occurs because value has type `arrow2::array::PrimitiveArray<i64>`, which does not implement the `Copy` trait
| value moved due to this method call
|
note: this function takes ownership of the receiver `self`, which moves value
|
216 | pub fn into_mut(self) -> Either<Self, MutablePrimitiveArray<T>> {
| ^^^^
*/ |
I make this PR to have some context for the discussion. I understand this hits the core of all memory operations so we must ensure its correct.
This allows for a
PrimitiveArray
to get aMutablePrimitiveArray
zero copy. Allowing for mutations, pushes etc.This conversion from
PrimitiveArray
toMutablePrimitiveArray
can only be done ifArc::get_mut
and the borrow checkerRust
by aVec
and not by an FFI.Bitmap
and the valuesBuffer<T>
suffice above requirements.