[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-API] [PATCH 2 of 8] CA-43021: More refactorings of the sparse_dd binary



# HG changeset patch
# User David Scott <dave.scott@xxxxxxxxxxxxx>
# Date 1282565810 -3600
# Node ID 24b830d6f50e96b7e78363dd2016278fc268c066
# Parent  9de4d96802c250f68519c26b7c021c41beda995b
CA-43021: More refactorings of the sparse_dd binary.

Split the DD operation into a 'fold' and a 'copy' (where the latter contains 
the side-effects, computes stats etc)
Move the substring record type into the Zerocheck module.

Signed-off-by: David Scott <dave.scott@xxxxxxxxxxxxx>

diff -r 9de4d96802c2 -r 24b830d6f50e ocaml/xapi/sparse_dd.ml
--- a/ocaml/xapi/sparse_dd.ml   Mon Aug 23 13:16:49 2010 +0100
+++ b/ocaml/xapi/sparse_dd.ml   Mon Aug 23 13:16:50 2010 +0100
@@ -4,6 +4,7 @@
 open Pervasiveext
 open Stringext
 open Listext
+open Zerocheck
 
 let ( +* ) = Int64.add
 let ( -* ) = Int64.sub
@@ -23,13 +24,6 @@
        let quantum = 16384 in
        ((x + quantum + quantum - 1) / quantum) * quantum
 
-(** Represents a substring without making a copy *)
-type substring = {
-       buf: string;
-       offset: int;
-       len: int;
-}
-
 (** The copying routine has inputs and outputs which both look like a 
     Unix file-descriptor *)
 module type IO = sig
@@ -37,10 +31,10 @@
        val op: t -> int64 -> substring -> unit
 end
        
-(* [fold_over_blocks (s, len) skip f initial] applies contiguous (start, 
length) pairs to 
+(* [partition_into_blocks (s, len) skip f initial] applies contiguous (start, 
length) pairs to 
    [f] starting at [s] up to maximum length [len] where each pair is as large 
as possible
    up to [skip]. *)
-let fold_over_blocks (s, len) skip f initial = 
+let partition_into_blocks (s, len) skip f initial = 
        let rec inner offset acc = 
                if offset = s +* len then acc
                else
@@ -59,27 +53,32 @@
 
 (** Perform the data duplication ("DD") *)
 module DD(Input : IO)(Output : IO) = struct
+       let fold bat sparse (src: Input.t) size f initial = 
+               let buf = String.create (Int64.to_int blocksize) in
+               let do_block acc (offset, this_chunk) =
+                       Input.op src offset { buf = buf; offset = 0; len = 
Int64.to_int this_chunk };
+                       begin match sparse with
+                       | Some zero -> fold_over_nonzeros buf (Int64.to_int 
this_chunk) roundup (f offset) acc
+                       | None -> f offset acc { buf = buf; offset = 0; len = 
Int64.to_int this_chunk }
+                       end in
+               (* For each entry from the BAT, copy it as a sequence of 
sub-blocks *)
+               Bat.fold_left (fun acc b -> partition_into_blocks b blocksize 
do_block acc) initial bat
+
        (** [copy progress_cb bat sparse src dst size] copies blocks of data 
from [src] to [dst]
            where [bat] represents the allocated / dirty blocks in [src];
            where if sparse is None it means don't scan for and skip over 
blocks of zeroes in [src]
            where if sparse is (Some c) it means do scan for and skip over 
blocks of 'c' in [src]
            while calling [progress_cb] frequently to report the fraction 
complete
        *)
-       let copy progress_cb bat sparse (src: Input.t) (dst: Output.t) size = 
-               let buf = String.create (Int64.to_int blocksize) in
-               let do_block stats (offset, this_chunk) : stats =
-                       progress_cb ((Int64.to_float offset) /. (Int64.to_float 
size));   
-                       Input.op src offset { buf = buf; offset = 0; len = 
Int64.to_int this_chunk };
-                       let write_extent stats (s, e) = 
-                               Output.op dst (offset +* (Int64.of_int s)) { 
buf = buf; offset = s; len = e };
-                               { stats with writes = stats.writes + 1; bytes = 
stats.bytes +* (Int64.of_int e) }
-                       in
-                       begin match sparse with
-                       | Some zero -> Zerocheck.fold_over_nonzeros buf 
(Int64.to_int this_chunk) roundup write_extent stats
-                       | None -> write_extent stats (0, Int64.to_int 
this_chunk)
-                       end in
-               (* For each entry from the BAT, copy it as a sequence of 
sub-blocks *)
-               Bat.fold_left (fun stats b -> fold_over_blocks b blocksize 
do_block stats) { writes = 0; bytes = 0L } bat
+       let copy progress_cb bat sparse src dst size =
+               let total_work = Bat.fold_left (fun total (_, size) -> total +* 
size) 0L bat in 
+               fold bat sparse src size
+                       (fun offset stats substr -> 
+                               Output.op dst (offset +* (Int64.of_int 
substr.offset)) substr;
+                               let stats' = { writes = stats.writes + 1; bytes 
= stats.bytes +* (Int64.of_int substr.len) } in
+                               progress_cb (Int64.to_float stats'.bytes /. 
(Int64.to_float total_work));
+                               stats')
+                       { writes = 0; bytes = 0L }
 end
 
 (* Helper function to always return a block of zeroes, like /dev/null *)
 ocaml/xapi/sparse_dd.ml |  47 +++++++++++++++++++++++------------------------
 1 files changed, 23 insertions(+), 24 deletions(-)


Attachment: xen-api.hg-2.patch
Description: Text Data

_______________________________________________
xen-api mailing list
xen-api@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/mailman/listinfo/xen-api

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.