···11+diff --git a/serlib/ser_stdlib.ml b/serlib/ser_stdlib.ml
22+index 894d300..11c9217 100644
33+--- a/serlib/ser_stdlib.ml
44++++ b/serlib/ser_stdlib.ml
55+@@ -28,6 +28,7 @@ let ref_to_yojson f x = f !x
66+ let ref_of_yojson f x = Result.map (fun x -> ref x) (f x)
77+ let hash_fold_ref = hash_fold_ref_frozen
88+ let compare_ref = compare_ref
99++let (==) x y = (==) x y
1010+1111+ module Lazy = struct
1212+ type 'a t = 'a lazy_t
1313+@@ -35,3 +36,4 @@ module Lazy = struct
1414+ end
1515+1616+ module Option = Stdlib.Option
1717++module List = Stdlib.List
···11+diff --git a/lib/engine/scheduler.ml b/lib/engine/scheduler.ml
22+index e32bd0f..93b566b 100644
33+--- a/lib/engine/scheduler.ml
44++++ b/lib/engine/scheduler.ml
55+@@ -601,7 +601,7 @@ module Make(Backend : Backend) = struct
66+ )
77+ )
88+ | Trywith tw -> (
99+- match Table.find sched.traces (Workflow.id tw.w) with
1010++ match Hashtbl.find sched.traces (Workflow.id tw.w) with
1111+ | Some eventual_trace -> (
1212+ eventual_trace >>= function
1313+ | Ok (Run r) ->
1414+@@ -667,10 +667,10 @@ module Make(Backend : Backend) = struct
1515+ let register_build sched ~id ~build_trace =
1616+ let open Eval_thread.Infix in
1717+ (
1818+- match Table.find sched.traces id with
1919++ match Hashtbl.find sched.traces id with
2020+ | None ->
2121+ let trace = build_trace () in
2222+- Table.set sched.traces ~key:id ~data:trace ;
2323++ Hashtbl.set sched.traces ~key:id ~data:trace ;
2424+ trace
2525+ | Some trace -> trace
2626+ ) >>= fun trace ->
2727+@@ -854,7 +854,7 @@ module Make(Backend : Backend) = struct
2828+ Eval_thread.join l.elts ~f:(build ?target sched)
2929+ | Trywith tw -> (
3030+ build sched ?target tw.w >> fun w_result ->
3131+- match Table.find sched.traces (Workflow.id tw.w) with
3232++ match Hashtbl.find sched.traces (Workflow.id tw.w) with
3333+ | Some eventual_trace -> (
3434+ eventual_trace >> function
3535+ | Ok (Run r) when run_trywith_recovery r.details ->
3636+diff --git a/lib/multinode/bistro_multinode.ml b/lib/multinode/bistro_multinode.ml
3737+index 01dc5ac..3fc6b0e 100644
3838+--- a/lib/multinode/bistro_multinode.ml
3939++++ b/lib/multinode/bistro_multinode.ml
4040+@@ -130,7 +130,7 @@ module Server = struct
4141+ let search (type s) (table : s String.Table.t) ~f =
4242+ let module M = struct exception Found of string * s end in
4343+ try
4444+- String.Table.fold table ~init:() ~f:(fun ~key ~data () -> if f ~key ~data then raise (M.Found (key, data))) ;
4545++ Hashtbl.fold table ~init:() ~f:(fun ~key ~data () -> if f ~key ~data then raise (M.Found (key, data))) ;
4646+ None
4747+ with M.Found (k, v) -> Some (k, v)
4848+4949+@@ -145,7 +145,7 @@ module Server = struct
5050+ match allocation_attempt with
5151+ | None -> Some elt
5252+ | Some (worker_id, (Resource curr)) ->
5353+- String.Table.set pool.available ~key:worker_id ~data:(Resource { np = curr.np - np ; mem = curr.mem - mem }) ;
5454++ Hashtbl.set pool.available ~key:worker_id ~data:(Resource { np = curr.np - np ; mem = curr.mem - mem }) ;
5555+ Lwt.wakeup u (worker_id, Resource { np ; mem }) ;
5656+ None
5757+ )
5858+@@ -163,12 +163,12 @@ module Server = struct
5959+ t
6060+6161+ let add_worker pool (Worker { id ; np ; mem ; _ }) =
6262+- match String.Table.add pool.available ~key:id ~data:(Allocator.Resource { np ; mem }) with
6363++ match Hashtbl.add pool.available ~key:id ~data:(Allocator.Resource { np ; mem }) with
6464+ | `Ok -> allocation_pass pool
6565+ | `Duplicate -> failwith "A worker has been added twice"
6666+6767+ let release pool worker_id (Allocator.Resource { np ; mem }) =
6868+- String.Table.update pool.available worker_id ~f:(function
6969++ Hashtbl.update pool.available worker_id ~f:(function
7070+ | None -> failwith "Tried to release resources of inexistent worker"
7171+ | Some (Resource r) -> Resource { np = r.np + np ; mem = r.mem + mem }
7272+ )
7373+@@ -235,13 +235,13 @@ module Server = struct
7474+ | Subscript { np ; mem } ->
7575+ let id = new_id () in
7676+ let w = create_worker ~np ~mem id in
7777+- String.Table.set state.workers ~key:id ~data:w ;
7878++ Hashtbl.set state.workers ~key:id ~data:w ;
7979+ Worker_allocator.add_worker state.alloc w ;
8080+ log (Logger.Debug (sprintf "new worker %s" id)) ;
8181+ Lwt.return (Client_id id)
8282+8383+ | Get_job { client_id } -> (
8484+- match String.Table.find state.workers client_id with
8585++ match Hashtbl.find state.workers client_id with
8686+ | None -> Lwt.return None
8787+ | Some (Worker worker) ->
8888+ Lwt.choose [
8989+@@ -250,22 +250,22 @@ module Server = struct
9090+ ] >>= function
9191+ | `Job wp ->
9292+ let workflow_id = workflow_id_of_job_waiter wp in
9393+- String.Table.set worker.running_jobs ~key:workflow_id ~data:wp ;
9494++ Hashtbl.set worker.running_jobs ~key:workflow_id ~data:wp ;
9595+ Lwt.return (Some (job_of_job_waiter wp))
9696+ | `Stop -> Lwt.return None
9797+ )
9898+9999+ | Plugin_result r ->
100100+- let Worker worker = String.Table.find_exn state.workers r.client_id in
101101++ let Worker worker = Hashtbl.find_exn state.workers r.client_id in
102102+ Lwt.return (
103103+- match String.Table.find_exn worker.running_jobs r.workflow_id with
104104++ match Hashtbl.find_exn worker.running_jobs r.workflow_id with
105105+ | Waiting_plugin wp -> Lwt.wakeup wp.waiter r.result
106106+ | Waiting_shell_command _ -> assert false (* should never happen *)
107107+ )
108108+ | Shell_command_result r ->
109109+- let Worker worker = String.Table.find_exn state.workers r.client_id in
110110++ let Worker worker = Hashtbl.find_exn state.workers r.client_id in
111111+ Lwt.return (
112112+- match String.Table.find_exn worker.running_jobs r.workflow_id with
113113++ match Hashtbl.find_exn worker.running_jobs r.workflow_id with
114114+ | Waiting_plugin _ -> assert false (* should never happen *)
115115+ | Waiting_shell_command wp -> Lwt.wakeup wp.waiter r.result
116116+ )
117117+@@ -307,7 +307,7 @@ module Server = struct
118118+119119+ let request_resource backend req =
120120+ Worker_allocator.request backend.state.alloc req >|= fun (worker_id, resource) ->
121121+- String.Table.find_exn backend.state.workers worker_id, resource
122122++ Hashtbl.find_exn backend.state.workers worker_id, resource
123123+124124+ let release_resource backend worker_id res =
125125+ Worker_allocator.release backend.state.alloc worker_id res
126126+@@ -334,7 +334,7 @@ module Server = struct
127127+ * loop () *)
128128+129129+ let eval backend { worker_id ; workflow_id } f x =
130130+- let Worker worker = String.Table.find_exn backend.state.workers worker_id in
131131++ let Worker worker = Hashtbl.find_exn backend.state.workers worker_id in
132132+ let f () = f x in
133133+ let t, u = Lwt.wait () in
134134+ let job_waiter = Waiting_plugin { waiter = u ; f ; workflow_id } in
135135+@@ -342,7 +342,7 @@ module Server = struct
136136+ t
137137+138138+ let run_shell_command backend { worker_id ; workflow_id } cmd =
139139+- let Worker worker = String.Table.find_exn backend.state.workers worker_id in
140140++ let Worker worker = Hashtbl.find_exn backend.state.workers worker_id in
141141+ let t, u = Lwt.wait () in
142142+ let job = Waiting_shell_command { waiter = u ; cmd ; workflow_id } in
143143+ Lwt_queue.push worker.pending_jobs job ;
144144+diff --git a/lib/utils/dot_output.ml b/lib/utils/dot_output.ml
145145+index 90c299f..d13fceb 100644
146146+--- a/lib/utils/dot_output.ml
147147++++ b/lib/utils/dot_output.ml
148148+@@ -24,7 +24,7 @@ module G = struct
149149+ (* let successors g u = fold_succ (fun h t -> h :: t) g u [] *)
150150+151151+ let rec of_workflow_aux seen acc u =
152152+- if S.mem seen u then (seen, acc)
153153++ if Set.mem seen u then (seen, acc)
154154+ else (
155155+ let deps = W.Any.deps u in
156156+ let seen, acc =
157157+@@ -34,7 +34,7 @@ module G = struct
158158+ in
159159+ let acc = add_vertex acc u in
160160+ let acc = List.fold deps ~init:acc ~f:(fun acc v -> add_edge acc u v) in
161161+- let seen = S.add seen u in
162162++ let seen = Set.add seen u in
163163+ seen, acc
164164+ )
165165+166166+@@ -109,7 +109,7 @@ let dot_output ?db oc g ~needed =
167167+ ]
168168+ in
169169+ let vertex_attributes u =
170170+- let needed = (match db with None -> true | Some _ -> false) || S.mem needed u in
171171++ let needed = (match db with None -> true | Some _ -> false) || Set.mem needed u in
172172+ let color = if needed then black else light_gray in
173173+ let shape = `Shape (shape u) in
174174+ let W.Any w = u in
175175+@@ -141,7 +141,7 @@ let dot_output ?db oc g ~needed =
176176+ | _ -> []
177177+ in
178178+ let color =
179179+- if (match db with None -> true | Some _ -> false) || (S.mem needed u && not (already_done u))
180180++ if (match db with None -> true | Some _ -> false) || (Set.mem needed u && not (already_done u))
181181+ then black else light_gray in
182182+ style @ [ `Color color ]
183183+ in
184184+diff --git a/lib/utils/repo.ml b/lib/utils/repo.ml
185185+index 06abcd5..206a99e 100644
186186+--- a/lib/utils/repo.ml
187187++++ b/lib/utils/repo.ml
188188+@@ -160,7 +160,7 @@ let protected_set repo =
189189+ | Select s -> fold_path_workflow acc (W.Any s.dir)
190190+ | Input _ -> acc
191191+ | Shell _
192192+- | Plugin _ -> String.Set.add acc (W.id w)
193193++ | Plugin _ -> Set.add acc (W.id w)
194194+ | Trywith tw ->
195195+ fold_path_workflow (fold_path_workflow acc (W.Any tw.w)) (W.Any tw.failsafe)
196196+ | Ifelse ie ->
197197+@@ -187,7 +187,7 @@ let cache_clip_fold ~bistro_dir repo ~f ~init =
198198+ let protected = protected_set repo in
199199+ let db = Db.init_exn bistro_dir in
200200+ Db.fold_cache db ~init ~f:(fun acc id ->
201201+- f db acc (if String.Set.mem protected id then `Protected id else `Unprotected id)
202202++ f db acc (if Set.mem protected id then `Protected id else `Unprotected id)
203203+ )
204204+205205+ let cache_clip_dry_run ~bistro_dir repo =