Skip to content

Commit

Permalink
refactor: get rid of TempBlock completely
Browse files Browse the repository at this point in the history
Signed-off-by: Yiyang Wu <[email protected]>
  • Loading branch information
ToolmanP committed Sep 9, 2024
1 parent e2a9e21 commit efb93e8
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 307 deletions.
101 changes: 6 additions & 95 deletions erofs-sys/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,10 @@ use super::map::*;
use super::superblock::*;
use super::*;

use crate::round;

/// Represent some sort of generic data source. This cound be file, memory or even network.
/// Note that users should never use this directly please use backends instead.
pub(crate) trait Source {
fn fill(&self, data: &mut [u8], offset: Off) -> PosixResult<u64>;
fn get_temp_buffer(&self, offset: Off, maxsize: Off) -> PosixResult<TempBuffer> {
let mut block: TempBlock = EROFS_TEMP_BLOCK;
let accessor = TempBlockAccessor::from(offset);
self.fill(&mut block, accessor.base).map(|sz| {
TempBuffer::new(
block,
accessor.off as usize,
accessor.len.min(sz).min(maxsize) as usize,
)
})
}
}

/// Represents a file source.
Expand All @@ -37,34 +24,31 @@ pub(crate) trait FileSource: Source {}
// Represents a memory source. Note that as_buf and as_buf_mut should only represent memory within
// a page. Cross page memory is not supported and treated as an error.
pub(crate) trait PageSource<'a>: Source {
fn as_buf(&'a self, offset: Off, len: Off) -> PosixResult<RefBuffer<'a>>;
fn as_buf_mut(&'a mut self, offset: Off, len: Off) -> PosixResult<RefBufferMut<'a>>;
fn as_buf(&'a self, offset: Off, len: Off) -> PosixResult<&'a [u8]>;
}

/// Represents a generic data access backend that is backed by some sort of data source.
/// This often has temporary buffers to decompress the data from the data source.
/// The method signatures are the same as those of the Source trait.
pub(crate) trait Backend {
fn fill(&self, data: &mut [u8], offset: Off) -> PosixResult<u64>;
fn get_temp_buffer(&self, offset: Off, maxsize: Off) -> PosixResult<TempBuffer>;
}

/// Represents a file backend whose source is a file.
pub(crate) trait FileBackend: Backend {}

/// Represents a memory backend whose source is memory.
pub(crate) trait MemoryBackend<'a>: Backend {
fn as_buf(&'a self, offset: Off, len: Off) -> PosixResult<RefBuffer<'a>>;
fn as_buf_mut(&'a mut self, offset: Off, len: Off) -> PosixResult<RefBufferMut<'a>>;
fn as_buf(&'a self, offset: Off, len: Off) -> PosixResult<&'a [u8]>;
}

/// Represents a TempBuffer which owns a temporary on-stack/on-heap buffer.
/// Note that file or network backend can only use this since they can't access the data from the
/// memory directly.
pub(crate) struct TempBuffer {
block: TempBlock,
start: usize,
maxsize: usize,
pub(crate) block: Vec<u8>,
pub(crate) start: usize,
pub(crate) maxsize: usize,
}

/// Represents a buffer trait which can yield its internal reference or be casted as an iterator of
Expand All @@ -76,26 +60,14 @@ pub(crate) trait Buffer {
}
}

/// Represents a mutable buffer trait which can yield its internal mutable reference.
pub(crate) trait BufferMut: Buffer {
fn content_mut(&mut self) -> &mut [u8];
}

impl TempBuffer {
pub(crate) fn new(block: TempBlock, start: usize, maxsize: usize) -> Self {
pub(crate) fn new(block: Vec<u8>, start: usize, maxsize: usize) -> Self {
Self {
block,
start,
maxsize,
}
}
pub(crate) const fn empty() -> Self {
Self {
block: EROFS_TEMP_BLOCK,
start: 0,
maxsize: 0,
}
}
}

impl Buffer for TempBuffer {
Expand All @@ -104,12 +76,6 @@ impl Buffer for TempBuffer {
}
}

impl BufferMut for TempBuffer {
fn content_mut(&mut self) -> &mut [u8] {
&mut self.block[self.start..self.maxsize + self.start]
}
}

/// Represents a buffer that holds a reference to a slice of data that
/// is borrowed from the thin air.
pub(crate) struct RefBuffer<'a> {
Expand All @@ -119,18 +85,6 @@ pub(crate) struct RefBuffer<'a> {
put_buf: fn(*mut core::ffi::c_void),
}

impl Buffer for [u8] {
fn content(&self) -> &[u8] {
self
}
}

impl BufferMut for [u8] {
fn content_mut(&mut self) -> &mut [u8] {
self
}
}

impl<'a> Buffer for RefBuffer<'a> {
fn content(&self) -> &[u8] {
&self.buf[self.start..self.start + self.len]
Expand Down Expand Up @@ -158,46 +112,3 @@ impl<'a> Drop for RefBuffer<'a> {
(self.put_buf)(self.buf.as_ptr() as *mut core::ffi::c_void)
}
}

/// Represents a mutable buffer that holds a reference to a slice of data
/// that is borrowed from the thin air.
pub(crate) struct RefBufferMut<'a> {
buf: &'a mut [u8],
start: usize,
len: usize,
put_buf: fn(*mut core::ffi::c_void),
}

impl<'a> RefBufferMut<'a> {
pub(crate) fn new(
buf: &'a mut [u8],
start: usize,
len: usize,
put_buf: fn(*mut core::ffi::c_void),
) -> Self {
Self {
buf,
start,
len,
put_buf,
}
}
}

impl<'a> Buffer for RefBufferMut<'a> {
fn content(&self) -> &[u8] {
&self.buf[self.start..self.start + self.len]
}
}

impl<'a> BufferMut for RefBufferMut<'a> {
fn content_mut(&mut self) -> &mut [u8] {
&mut self.buf[self.start..self.start + self.len]
}
}

impl<'a> Drop for RefBufferMut<'a> {
fn drop(&mut self) {
(self.put_buf)(self.buf.as_mut_ptr() as *mut core::ffi::c_void)
}
}
9 changes: 1 addition & 8 deletions erofs-sys/src/data/backends/uncompressed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,16 @@ where
fn fill(&self, data: &mut [u8], offset: Off) -> PosixResult<u64> {
self.source.fill(data, offset)
}
fn get_temp_buffer(&self, offset: Off, maxsize: Off) -> PosixResult<TempBuffer> {
self.source.get_temp_buffer(offset, maxsize)
}
}

impl<T> FileBackend for UncompressedBackend<T> where T: Source {}

impl<'a, T> MemoryBackend<'a> for UncompressedBackend<T>
where
T: PageSource<'a>,
{
fn as_buf(&'a self, offset: Off, len: Off) -> PosixResult<RefBuffer<'a>> {
fn as_buf(&'a self, offset: Off, len: Off) -> PosixResult<&'a [u8]> {
self.source.as_buf(offset, len)
}
fn as_buf_mut(&'a mut self, offset: Off, len: Off) -> PosixResult<RefBufferMut<'a>> {
self.source.as_buf_mut(offset, len)
}
}

impl<T: Source> UncompressedBackend<T> {
Expand Down
47 changes: 30 additions & 17 deletions erofs-sys/src/data/raw_iters/ref_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ where
B: MemoryBackend<'a>,
I: Inode,
{
sb: &'a SuperBlock,
backend: &'a B,
map_iter: MapIter<'a, 'b, FS, I>,
}
Expand All @@ -19,8 +20,16 @@ where
B: MemoryBackend<'a>,
I: Inode,
{
pub(crate) fn new(backend: &'a B, map_iter: MapIter<'a, 'b, FS, I>) -> Self {
Self { backend, map_iter }
pub(crate) fn new(
sb: &'a SuperBlock,
backend: &'a B,
map_iter: MapIter<'a, 'b, FS, I>,
) -> Self {
Self {
sb,
backend,
map_iter,
}
}
}

Expand All @@ -35,11 +44,13 @@ where
match self.map_iter.next() {
Some(map) => match map {
Ok(m) => {
match self
.backend
.as_buf(m.physical.start, m.physical.len.min(EROFS_TEMP_BLOCK_SZ))
{
Ok(buf) => Some(heap_alloc(buf).map(|v| v as Box<dyn Buffer + 'a>)),
let accessor = self.sb.blk_access(m.physical.start);
let len = m.physical.len.min(accessor.len);
match self.backend.as_buf(m.physical.start, len) {
Ok(buf) => Some(
heap_alloc(RefBuffer::new(buf, 0, len as usize, |_| {}))
.map(|v| v as Box<dyn Buffer + 'a>),
),
Err(e) => Some(Err(e)),
}
}
Expand All @@ -62,22 +73,22 @@ pub(crate) struct ContinuousRefIter<'a, B>
where
B: MemoryBackend<'a>,
{
sb: &'a SuperBlock,
backend: &'a B,
offset: Off,
len: Off,
first: bool,
}

impl<'a, B> ContinuousRefIter<'a, B>
where
B: MemoryBackend<'a>,
{
pub(crate) fn new(backend: &'a B, offset: Off, len: Off) -> Self {
pub(crate) fn new(sb: &'a SuperBlock, backend: &'a B, offset: Off, len: Off) -> Self {
Self {
sb,
backend,
offset,
len,
first: true,
}
}
}
Expand All @@ -91,15 +102,17 @@ where
if self.len == 0 {
return None;
}

let pa = TempBlockAccessor::from(self.offset);
let len = pa.len.min(self.len);
let accessor = self.sb.blk_access(self.offset);
let len = accessor.len.min(self.len);
let result: Option<Self::Item> = self.backend.as_buf(self.offset, len).map_or_else(
|e| Some(Err(e)),
|x| {
self.offset += x.content().len() as Off;
self.len -= x.content().len() as Off;
Some(heap_alloc(x).map(|v| v as Box<dyn Buffer + 'a>))
|buf| {
self.offset += len;
self.len -= len;
Some(
heap_alloc(RefBuffer::new(buf, 0, len as usize, |_| {}))
.map(|v| v as Box<dyn Buffer + 'a>),
)
},
);
result
Expand Down
Loading

0 comments on commit efb93e8

Please sign in to comment.