From 66c675c7657f831886eab6fec00e3f594fec7d14 Mon Sep 17 00:00:00 2001 From: David Scott Date: Tue, 23 Jan 2018 12:09:34 +0000 Subject: [PATCH] fusedump: read packets lazily from the stream Previously the packets were all read into a list which required a lot of memory for long traces. This patch reads the packets lazily from the stream, just in time to pretty-print them. This reduces the memory footprint of fusedump and removes the initial start-up delay where previously the whole file was parsed. Signed-off-by: David Scott --- src/fusedump.ml | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/fusedump.ml b/src/fusedump.ml index a82a7b8..9bad084 100644 --- a/src/fusedump.ml +++ b/src/fusedump.ml @@ -191,10 +191,9 @@ let parse_packet host query_table fd = in Some (now, packet) -let parse_session filename = +let packet_stream_of_fd fd = let header_len = 4 + 1 + 1 + 2 in let bheader = Bytes.create header_len in - with_open_fd filename @@ fun fd -> let header_read = Unix.read fd bheader 0 header_len in let header = Bytes.to_string bheader in (if header_read <> header_len then failwith "couldn't read header"); @@ -211,11 +210,15 @@ let parse_session filename = | c -> failf "unknown host type '%c'" c in let query_table = Hashtbl.create 128 in - let rec read_next session = match parse_packet host query_table fd with - | None -> List.rev session - | Some packet -> read_next (packet::session) + let rec read_next () = match parse_packet host query_table fd with + | None -> `Eof + | Some packet -> `Next(packet, read_next) in - read_next [] + read_next () + +let rec iter f = function + | `Eof -> () + | `Next(packet, rest) -> f packet; iter f (rest ()) let pretty_print time (t, p) = Printf.printf "%s%s\n%!" @@ -228,8 +231,9 @@ let pretty_print time (t, p) = let show time session_file = try - let session = parse_session session_file in - List.iter (pretty_print time) session; + with_open_fd session_file @@ fun fd -> + let session = packet_stream_of_fd fd in + iter (pretty_print time) session; `Ok () with exn -> `Error (false,