File: extentlistset_test.ml

package info (click to toggle)
xen-api-libs 0.5.2-3
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,940 kB
  • sloc: ml: 13,925; sh: 2,930; ansic: 1,699; makefile: 1,240; python: 83
file content (92 lines) | stat: -rw-r--r-- 3,173 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
(* We will check if a list of set equalities hold over random inputs *)

open Set_test

(* We test using the integer domain only. *)
module Intextentlist = ExtentlistSet.ExtentlistSet(struct 
  type t=int 
  let zero=0 
  let add=(+) 
  let sub=(-) 
end)
open Intextentlist

(* Sets are finite, up to cardinality [size] *)
let size = 1000

module Tests = SetEqualities(struct
	type t = Intextentlist.t
	let universe = of_list [(0, size)]
	let (+) = union
	let (^) = intersection
	let (-) = difference

	let not x = universe - x
	let (=) x y = (x - y = empty) && (y - x = empty)
	let extent_to_string (s, l) = Printf.sprintf "(%d, %d)" s l
	let to_string xs = String.concat ", " (List.map extent_to_string (to_list xs))
end)
(* Given a triple of inputs, check that all the set equalities hold *)
let one (a, b, c) = List.iter (fun f -> f a b c) Tests.all

open LazyList

(** [make p s e] return an extentlist starting at [s], ending before [e] where
    an integer x is covered by the extentlist iff [p x] *)
let make p s e =
  let rec ints acc a b = if a < b then ints (a :: acc) (a + 1) b else acc in
  of_list (List.fold_left (fun acc x -> if p x then (x, 1)::acc else acc) [] (ints [] s e))

(* A lazy-list of random triples (a, b, c)*)
let random_inputs =	
  let one () = make (fun _ -> Random.bool ()) 0 (size - 1) in
  (* Create triples of random inputs for the checker *)
  let three () = one (), one (), one () in
  let rec f () = lazy (Cons(three (), f ())) in
  f ()

let _ = 
  let n = 1000 in
  iter (fun _ -> ()) (take n (map one random_inputs));
  Printf.printf "%d random sets of maximum size %d checked.\n" n size

type run = 
  | Empty of int
  | Full of int
let to_run_list xs = 
  let rec inner acc index = function
	| [] -> acc
	| (x, y) :: xs -> inner (Full y :: (Empty (x - index)) :: acc) (x + y) xs in  let map f xs = 
	let rec inner acc f = function
	  | [] -> acc
	  | (x :: xs) -> inner ((f x)::acc) f xs in
	  inner [] f xs in

	List.rev (inner [] 0 xs)

let _ =
  (* vhds have max size of 2 TiB, in 2 MiB blocks => 2**20 blocks *)
  (* The BAT consists of up to 2**20 blocks in any order *)
  (* Worst case for us is as many singleton blocks as possible, which *)
  (* can't be coalesced because they don't have neighbours. The maximum *)
  (* number of blocks is achieved with the allocation pattern 10101010... *)
  (* i.e. 2**19 singleton blocks. *)

  (* As a bitmap we would have 2**19 / 2**3 = 2**16 bytes (64kbit) *)
  let worst_case = make (fun x -> x mod 2 = 1) 0 (1024*1024/2/12) in
  let hex (a, b) = Printf.sprintf "%x,%x" a b in
  let to_string xs = "[" ^ (String.concat ";" (Listext.List.map_tr hex xs)) ^ "]" in


  Printf.printf "generated\n";
	let x = to_list worst_case in
Printf.printf "got a list\n";
	  let y = Listext.List.map_tr hex x in
Printf.printf "got lots of strings\n";
  let s = to_string (to_list worst_case) in
  Printf.printf "Extent size=%d\n" (String.length s);
	let string_of_run = function
	  | Empty x -> Printf.sprintf "-%d" x
	  | Full x -> Printf.sprintf "+%d" x in
	let s' = String.concat ";" (Listext.List.map_tr string_of_run (to_run_list x)) in
	  Printf.printf "Runs size=%d\n" (String.length s')