Skip to content

Commit

Permalink
feat: rc-zip-tokio: Re-use cursor if it's at the right offset already (
Browse files Browse the repository at this point in the history
…#71)

* feat: rc-zip-tokio: Re-use cursor if it's at the right offset already

cf. #61

* feat: rc-zip: Re-use cursor if it's at the right offset
  • Loading branch information
fasterthanlime authored Mar 16, 2024
1 parent a26f09d commit a34a302
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 3 deletions.
31 changes: 29 additions & 2 deletions rc-zip-sync/src/read_zip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,40 @@ where
type File = F;

fn read_zip_with_size(&self, size: u64) -> Result<ArchiveHandle<'_, F>, Error> {
trace!(%size, "read_zip_with_size");
struct CursorState<'a, F: HasCursor + 'a> {
cursor: <F as HasCursor>::Cursor<'a>,
offset: u64,
}
let mut cstate: Option<CursorState<'_, F>> = None;

let mut fsm = ArchiveFsm::new(size);
loop {
if let Some(offset) = fsm.wants_read() {
trace!(%offset, "read_zip_with_size: wants_read, space len = {}", fsm.space().len());
match self.cursor_at(offset).read(fsm.space()) {

let mut cstate_next = match cstate.take() {
Some(cstate) => {
if cstate.offset == offset {
// all good, re-using
cstate
} else {
CursorState {
cursor: self.cursor_at(offset),
offset,
}
}
}
None => CursorState {
cursor: self.cursor_at(offset),
offset,
},
};

match cstate_next.cursor.read(fsm.space()) {
Ok(read_bytes) => {
cstate_next.offset += read_bytes as u64;
cstate = Some(cstate_next);

trace!(%read_bytes, "read_zip_with_size: read");
if read_bytes == 0 {
return Err(Error::IO(std::io::ErrorKind::UnexpectedEof.into()));
Expand Down
32 changes: 31 additions & 1 deletion rc-zip-tokio/src/read_zip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,41 @@ where
type File = F;

async fn read_zip_with_size(&self, size: u64) -> Result<ArchiveHandle<'_, F>, Error> {
struct CursorState<'a, F: HasCursor + 'a> {
cursor: <F as HasCursor>::Cursor<'a>,
offset: u64,
}
let mut cstate: Option<CursorState<'_, F>> = None;

let mut fsm = ArchiveFsm::new(size);
loop {
if let Some(offset) = fsm.wants_read() {
match self.cursor_at(offset).read(fsm.space()).await {
trace!(%offset, "read_zip_with_size: wants_read, space len = {}", fsm.space().len());

let mut cstate_next = match cstate.take() {
Some(cstate) => {
if cstate.offset == offset {
// all good, re-using
cstate
} else {
CursorState {
cursor: self.cursor_at(offset),
offset,
}
}
}
None => CursorState {
cursor: self.cursor_at(offset),
offset,
},
};

match cstate_next.cursor.read(fsm.space()).await {
Ok(read_bytes) => {
cstate_next.offset += read_bytes as u64;
cstate = Some(cstate_next);

trace!(%read_bytes, "read_zip_with_size: read");
if read_bytes == 0 {
return Err(Error::IO(io::ErrorKind::UnexpectedEof.into()));
}
Expand Down

0 comments on commit a34a302

Please sign in to comment.