-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtest_ancient_dict_write.ml
91 lines (76 loc) · 2.36 KB
/
test_ancient_dict_write.ml
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
(* Create shared dictionary. *)
open Test_ancient_dict
open Printf
open Unix
let argv = Array.to_list Sys.argv
let wordsfile, datafile, baseaddr =
match argv with
| [_; wordsfile; datafile; baseaddr] ->
let baseaddr = Nativeint.of_string baseaddr in
wordsfile, datafile, baseaddr
| _ ->
failwith (sprintf "usage: %s wordsfile datafile baseaddr"
Sys.executable_name)
let md =
let fd = openfile datafile [O_RDWR; O_TRUNC; O_CREAT] 0o644 in
Ancient.attach fd baseaddr
(* Tree used to store the words. This is stupid and inefficient
* but it is here to demonstrate the 'Ancient' module, not good use
* of trees.
*)
let arraysize = 256 (* one element for each character *)
let tree : tree array = Array.make arraysize Not_Found
let add_to_tree word =
let len = String.length word in
if len > 0 then (
let tree = ref tree in
for i = 0 to len-2; do
let c = word.[i] in
let c = Char.code c in
match (!tree).(c) with
| Not_Found ->
(* Allocate more tree. *)
let tree' = Array.make arraysize Not_Found in
(!tree).(c) <- Not_Exists tree';
tree := tree'
| Exists (witness, tree') ->
assert ( Array.length witness = witness_size);
tree := tree'
| Not_Exists tree' ->
tree := tree'
done;
(* Final character. *)
let c = word.[len-1] in
let c = Char.code c in
match (!tree).(c) with
| Not_Found ->
(!tree).(c) <- Exists (Array.make witness_size 0, Array.make arraysize Not_Found)
| Exists (witness, _) ->
assert ( Array.length witness = witness_size);
() (* same word added twice *)
| Not_Exists tree' ->
(!tree).(c) <- Exists (Array.make witness_size 0,tree')
)
let () =
(* Read in the words and put them in the tree. *)
let chan = open_in wordsfile in
let count = ref 0 in
let rec loop () =
let word = input_line chan in
add_to_tree word;
incr count;
loop ()
in
(try loop () with End_of_file -> ());
close_in chan;
printf "Added %d words to the tree.\n" !count;
printf "Sharing tree in data file ...\n%!";
ignore (Ancient.share md 0 tree);
(* Perform a full GC and compact, which is a good way to see
* if we've trashed the OCaml heap in some way.
*)
Array.fill tree 0 arraysize Not_Found;
printf "Garbage collecting ...\n%!";
Gc.compact ();
printf "Detaching file and finishing.\n%!";
Ancient.detach md