:: commit 3084b81fa8a5346c58fcdeabe7195b253b0da7f5

KrekBuk <register@mrgregorix.net> — 2020-05-02 14:00

parents: b842720a70

FAT32: improve non-fragmented files read times fat32_read now looks for non-fragmented chains to load large files in single read_partition call which should improve performance for reading larger files.

diff --git a/src/fs/fat32.c b/src/fs/fat32.c
index 208c6002..ff6505f2 100644
--- a/src/fs/fat32.c
+++ b/src/fs/fat32.c
@@ -277,16 +277,35 @@ int fat32_read(struct fat32_file_handle* file, void* buf, uint64_t loc, uint64_t
         loc -= cluster_size;
     }
 
-    uint64_t readTotal = 0;
+    uint64_t read_total = 0;
 
     do {
+        // find non-fragmented cluster chains to improve read performance
+        uint32_t non_fragmented_clusters = 1;
+        for (size_t i = 0 ; i < count / cluster_size; i++) {
+            uint32_t next_cluster;
+
+            r = fat32_read_cluster_from_map(&file->context, current_cluster_number + i, &next_cluster);
+
+            if (r != 0) {
+                print("fat32: failed to read cluster %x from map\n", current_cluster_number);
+                return r;
+            }
+
+            if (next_cluster != current_cluster_number + i + 1) {
+                break;
+            }
+
+            non_fragmented_clusters++;
+        }
+
         // find largest read size
         uint64_t current_read = count;
-        if (current_read > cluster_size - loc) {
-            current_read = cluster_size - loc;
+        if (current_read > non_fragmented_clusters * cluster_size - loc) {
+            current_read = non_fragmented_clusters * cluster_size - loc;
         }
 
-        r = fat32_load_fat_cluster_to_memory(&file->context, current_cluster_number, buf + readTotal, loc, current_read);
+        r = fat32_load_fat_cluster_to_memory(&file->context, current_cluster_number, buf + read_total, loc, current_read);
 
         if (r != 0) {
             print("fat32: failed to load cluster %x to memory\n", current_cluster_number);
@@ -295,7 +314,7 @@ int fat32_read(struct fat32_file_handle* file, void* buf, uint64_t loc, uint64_t
 
         loc = 0;
         count -= current_read;
-        readTotal += current_read;
+        read_total += current_read;
 
         if (count == 0) {
             return 0;
tab: 248 wrap: offon