WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-api

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

To: xen-api@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-API] [PATCH 1 of 8] CA-43021: Small refactorings of the new sparse_dd code
From: David Scott <dave.scott@xxxxxxxxxxxxx>
Date: Mon, 23 Aug 2010 13:17:41 +0100
Delivery-date: Mon, 23 Aug 2010 05:39:22 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1282565860@ely>
List-help: <mailto:xen-api-request@lists.xensource.com?subject=help>
List-id: Discussion of API issues surrounding Xen <xen-api.lists.xensource.com>
List-post: <mailto:xen-api@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-api>, <mailto:xen-api-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1282565860@ely>
Sender: xen-api-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.4.3
# 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