Skip to content

Commit 32f6da7

Browse files
committed
Initial buffer allocator
Signed-off-by: Nicholas Gates <nick@nickgates.com>
1 parent 2839502 commit 32f6da7

4 files changed

Lines changed: 177 additions & 10 deletions

File tree

vortex-array/public-api.lock

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8388,6 +8388,8 @@ pub unsafe fn vortex_array::builders::PrimitiveBuilder<T>::set_validity_unchecke
83888388

83898389
pub fn vortex_array::builders::builder_with_capacity(dtype: &vortex_array::dtype::DType, capacity: usize) -> alloc::boxed::Box<dyn vortex_array::builders::ArrayBuilder>
83908390

8391+
pub fn vortex_array::builders::builder_with_capacity_in(allocator: vortex_array::memory::BufferAllocatorRef, dtype: &vortex_array::dtype::DType, capacity: usize) -> alloc::boxed::Box<dyn vortex_array::builders::ArrayBuilder>
8392+
83918393
pub mod vortex_array::builtins
83928394

83938395
pub trait vortex_array::builtins::ArrayBuiltins: core::marker::Sized
@@ -13262,6 +13264,110 @@ pub fn V::matches(array: &vortex_array::ArrayRef) -> bool
1326213264

1326313265
pub fn V::try_match<'a>(array: &'a vortex_array::ArrayRef) -> core::option::Option<vortex_array::ArrayView<'a, V>>
1326413266

13267+
pub mod vortex_array::memory
13268+
13269+
pub struct vortex_array::memory::DefaultBufferAllocator
13270+
13271+
impl core::default::Default for vortex_array::memory::DefaultBufferAllocator
13272+
13273+
pub fn vortex_array::memory::DefaultBufferAllocator::default() -> vortex_array::memory::DefaultBufferAllocator
13274+
13275+
impl core::fmt::Debug for vortex_array::memory::DefaultBufferAllocator
13276+
13277+
pub fn vortex_array::memory::DefaultBufferAllocator::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
13278+
13279+
impl vortex_array::memory::BufferAllocator for vortex_array::memory::DefaultBufferAllocator
13280+
13281+
pub fn vortex_array::memory::DefaultBufferAllocator::allocate(&self, len: usize, alignment: vortex_buffer::alignment::Alignment) -> vortex_error::VortexResult<vortex_array::memory::WritableHostBuffer>
13282+
13283+
pub struct vortex_array::memory::MemorySession
13284+
13285+
impl vortex_array::memory::MemorySession
13286+
13287+
pub fn vortex_array::memory::MemorySession::allocator(&self) -> vortex_array::memory::BufferAllocatorRef
13288+
13289+
pub fn vortex_array::memory::MemorySession::new(allocator: vortex_array::memory::BufferAllocatorRef) -> Self
13290+
13291+
pub fn vortex_array::memory::MemorySession::set_allocator(&mut self, allocator: vortex_array::memory::BufferAllocatorRef)
13292+
13293+
impl core::default::Default for vortex_array::memory::MemorySession
13294+
13295+
pub fn vortex_array::memory::MemorySession::default() -> Self
13296+
13297+
impl core::fmt::Debug for vortex_array::memory::MemorySession
13298+
13299+
pub fn vortex_array::memory::MemorySession::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
13300+
13301+
pub struct vortex_array::memory::WritableHostBuffer
13302+
13303+
impl vortex_array::memory::WritableHostBuffer
13304+
13305+
pub fn vortex_array::memory::WritableHostBuffer::alignment(&self) -> vortex_buffer::alignment::Alignment
13306+
13307+
pub fn vortex_array::memory::WritableHostBuffer::as_mut_slice(&mut self) -> &mut [u8]
13308+
13309+
pub fn vortex_array::memory::WritableHostBuffer::as_mut_slice_typed<T>(&mut self) -> vortex_error::VortexResult<&mut [T]>
13310+
13311+
pub fn vortex_array::memory::WritableHostBuffer::freeze(self) -> vortex_buffer::ByteBuffer
13312+
13313+
pub fn vortex_array::memory::WritableHostBuffer::freeze_typed<T>(self) -> vortex_error::VortexResult<vortex_buffer::buffer::Buffer<T>>
13314+
13315+
pub fn vortex_array::memory::WritableHostBuffer::is_empty(&self) -> bool
13316+
13317+
pub fn vortex_array::memory::WritableHostBuffer::len(&self) -> usize
13318+
13319+
pub fn vortex_array::memory::WritableHostBuffer::new(inner: alloc::boxed::Box<dyn vortex_array::memory::HostBufferMut>) -> Self
13320+
13321+
impl core::fmt::Debug for vortex_array::memory::WritableHostBuffer
13322+
13323+
pub fn vortex_array::memory::WritableHostBuffer::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result
13324+
13325+
pub trait vortex_array::memory::BufferAllocator: core::fmt::Debug + core::marker::Send + core::marker::Sync + 'static
13326+
13327+
pub fn vortex_array::memory::BufferAllocator::allocate(&self, len: usize, alignment: vortex_buffer::alignment::Alignment) -> vortex_error::VortexResult<vortex_array::memory::WritableHostBuffer>
13328+
13329+
impl vortex_array::memory::BufferAllocator for vortex_array::memory::DefaultBufferAllocator
13330+
13331+
pub fn vortex_array::memory::DefaultBufferAllocator::allocate(&self, len: usize, alignment: vortex_buffer::alignment::Alignment) -> vortex_error::VortexResult<vortex_array::memory::WritableHostBuffer>
13332+
13333+
pub trait vortex_array::memory::BufferAllocatorExt: vortex_array::memory::BufferAllocator
13334+
13335+
pub fn vortex_array::memory::BufferAllocatorExt::allocate_typed<T>(&self, len: usize) -> vortex_error::VortexResult<vortex_array::memory::WritableHostBuffer>
13336+
13337+
impl<A: vortex_array::memory::BufferAllocator + ?core::marker::Sized> vortex_array::memory::BufferAllocatorExt for A
13338+
13339+
pub fn A::allocate_typed<T>(&self, len: usize) -> vortex_error::VortexResult<vortex_array::memory::WritableHostBuffer>
13340+
13341+
pub trait vortex_array::memory::HostBufferMut: core::marker::Send + 'static
13342+
13343+
pub fn vortex_array::memory::HostBufferMut::alignment(&self) -> vortex_buffer::alignment::Alignment
13344+
13345+
pub fn vortex_array::memory::HostBufferMut::as_mut_slice(&mut self) -> &mut [u8]
13346+
13347+
pub fn vortex_array::memory::HostBufferMut::freeze(self: alloc::boxed::Box<Self>) -> vortex_buffer::ByteBuffer
13348+
13349+
pub fn vortex_array::memory::HostBufferMut::is_empty(&self) -> bool
13350+
13351+
pub fn vortex_array::memory::HostBufferMut::len(&self) -> usize
13352+
13353+
pub trait vortex_array::memory::MemorySessionExt: vortex_session::SessionExt
13354+
13355+
pub fn vortex_array::memory::MemorySessionExt::allocator(&self) -> vortex_array::memory::BufferAllocatorRef
13356+
13357+
pub fn vortex_array::memory::MemorySessionExt::memory(&self) -> vortex_session::Ref<'_, vortex_array::memory::MemorySession>
13358+
13359+
pub fn vortex_array::memory::MemorySessionExt::memory_mut(&self) -> vortex_session::RefMut<'_, vortex_array::memory::MemorySession>
13360+
13361+
impl<S: vortex_session::SessionExt> vortex_array::memory::MemorySessionExt for S
13362+
13363+
pub fn S::allocator(&self) -> vortex_array::memory::BufferAllocatorRef
13364+
13365+
pub fn S::memory(&self) -> vortex_session::Ref<'_, vortex_array::memory::MemorySession>
13366+
13367+
pub fn S::memory_mut(&self) -> vortex_session::RefMut<'_, vortex_array::memory::MemorySession>
13368+
13369+
pub type vortex_array::memory::BufferAllocatorRef = alloc::sync::Arc<dyn vortex_array::memory::BufferAllocator>
13370+
1326513371
pub mod vortex_array::normalize
1326613372

1326713373
pub enum vortex_array::normalize::Operation<'a>
@@ -22362,6 +22468,8 @@ pub struct vortex_array::ExecutionCtx
2236222468

2236322469
impl vortex_array::ExecutionCtx
2236422470

22471+
pub fn vortex_array::ExecutionCtx::allocator(&self) -> vortex_array::memory::BufferAllocatorRef
22472+
2236522473
pub fn vortex_array::ExecutionCtx::log(&mut self, msg: core::fmt::Arguments<'_>)
2236622474

2236722475
pub fn vortex_array::ExecutionCtx::new(session: vortex_session::VortexSession) -> Self

vortex-array/src/memory.rs

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::sync::Arc;
1010

1111
use bytes::Bytes;
1212
use vortex_buffer::Alignment;
13+
use vortex_buffer::Buffer;
1314
use vortex_buffer::ByteBuffer;
1415
use vortex_buffer::ByteBufferMut;
1516
use vortex_error::VortexResult;
@@ -24,6 +25,11 @@ pub trait HostBufferMut: Send + 'static {
2425
/// Returns the logical byte length of the buffer.
2526
fn len(&self) -> usize;
2627

28+
/// Whether the buffer is empty.
29+
fn is_empty(&self) -> bool {
30+
self.len() == 0
31+
}
32+
2733
/// Returns the alignment of the buffer.
2834
fn alignment(&self) -> Alignment;
2935

@@ -72,25 +78,23 @@ impl WritableHostBuffer {
7278
InvalidArgument: "Cannot create typed mutable slice for zero-sized type {}",
7379
std::any::type_name::<T>()
7480
);
81+
vortex_ensure!(
82+
self.alignment().is_aligned_to(Alignment::of::<T>()),
83+
InvalidArgument: "Buffer is not sufficiently aligned for type {}",
84+
std::any::type_name::<T>()
85+
);
7586

7687
let bytes = self.as_mut_slice();
7788
let byte_len = bytes.len();
7889
let ptr = bytes.as_mut_ptr();
7990
let type_size = size_of::<T>();
80-
let type_align = align_of::<T>();
8191

8292
vortex_ensure!(
83-
byte_len % type_size == 0,
93+
byte_len.is_multiple_of(type_size),
8494
InvalidArgument: "Buffer length {byte_len} is not a multiple of {} for {}",
8595
type_size,
8696
std::any::type_name::<T>()
8797
);
88-
vortex_ensure!(
89-
(ptr as usize) % type_align == 0,
90-
InvalidArgument: "Buffer pointer is not aligned to {} for {}",
91-
type_align,
92-
std::any::type_name::<T>()
93-
);
9498

9599
// SAFETY: We checked size divisibility and pointer alignment for `T`,
96100
// and we have exclusive mutable access to the underlying bytes.
@@ -101,6 +105,35 @@ impl WritableHostBuffer {
101105
pub fn freeze(self) -> ByteBuffer {
102106
self.inner.freeze()
103107
}
108+
109+
/// Freeze the writable buffer into a typed immutable [`Buffer<T>`].
110+
pub fn freeze_typed<T>(self) -> VortexResult<Buffer<T>> {
111+
vortex_ensure!(
112+
size_of::<T>() != 0,
113+
InvalidArgument: "Cannot freeze typed buffer for zero-sized type {}",
114+
std::any::type_name::<T>()
115+
);
116+
117+
let buffer = self.freeze();
118+
let byte_len = buffer.len();
119+
let type_size = size_of::<T>();
120+
let type_align = Alignment::of::<T>();
121+
122+
vortex_ensure!(
123+
byte_len % type_size == 0,
124+
InvalidArgument: "Buffer length {byte_len} is not a multiple of {} for {}",
125+
type_size,
126+
std::any::type_name::<T>()
127+
);
128+
vortex_ensure!(
129+
buffer.is_aligned(type_align),
130+
InvalidArgument: "Buffer pointer is not aligned to {} for {}",
131+
type_align,
132+
std::any::type_name::<T>()
133+
);
134+
135+
Ok(Buffer::from_byte_buffer(buffer))
136+
}
104137
}
105138

106139
impl Debug for WritableHostBuffer {
@@ -320,4 +353,26 @@ mod tests {
320353
let msg = format!("{err}");
321354
assert!(msg.contains("not a multiple of"));
322355
}
356+
357+
#[test]
358+
fn freeze_typed_round_trip() {
359+
let allocator = DefaultBufferAllocator;
360+
let mut writable = allocator.allocate_typed::<u64>(4).unwrap();
361+
writable
362+
.as_mut_slice_typed::<u64>()
363+
.unwrap()
364+
.copy_from_slice(&[1, 3, 5, 7]);
365+
366+
let frozen = writable.freeze_typed::<u64>().unwrap();
367+
assert_eq!(frozen.as_slice(), [1, 3, 5, 7]);
368+
}
369+
370+
#[test]
371+
fn freeze_typed_rejects_length_mismatch() {
372+
let allocator = DefaultBufferAllocator;
373+
let writable = allocator.allocate(7, Alignment::none()).unwrap();
374+
let err = writable.freeze_typed::<u32>().unwrap_err();
375+
let msg = format!("{err}");
376+
assert!(msg.contains("not a multiple of"));
377+
}
323378
}

vortex-file/public-api.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,11 @@ pub const vortex_file::VORTEX_FILE_EXTENSION: &str
398398

399399
pub static vortex_file::ALLOWED_ENCODINGS: std::sync::lazy_lock::LazyLock<vortex_utils::aliases::hash_set::HashSet<vortex_array::array::ArrayId>>
400400

401-
pub trait vortex_file::OpenOptionsSessionExt: vortex_array::session::ArraySessionExt + vortex_layout::session::LayoutSessionExt + vortex_io::session::RuntimeSessionExt
401+
pub trait vortex_file::OpenOptionsSessionExt: vortex_array::session::ArraySessionExt + vortex_layout::session::LayoutSessionExt + vortex_io::session::RuntimeSessionExt + vortex_array::memory::MemorySessionExt
402402

403403
pub fn vortex_file::OpenOptionsSessionExt::open_options(&self) -> vortex_file::VortexOpenOptions
404404

405-
impl<S: vortex_array::session::ArraySessionExt + vortex_layout::session::LayoutSessionExt + vortex_io::session::RuntimeSessionExt> vortex_file::OpenOptionsSessionExt for S
405+
impl<S: vortex_array::session::ArraySessionExt + vortex_layout::session::LayoutSessionExt + vortex_io::session::RuntimeSessionExt + vortex_array::memory::MemorySessionExt> vortex_file::OpenOptionsSessionExt for S
406406

407407
pub fn S::open_options(&self) -> vortex_file::VortexOpenOptions
408408

vortex-io/public-api.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ impl vortex_io::object_store::ObjectStoreReadAt
150150

151151
pub fn vortex_io::object_store::ObjectStoreReadAt::new(store: alloc::sync::Arc<dyn object_store::ObjectStore>, path: object_store::path::Path, handle: vortex_io::runtime::Handle) -> Self
152152

153+
pub fn vortex_io::object_store::ObjectStoreReadAt::new_with_allocator(store: alloc::sync::Arc<dyn object_store::ObjectStore>, path: object_store::path::Path, handle: vortex_io::runtime::Handle, allocator: vortex_array::memory::BufferAllocatorRef) -> Self
154+
153155
pub fn vortex_io::object_store::ObjectStoreReadAt::with_coalesce_config(self, config: vortex_io::CoalesceConfig) -> Self
154156

155157
pub fn vortex_io::object_store::ObjectStoreReadAt::with_concurrency(self, concurrency: usize) -> Self
@@ -466,6 +468,8 @@ impl vortex_io::std_file::FileReadAt
466468

467469
pub fn vortex_io::std_file::FileReadAt::open(path: impl core::convert::AsRef<std::path::Path>, handle: vortex_io::runtime::Handle) -> vortex_error::VortexResult<Self>
468470

471+
pub fn vortex_io::std_file::FileReadAt::open_with_allocator(path: impl core::convert::AsRef<std::path::Path>, handle: vortex_io::runtime::Handle, allocator: vortex_array::memory::BufferAllocatorRef) -> vortex_error::VortexResult<Self>
472+
469473
impl vortex_io::VortexReadAt for vortex_io::std_file::FileReadAt
470474

471475
pub fn vortex_io::std_file::FileReadAt::coalesce_config(&self) -> core::option::Option<vortex_io::CoalesceConfig>

0 commit comments

Comments
 (0)