From d17b55089a78f0d7d5e2a926dc36ee8068785b5f Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Mon, 16 May 2016 09:49:05 -0600 Subject: [PATCH] More efficient reads --- src/filesystem.rs | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/src/filesystem.rs b/src/filesystem.rs index dd948c8..bbb3e21 100644 --- a/src/filesystem.rs +++ b/src/filesystem.rs @@ -1,3 +1,5 @@ +use std::cmp::min; + use system::error::{Result, Error, EEXIST, EISDIR, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY}; use super::{Disk, ExNode, Extent, Header, Node}; @@ -398,19 +400,51 @@ impl FileSystem { let mut i = 0; for extent in extents.iter() { - for (block, size) in extent.blocks() { + let mut block = extent.block; + let mut length = extent.length; + + if byte_offset > 0 && length > 0 { let mut sector = [0; 512]; try!(self.read_at(block, &mut sector)); - if byte_offset < size && i < buf.len() { - for (s_b, mut b) in sector[byte_offset..size].iter().zip(buf[i..].iter_mut()) { - *b = *s_b; - i += 1; - } + let sector_size = min(sector.len() as u64, length) as usize; + for (s_b, mut b) in sector[byte_offset..sector_size].iter().zip(buf[i..].iter_mut()) { + *b = *s_b; + i += 1; } + block += 1; + length -= sector_size as u64; + byte_offset = 0; } + + let length_aligned = ((min(length, (buf.len() - i) as u64)/512) * 512) as usize; + + if length_aligned > 0 { + let extent_buf = &mut buf[i..i + length_aligned]; + try!(self.read_at(block, extent_buf)); + i += length_aligned; + block += (length_aligned as u64)/512; + length -= length_aligned as u64; + } + + if length > 0 { + let mut sector = [0; 512]; + try!(self.read_at(block, &mut sector)); + + let sector_size = min(sector.len() as u64, length) as usize; + for (s_b, mut b) in sector[..sector_size].iter().zip(buf[i..].iter_mut()) { + *b = *s_b; + i += 1; + } + + block += 1; + length -= sector_size as u64; + } + + assert_eq!(length, 0); + assert_eq!(block, extent.block + (extent.length + 511)/512); } Ok(i) -- GitLab