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

[Xen-API] [PATCH 1 of 8] CA-43021: Small refactorings of the new sparse_dd code



# HG changeset patch
# User David Scott <dave.scott@xxxxxxxxxxxxx>
# Date 1282565809 -3600
# Node ID 9de4d96802c250f68519c26b7c021c41beda995b
# Parent  4aeb389f3b5a2e88c87228094217b7d092ed22ca
CA-43021: Small refactorings of the new sparse_dd code.

Split the 'Stream' signature into two since we don't have to be reading and 
writing to the same kind of data.
Add a convenient 'substring' record type rather than passing around multiple 
arguments all the time.

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

diff -r 4aeb389f3b5a -r 9de4d96802c2 ocaml/xapi/sparse_dd.ml
--- a/ocaml/xapi/sparse_dd.ml   Mon Aug 23 13:09:56 2010 +0100
+++ b/ocaml/xapi/sparse_dd.ml   Mon Aug 23 13:16:49 2010 +0100
@@ -23,13 +23,20 @@
        let quantum = 16384 in
        ((x + quantum + quantum - 1) / quantum) * quantum
 
-(** The copying routine can operate on anything which looks like a 
file-descriptor/Stream *)
-module type Stream = sig
-       type stream
-       val read: stream -> int64 -> string -> int -> int -> unit
-       val write: stream -> int64 -> string -> int -> int -> int
+(** 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
+       type t
+       val op: t -> int64 -> substring -> unit
 end
-
+       
 (* [fold_over_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]. *)
@@ -51,22 +58,21 @@
 }
 
 (** Perform the data duplication ("DD") *)
-module DD(S : Stream) = struct
+module DD(Input : IO)(Output : IO) = struct
        (** [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: S.stream) (dst: S.stream) size = 
+       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));   
-                       S.read src offset buf 0 (Int64.to_int this_chunk);
+                       Input.op src offset { buf = buf; offset = 0; len = 
Int64.to_int this_chunk };
                        let write_extent stats (s, e) = 
-                               let n = S.write dst (offset +* (Int64.of_int 
s)) buf s e in
-                               if n < e then raise (ShortWrite(s, e, n));
-                               { stats with writes = stats.writes + 1; bytes = 
stats.bytes +* (Int64.of_int n) }
+                               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
@@ -77,54 +83,57 @@
 end
 
 (* Helper function to always return a block of zeroes, like /dev/null *)
-let read_zeroes _ _ buf offset len = 
-       for i = 0 to len - 1 do
-               buf.[offset + i] <- '\000'
-       done
+module Zero_reader = struct
+       type t = unit
+       let op _ _ { buf = buf; offset = offset; len = len } = 
+               for i = 0 to len - 1 do
+                       buf.[offset + i] <- '\000'
+               done
+end
 
-(** A Stream interface implemented over strings, useful for testing *)
-module String_stream = struct
-       type stream = string
-       let blit src srcoff dst dstoff len = 
-               (* Printf.printf "[%s](%d) -> [%s](%d) %d\n" "?" srcoff "?" 
dstoff len; *)
-               String.blit src srcoff dst dstoff len
-       let read str stream_offset buf offset len = 
+let blit src srcoff dst dstoff len = 
+       (* Printf.printf "[%s](%d) -> [%s](%d) %d\n" "?" srcoff "?" dstoff len; 
*)
+       String.blit src srcoff dst dstoff len
+
+module String_reader = struct
+       type t = string
+       let op str stream_offset { buf = buf; offset = offset; len = len } = 
                blit str (Int64.to_int stream_offset) buf offset len
-       let write str stream_offset buf offset len = 
-               blit buf offset str (Int64.to_int stream_offset) len;
-               len
+end
+module String_writer = struct
+       type t = string
+       let op str stream_offset { buf = buf; offset = offset; len = len } = 
+               blit buf offset str (Int64.to_int stream_offset) len
 end
 
 (** A File interface implemented over open Unix files *)
-module File_stream = struct
-       type stream = Unix.file_descr
-               
-       let read stream stream_offset buf offset len = 
+module File_reader = struct
+       type t = Unix.file_descr
+       let op stream stream_offset { buf = buf; offset = offset; len = len } = 
                Unix.LargeFile.lseek stream stream_offset Unix.SEEK_SET; 
                Unixext.really_read stream buf offset len 
-       let write stream stream_offset buf offset len = 
+end
+module File_writer = struct
+       type t = Unix.file_descr
+       let op stream stream_offset { buf = buf; offset = offset; len = len } = 
                let newoff = Unix.LargeFile.lseek stream stream_offset 
Unix.SEEK_SET in
                (* Printf.printf "Unix.write buf len %d; offset %d; len %d\n" 
(String.length buf) offset len; *)
-               Unix.write stream buf offset len
+               let n = Unix.write stream buf offset len in
+               if n < len
+               then raise (ShortWrite(offset, len, n))
 end
 
 (** An implementation of the DD algorithm over strings *)
-module String_copy = DD(String_stream)
+module String_copy = DD(String_reader)(String_writer)
 
 (** An implementatino of the DD algorithm which copies zeroes into strings *)
-module String_write_zero = DD(struct
-       include String_stream
-       let read = read_zeroes
-end)
+module String_write_zero = DD(Zero_reader)(String_writer)
 
 (** An implementatino of the DD algorithm over Unix files *)
-module File_copy = DD(File_stream)
+module File_copy = DD(File_reader)(File_writer)
 
 (** An implementatin of the DD algorithm which copies zeroes into files *)
-module File_write_zero = DD(struct
-       include File_stream
-       let read = read_zeroes
-end)
+module File_write_zero = DD(Zero_reader)(File_writer)
 
 (** [file_dd ?progress_cb ?size ?bat prezeroed src dst]
     If [size] is not given, will assume a plain file and will use st_size from 
Unix.stat.
@@ -154,7 +163,7 @@
                (fun fraction -> progress_cb (0.5 *. fraction)),
                (fun fraction -> progress_cb (0.5 *. fraction +. 0.5)) in
        Printf.printf "Wiping\n";
-       File_write_zero.copy progress_cb_zero bat' None ifd ofd size;
+       File_write_zero.copy progress_cb_zero bat' None () ofd size;
        Printf.printf "Copying\n";
        File_copy.copy progress_cb_copy bat (if prezeroed then Some '\000' else 
None) ifd ofd size
 
@@ -199,7 +208,7 @@
                let bat' = if prezeroed
                then empty_bat
                else Bat.difference full_bat bat in     
-               String_write_zero.copy (fun _ -> ()) bat' None input output 
(Int64.of_int size);
+               String_write_zero.copy (fun _ -> ()) bat' None () output 
(Int64.of_int size);
                let stats = String_copy.copy (fun _ -> ()) bat (if prezeroed 
then Some zero else None) input output (Int64.of_int size) in
                assert (String.compare input output = 0);
                stats
 ocaml/xapi/sparse_dd.ml |  97 ++++++++++++++++++++++++++----------------------
 1 files changed, 53 insertions(+), 44 deletions(-)


Attachment: xen-api.hg-1.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®.