···11+22+ - [Traverse.Bfs]: new function `{fold,iter}_component_dist` to
33+ perform a breadth-first traversal with the distance from the source
1425# 2.1.0 (August 30, 2023)
36
+25
vendor/opam/ocamlgraph/src/traverse.ml
···278278279279 let iter_component f = fold_component (fun v () -> f v) ()
280280281281+ (* with distance from the source
282282+283283+ instead of using a queue, we use two bags
284284+ (`todo` with vertices at distance `d`
285285+ and `next` with vertices at distance `d+1`*)
286286+287287+ let fold_component_dist f acc g v0 =
288288+ let h = H.create 97 in
289289+ (* invariant: [h] contains exactly the vertices
290290+ which have been pushed *)
291291+ let push v next =
292292+ if H.mem h v then next
293293+ else (H.add h v (); v :: next) in
294294+ let rec loop acc d next = function
295295+ | [] -> if next = [] then acc
296296+ else loop acc (d+1) [] next
297297+ | v :: todo ->
298298+ let acc = f v d acc in
299299+ let next = G.fold_succ push g v next in
300300+ loop acc d next todo in
301301+ loop acc 0 [] (push v0 [])
302302+303303+ let iter_component_dist f =
304304+ fold_component_dist (fun v d () -> f v d) ()
305305+281306 (* step-by-step iterator *)
282307283308 (* simple, yet O(1)-amortized, persistent queues *)
+6
vendor/opam/ocamlgraph/src/traverse.mli
···134134 val fold_component : (G.V.t -> 'a -> 'a) -> 'a -> G.t -> G.V.t -> 'a
135135 (** Idem, but limited to a single root vertex. *)
136136137137+ (** {2 With the distance to the source} *)
138138+139139+ val fold_component_dist : (G.V.t -> int -> 'a -> 'a) -> 'a -> G.t -> G.V.t -> 'a
140140+141141+ val iter_component_dist : (G.V.t -> int -> unit) -> G.t -> G.V.t -> unit
142142+137143 (** {2 Step-by-step iterator}
138144 See module [Dfs] *)
139145