Use tables of callbacks for the functions.
[virt-df.git] / diskzip / diskzip.ml
index 8acabc4..721335a 100644 (file)
@@ -182,14 +182,53 @@ and go_compress extcompress images =
       let size = disk#size in          (* Size in bytes. *)
       let nr_blocks = size /^ blocksize in (* Number of disk sectors. *)
 
-      (* Get the lookup function for this disk. *)
-      let lookup = Diskimage.get_owners_lookup machine ownership disk in
+      if !Diskimage.debug then
+       eprintf "Writing disk %s (%s sectors) ...\n%!"
+         disk#name (Int63.to_string nr_blocks);
 
-      (* Lookup each sector. *)
-      for blk = 0 to nr_blocks-1 do
-       ignore (lookup blk)
-      done
-  ) machine.Diskimage.m_disks;
+      (* Get the lookup function for this disk. *)
+      let lookup_offset =
+       Diskimage.get_owners_lookup machine ownership disk in
+
+      (* Convenience function to look up a block and test freeness. *)
+      let block_is_free blk =
+       let offset = blk *^ blocksize in
+       Diskimage.offset_is_free (lookup_offset offset)
+      in
+
+      (* Look up owners for each sector in turn. *)
+      let rec loop blk =
+       if blk < nr_blocks then (
+         (* The current sector (blk) is either free or not free.  Look
+          * for a stretch of sectors which are the same.
+          *)
+         let current_free = block_is_free blk in
+         let rec find_end blk =
+           if blk < nr_blocks then (
+             if block_is_free blk = current_free then
+               find_end (Int63.succ blk)
+             else
+               blk
+           ) else
+             nr_blocks                 (* End of the disk image. *)
+         in
+         let end_blk = find_end (Int63.succ blk) in
+
+         (* Current stretch is from blk .. end_blk-1. *)
+         if !Diskimage.debug then
+           eprintf "  %s stretch %s to %s-1 (%s bytes)\n"
+             (if current_free then "free" else "used")
+             (Int63.to_string blk) (Int63.to_string end_blk)
+             (Int63.to_string ((end_blk-^blk) *^ blocksize));
+
+
+
+
+         loop end_blk
+       )
+      in
+      loop ~^0
+  ) machine.Diskimage.m_disks