From 1c1b0583f17f49c058067dc6dff2b1abe30ab6c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=AE=87=E9=80=B8?= Date: Sun, 3 Mar 2024 20:55:00 +0800 Subject: [PATCH 1/2] refactor(buf): generalize impl of bufs --- compio-buf/src/io_buf.rs | 258 +++++++++++++++++++++++++-------------- compio-buf/src/slice.rs | 2 +- 2 files changed, 166 insertions(+), 94 deletions(-) diff --git a/compio-buf/src/io_buf.rs b/compio-buf/src/io_buf.rs index cec285d2..cc62e4a3 100644 --- a/compio-buf/src/io_buf.rs +++ b/compio-buf/src/io_buf.rs @@ -92,49 +92,51 @@ pub trait IoBuf: 'static { } } -impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf for vec_alloc!(u8, A) { +impl IoBuf for &'static B { fn as_buf_ptr(&self) -> *const u8 { - self.as_ptr() + (**self).as_buf_ptr() } fn buf_len(&self) -> usize { - self.len() + (**self).buf_len() } fn buf_capacity(&self) -> usize { - self.capacity() + (**self).buf_capacity() } } -impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf for box_alloc!([u8], A) { +impl IoBuf for &'static mut B { fn as_buf_ptr(&self) -> *const u8 { - self.as_ptr() + (**self).as_buf_ptr() } fn buf_len(&self) -> usize { - self.len() + (**self).buf_len() } fn buf_capacity(&self) -> usize { - self.len() + (**self).buf_capacity() } } -impl IoBuf for &'static mut [u8] { +impl IoBuf + for box_alloc!(B, A) +{ fn as_buf_ptr(&self) -> *const u8 { - self.as_ptr() + (**self).as_buf_ptr() } fn buf_len(&self) -> usize { - self.len() + (**self).buf_len() } fn buf_capacity(&self) -> usize { - self.len() + (**self).buf_capacity() } } -impl IoBuf for &'static [u8] { +impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBuf for vec_alloc!(u8, A) { fn as_buf_ptr(&self) -> *const u8 { self.as_ptr() } @@ -144,7 +146,7 @@ impl IoBuf for &'static [u8] { } fn buf_capacity(&self) -> usize { - self.len() + self.capacity() } } @@ -162,7 +164,7 @@ impl IoBuf for String { } } -impl IoBuf for &'static mut str { +impl IoBuf for str { fn as_buf_ptr(&self) -> *const u8 { self.as_ptr() } @@ -176,7 +178,7 @@ impl IoBuf for &'static mut str { } } -impl IoBuf for &'static str { +impl IoBuf for [u8] { fn as_buf_ptr(&self) -> *const u8 { self.as_ptr() } @@ -190,34 +192,6 @@ impl IoBuf for &'static str { } } -impl IoBuf for &'static [u8; N] { - fn as_buf_ptr(&self) -> *const u8 { - self.as_ptr() - } - - fn buf_len(&self) -> usize { - N - } - - fn buf_capacity(&self) -> usize { - N - } -} - -impl IoBuf for &'static mut [u8; N] { - fn as_buf_ptr(&self) -> *const u8 { - self.as_ptr() - } - - fn buf_len(&self) -> usize { - N - } - - fn buf_capacity(&self) -> usize { - N - } -} - impl IoBuf for [u8; N] { fn as_buf_ptr(&self) -> *const u8 { self.as_ptr() @@ -311,7 +285,9 @@ pub trait IoBufMut: IoBuf + SetBufInit { /// Get the uninitialized part of the buffer. fn as_mut_slice(&mut self) -> &mut [MaybeUninit] { - unsafe { std::slice::from_raw_parts_mut(self.as_buf_mut_ptr().cast(), self.buf_capacity()) } + unsafe { + std::slice::from_raw_parts_mut(self.as_buf_mut_ptr().cast(), (*self).buf_capacity()) + } } /// Create an [`IoSliceMut`] of the uninitialized part of the buffer. @@ -326,19 +302,27 @@ pub trait IoBufMut: IoBuf + SetBufInit { } } -impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBufMut for vec_alloc!(u8, A) { +impl IoBufMut for &'static mut B { fn as_buf_mut_ptr(&mut self) -> *mut u8 { - self.as_mut_ptr() + (**self).as_buf_mut_ptr() + } +} + +impl IoBufMut + for box_alloc!(B, A) +{ + fn as_buf_mut_ptr(&mut self) -> *mut u8 { + (**self).as_buf_mut_ptr() } } -impl IoBufMut for &'static mut [u8] { +impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> IoBufMut for vec_alloc!(u8, A) { fn as_buf_mut_ptr(&mut self) -> *mut u8 { self.as_mut_ptr() } } -impl IoBufMut for &'static mut [u8; N] { +impl IoBufMut for [u8] { fn as_buf_mut_ptr(&mut self) -> *mut u8 { self.as_mut_ptr() } @@ -360,7 +344,7 @@ impl IoBufMut for bytes::BytesMut { #[cfg(feature = "read_buf")] impl IoBufMut for std::io::BorrowedBuf<'static> { fn as_buf_mut_ptr(&mut self) -> *mut u8 { - self.filled().as_ptr() as _ + (*self).filled().as_ptr() as _ } } @@ -372,7 +356,7 @@ impl IoBufMut for arrayvec::ArrayVec { } /// A trait for vectored buffers. -pub trait IoVectoredBuf: 'static { +pub trait IoVectoredBuf: Sized + 'static { /// An iterator for the [`IoSlice`]s of the buffers. /// /// # Safety @@ -404,9 +388,47 @@ pub trait IoVectoredBuf: 'static { /// /// The time complexity of the returned iterator depends on the /// implementation of [`Iterator::nth`] of [`IoVectoredBuf::as_dyn_bufs`]. - fn owned_iter(self) -> Result>, Self> - where - Self: Sized; + fn owned_iter(self) -> Result>, Self>; +} + +impl IoVectoredBuf for &'static [T] { + fn as_dyn_bufs(&self) -> impl Iterator { + self.iter().map(|buf| buf as &dyn IoBuf) + } + + fn owned_iter(self) -> Result>, Self> { + IndexedIter::new(self, 0).map(OwnedIter::new) + } +} + +impl IoVectoredBuf for &'static mut [T] { + fn as_dyn_bufs(&self) -> impl Iterator { + self.iter().map(|buf| buf as &dyn IoBuf) + } + + fn owned_iter(self) -> Result>, Self> { + IndexedIter::new(self, 0).map(OwnedIter::new) + } +} + +impl IoVectoredBuf for &'static T { + fn as_dyn_bufs(&self) -> impl Iterator { + (**self).as_dyn_bufs() + } + + fn owned_iter(self) -> Result>, Self> { + IndexedIter::new(self, 0).map(OwnedIter::new) + } +} + +impl IoVectoredBuf for &'static mut T { + fn as_dyn_bufs(&self) -> impl Iterator { + (**self).as_dyn_bufs() + } + + fn owned_iter(self) -> Result>, Self> { + IndexedIter::new(self, 0).map(OwnedIter::new) + } } impl IoVectoredBuf for [T; N] { @@ -414,10 +436,7 @@ impl IoVectoredBuf for [T; N] { self.iter().map(|buf| buf as &dyn IoBuf) } - fn owned_iter(self) -> Result>, Self> - where - Self: Sized, - { + fn owned_iter(self) -> Result>, Self> { IndexedIter::new(self, 0).map(OwnedIter::new) } } @@ -429,10 +448,7 @@ impl IoVecto self.iter().map(|buf| buf as &dyn IoBuf) } - fn owned_iter(self) -> Result>, Self> - where - Self: Sized, - { + fn owned_iter(self) -> Result>, Self> { IndexedIter::new(self, 0).map(OwnedIter::new) } } @@ -443,10 +459,7 @@ impl IoVectoredBuf for arrayvec::ArrayVec { self.iter().map(|buf| buf as &dyn IoBuf) } - fn owned_iter(self) -> Result>, Self> - where - Self: Sized, - { + fn owned_iter(self) -> Result>, Self> { IndexedIter::new(self, 0).map(OwnedIter::new) } } @@ -486,9 +499,27 @@ pub trait IoVectoredBufMut: IoVectoredBuf + SetBufInit { /// /// The time complexity of the returned iterator depends on the /// implementation of [`Iterator::nth`] of [`IoVectoredBuf::as_dyn_bufs`]. - fn owned_iter_mut(self) -> Result>, Self> - where - Self: Sized; + fn owned_iter_mut(self) -> Result>, Self>; +} + +impl IoVectoredBufMut for &'static mut [T] { + fn as_dyn_mut_bufs(&mut self) -> impl Iterator { + self.iter_mut().map(|buf| buf as &mut dyn IoBufMut) + } + + fn owned_iter_mut(self) -> Result>, Self> { + IndexedIter::new(self, 0).map(OwnedIter::new) + } +} + +impl IoVectoredBufMut for &'static mut T { + fn as_dyn_mut_bufs(&mut self) -> impl Iterator { + (**self).as_dyn_mut_bufs() + } + + fn owned_iter_mut(self) -> Result>, Self> { + IndexedIter::new(self, 0).map(OwnedIter::new) + } } impl IoVectoredBufMut for [T; N] { @@ -496,10 +527,7 @@ impl IoVectoredBufMut for [T; N] { self.iter_mut().map(|buf| buf as &mut dyn IoBufMut) } - fn owned_iter_mut(self) -> Result>, Self> - where - Self: Sized, - { + fn owned_iter_mut(self) -> Result>, Self> { IndexedIter::new(self, 0).map(OwnedIter::new) } } @@ -511,10 +539,7 @@ impl IoVe self.iter_mut().map(|buf| buf as &mut dyn IoBufMut) } - fn owned_iter_mut(self) -> Result>, Self> - where - Self: Sized, - { + fn owned_iter_mut(self) -> Result>, Self> { IndexedIter::new(self, 0).map(OwnedIter::new) } } @@ -525,10 +550,7 @@ impl IoVectoredBufMut for arrayvec::ArrayVec self.iter_mut().map(|buf| buf as &mut dyn IoBufMut) } - fn owned_iter_mut(self) -> Result>, Self> - where - Self: Sized, - { + fn owned_iter_mut(self) -> Result>, Self> { IndexedIter::new(self, 0).map(OwnedIter::new) } } @@ -539,6 +561,30 @@ pub trait IoIndexedBuf: IoVectoredBuf { fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf>; } +impl IoIndexedBuf for &'static [T] { + fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> { + self.get(n).map(|b| b as _) + } +} + +impl IoIndexedBuf for &'static mut [T] { + fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> { + self.get(n).map(|b| b as _) + } +} + +impl IoIndexedBuf for &'static T { + fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> { + (**self).buf_nth(n) + } +} + +impl IoIndexedBuf for &'static mut T { + fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> { + (**self).buf_nth(n) + } +} + impl IoIndexedBuf for [T; N] { fn buf_nth(&self, n: usize) -> Option<&dyn IoBuf> { self.get(n).map(|b| b as _) @@ -566,6 +612,18 @@ pub trait IoIndexedBufMut: IoVectoredBufMut + IoIndexedBuf { fn buf_nth_mut(&mut self, n: usize) -> Option<&mut dyn IoBufMut>; } +impl IoIndexedBufMut for &'static mut [T] { + fn buf_nth_mut(&mut self, n: usize) -> Option<&mut dyn IoBufMut> { + self.get_mut(n).map(|b| b as _) + } +} + +impl IoIndexedBufMut for &'static mut T { + fn buf_nth_mut(&mut self, n: usize) -> Option<&mut dyn IoBufMut> { + (**self).buf_nth_mut(n) + } +} + impl IoIndexedBufMut for [T; N] { fn buf_nth_mut(&mut self, n: usize) -> Option<&mut dyn IoBufMut> { self.get_mut(n).map(|b| b as _) @@ -598,23 +656,31 @@ pub trait SetBufInit { unsafe fn set_buf_init(&mut self, len: usize); } -impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> SetBufInit for vec_alloc!(u8, A) { +impl SetBufInit for &'static mut B { unsafe fn set_buf_init(&mut self, len: usize) { - if self.buf_len() < len { - self.set_len(len); - } + (**self).set_buf_init(len) } } -impl SetBufInit for &'static mut [u8] { +impl SetBufInit + for box_alloc!(B, A) +{ unsafe fn set_buf_init(&mut self, len: usize) { - debug_assert!(len <= self.len()); + (**self).set_buf_init(len) } } -impl SetBufInit for &'static mut [u8; N] { +impl<#[cfg(feature = "allocator_api")] A: Allocator + 'static> SetBufInit for vec_alloc!(u8, A) { unsafe fn set_buf_init(&mut self, len: usize) { - debug_assert!(len <= N); + if (**self).buf_len() < len { + self.set_len(len); + } + } +} + +impl SetBufInit for [u8] { + unsafe fn set_buf_init(&mut self, len: usize) { + debug_assert!(len <= self.len()); } } @@ -627,7 +693,7 @@ impl SetBufInit for [u8; N] { #[cfg(feature = "bytes")] impl SetBufInit for bytes::BytesMut { unsafe fn set_buf_init(&mut self, len: usize) { - if self.buf_len() < len { + if (**self).buf_len() < len { self.set_len(len); } } @@ -636,7 +702,7 @@ impl SetBufInit for bytes::BytesMut { #[cfg(feature = "read_buf")] impl SetBufInit for std::io::BorrowedBuf<'static> { unsafe fn set_buf_init(&mut self, len: usize) { - let current_len = self.buf_len(); + let current_len = (*self).buf_len(); if current_len < len { self.unfilled().advance(len - current_len); } @@ -646,12 +712,18 @@ impl SetBufInit for std::io::BorrowedBuf<'static> { #[cfg(feature = "arrayvec")] impl SetBufInit for arrayvec::ArrayVec { unsafe fn set_buf_init(&mut self, len: usize) { - if self.buf_len() < len { + if (**self).buf_len() < len { self.set_len(len); } } } +impl SetBufInit for [T] { + unsafe fn set_buf_init(&mut self, len: usize) { + default_set_buf_init(self.iter_mut(), len) + } +} + impl SetBufInit for [T; N] { unsafe fn set_buf_init(&mut self, len: usize) { default_set_buf_init(self.iter_mut(), len) @@ -678,7 +750,7 @@ unsafe fn default_set_buf_init<'a, B: IoBufMut>( mut len: usize, ) { for buf in iter { - let capacity = buf.buf_capacity(); + let capacity = (*buf).buf_capacity(); if len >= capacity { buf.set_buf_init(capacity); len -= capacity; diff --git a/compio-buf/src/slice.rs b/compio-buf/src/slice.rs index 01f01e99..a6f1ef1f 100644 --- a/compio-buf/src/slice.rs +++ b/compio-buf/src/slice.rs @@ -59,7 +59,7 @@ impl Slice { } fn slice_mut(buffer: &mut T) -> &mut [u8] { - unsafe { std::slice::from_raw_parts_mut(buffer.as_buf_mut_ptr(), buffer.buf_len()) } + unsafe { std::slice::from_raw_parts_mut(buffer.as_buf_mut_ptr(), (*buffer).buf_len()) } } impl Deref for Slice { From 60a659f57806cdb6cc27b072275898dfe159e34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=AE=87=E9=80=B8?= Date: Sun, 3 Mar 2024 21:10:47 +0800 Subject: [PATCH 2/2] refactor(io): aware of allocator_api --- compio-io/src/read/mod.rs | 62 +++++++++++++++------- compio-io/src/write/mod.rs | 102 +++++++++++++++++++++++-------------- 2 files changed, 109 insertions(+), 55 deletions(-) diff --git a/compio-io/src/read/mod.rs b/compio-io/src/read/mod.rs index b2aeb5c8..57cb33d3 100644 --- a/compio-io/src/read/mod.rs +++ b/compio-io/src/read/mod.rs @@ -2,7 +2,9 @@ use std::alloc::Allocator; use std::{io::Cursor, rc::Rc, sync::Arc}; -use compio_buf::{buf_try, vec_alloc, BufResult, IntoInner, IoBuf, IoBufMut, IoVectoredBufMut}; +use compio_buf::{ + box_alloc, buf_try, vec_alloc, BufResult, IntoInner, IoBuf, IoBufMut, IoVectoredBufMut, +}; mod buf; #[macro_use] @@ -59,25 +61,31 @@ pub trait AsyncRead { } } -macro_rules! impl_read { - ($($ty:ty),*) => { - $( - impl AsyncRead for $ty { - #[inline(always)] - async fn read(&mut self, buf: T) -> BufResult { - (**self).read(buf).await - } +impl AsyncRead for &mut A { + #[inline(always)] + async fn read(&mut self, buf: T) -> BufResult { + (**self).read(buf).await + } - #[inline(always)] - async fn read_vectored(&mut self, buf: T) -> BufResult { - (**self).read_vectored(buf).await - } - } - )* - }; + #[inline(always)] + async fn read_vectored(&mut self, buf: T) -> BufResult { + (**self).read_vectored(buf).await + } } -impl_read!(&mut A, Box); +impl AsyncRead + for box_alloc!(R, A) +{ + #[inline(always)] + async fn read(&mut self, buf: T) -> BufResult { + (**self).read(buf).await + } + + #[inline(always)] + async fn read_vectored(&mut self, buf: T) -> BufResult { + (**self).read_vectored(buf).await + } +} impl AsyncRead for &[u8] { #[inline] @@ -139,6 +147,23 @@ macro_rules! impl_read_at { )* }; + (@ptra $($ty:ident),*) => { + $( + #[cfg(feature = "allocator_api")] + impl AsyncReadAt for $ty { + async fn read_at(&self, buf: T, pos: u64) -> BufResult { + (**self).read_at(buf, pos).await + } + + async fn read_vectored_at(&self, buf: T, pos: u64) -> BufResult { + (**self).read_vectored_at(buf, pos).await + } + } + #[cfg(not(feature = "allocator_api"))] + impl_read_at!(@ptr $ty); + )* + }; + (@slice $($(const $len:ident =>)? $ty:ty), *) => { $( impl<$(const $len: usize)?> AsyncReadAt for $ty { @@ -152,7 +177,8 @@ macro_rules! impl_read_at { } } -impl_read_at!(@ptr &A, &mut A, Box, Rc, Arc); +impl_read_at!(@ptr &A, &mut A); +impl_read_at!(@ptra Box, Rc, Arc); impl_read_at!(@slice [u8], const LEN => [u8; LEN]); impl<#[cfg(feature = "allocator_api")] A: Allocator> AsyncReadAt for vec_alloc!(u8, A) { diff --git a/compio-io/src/write/mod.rs b/compio-io/src/write/mod.rs index 504c8005..f2684362 100644 --- a/compio-io/src/write/mod.rs +++ b/compio-io/src/write/mod.rs @@ -2,7 +2,7 @@ use std::alloc::Allocator; use std::io::Cursor; -use compio_buf::{buf_try, vec_alloc, BufResult, IntoInner, IoBuf, IoVectoredBuf}; +use compio_buf::{box_alloc, buf_try, vec_alloc, BufResult, IntoInner, IoBuf, IoVectoredBuf}; use crate::IoResult; @@ -50,31 +50,43 @@ pub trait AsyncWrite { async fn shutdown(&mut self) -> IoResult<()>; } -macro_rules! impl_write { - (@ptr $($ty:ty),*) => { - $( - impl AsyncWrite for $ty { - async fn write(&mut self, buf: T) -> BufResult { - (**self).write(buf).await - } +impl AsyncWrite for &mut A { + async fn write(&mut self, buf: T) -> BufResult { + (**self).write(buf).await + } - async fn write_vectored(&mut self, buf: T) -> BufResult { - (**self).write_vectored(buf).await - } + async fn write_vectored(&mut self, buf: T) -> BufResult { + (**self).write_vectored(buf).await + } - async fn flush(&mut self) -> IoResult<()> { - (**self).flush().await - } + async fn flush(&mut self) -> IoResult<()> { + (**self).flush().await + } - async fn shutdown(&mut self) -> IoResult<()> { - (**self).shutdown().await - } - } - )* - }; + async fn shutdown(&mut self) -> IoResult<()> { + (**self).shutdown().await + } } -impl_write!(@ptr &mut A, Box); +impl AsyncWrite + for box_alloc!(W, A) +{ + async fn write(&mut self, buf: T) -> BufResult { + (**self).write(buf).await + } + + async fn write_vectored(&mut self, buf: T) -> BufResult { + (**self).write_vectored(buf).await + } + + async fn flush(&mut self) -> IoResult<()> { + (**self).flush().await + } + + async fn shutdown(&mut self) -> IoResult<()> { + (**self).shutdown().await + } +} /// Write is implemented for `Vec` by appending to the vector. The vector /// will grow as needed. @@ -127,21 +139,38 @@ pub trait AsyncWriteAt { } } -macro_rules! impl_write_at { - (@ptr $($ty:ty),*) => { - $( - impl AsyncWriteAt for $ty { - async fn write_at(&mut self, buf: T, pos: u64) -> BufResult { - (**self).write_at(buf, pos).await - } +impl AsyncWriteAt for &mut A { + async fn write_at(&mut self, buf: T, pos: u64) -> BufResult { + (**self).write_at(buf, pos).await + } - async fn write_vectored_at(&mut self, buf: T, pos: u64) -> BufResult { - (**self).write_vectored_at(buf, pos).await - } - } - )* - }; - (@slice $($(const $len:ident =>)? $ty:ty),*) => { + async fn write_vectored_at( + &mut self, + buf: T, + pos: u64, + ) -> BufResult { + (**self).write_vectored_at(buf, pos).await + } +} + +impl AsyncWriteAt + for box_alloc!(W, A) +{ + async fn write_at(&mut self, buf: T, pos: u64) -> BufResult { + (**self).write_at(buf, pos).await + } + + async fn write_vectored_at( + &mut self, + buf: T, + pos: u64, + ) -> BufResult { + (**self).write_vectored_at(buf, pos).await + } +} + +macro_rules! impl_write_at { + ($($(const $len:ident =>)? $ty:ty),*) => { $( impl<$(const $len: usize)?> AsyncWriteAt for $ty { async fn write_at(&mut self, buf: T, pos: u64) -> BufResult { @@ -156,8 +185,7 @@ macro_rules! impl_write_at { } } -impl_write_at!(@ptr &mut A, Box); -impl_write_at!(@slice [u8], const LEN => [u8; LEN]); +impl_write_at!([u8], const LEN => [u8; LEN]); /// This implementation aligns the behavior of files. If `pos` is larger than /// the vector length, the vectored will be extended, and the extended area will