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