(**************************************************************************) (* *) (* Copyright (C) 2012 Johannes 'josch' Schauer *) (* Copyright (C) 2012 Pietro Abate *) (* *) (* This library is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Lesser General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version. A special linking *) (* exception to the GNU Lesser General Public License applies to this *) (* library, see the COPYING file for more information. *) (**************************************************************************) open! ExtLib open Common module StringSet = BootstrapCommon.StringSet module Make (U : sig val univ : Cudf.universe end) = struct module G = BuildGraph.G module FindCyclesG = GraphUtils.FindCycles(G) module BGE = BuildGraphExtras.Make(struct let univ = U.univ end) let edges_in_most_cycles g cycles = let hist = FindCyclesG.get_cycles_per_edge_ht g cycles in let builddep_edges = List.filter (fun (k,_) -> match k with | (_,{BuildGraph.depend = BuildGraph.BuildDep},_) -> true | (_,{BuildGraph.depend = BuildGraph.BuildsFrom _},_) -> false ) (Hashtbl.fold (fun k v acc -> (k,v)::acc) hist []) in let cmp (v1, c1) (v2, c2) = let c = compare c2 c1 in if c <> 0 then c else match v1,v2 with | (sv1,{BuildGraph.depend = BuildGraph.BuildDep},iv1),(sv2,{BuildGraph.depend = BuildGraph.BuildDep},iv2) -> let srcpkgcmp = compare (BuildGraph.Unique.uid sv1) (BuildGraph.Unique.uid sv2) in if srcpkgcmp <> 0 then srcpkgcmp else compare (BuildGraph.Unique.uid iv1) (BuildGraph.Unique.uid iv2) | _ -> failwith "impossible" in List.sort ~cmp builddep_edges let min_builddep g = let src_vertices = G.fold_vertex (fun v acc -> let vertex = BuildGraph.Unique.value v in match vertex with | BuildGraph.SrcPkg id -> let p = CudfAdd.inttopkg U.univ id in (p, BGE.pkglist_of_vlist (G.succ g v))::acc | _ -> acc ) g [] in List.sort ~cmp:(fun (p1,a) (p2,b) -> let num_comp = compare (List.length a) (List.length b) in match num_comp with | 0 -> CudfAdd.compare p1 p2 | n -> n ) src_vertices let get_src_bin_stats g = G.fold_vertex (fun v acc -> let succ = List.length (G.succ g v) in let pred = List.length (G.pred g v) in (v, succ, pred)::acc ) g [] let ratio_source g = let src_vertices = G.fold_vertex (fun v acc -> let vertex = BuildGraph.Unique.value v in match vertex with | BuildGraph.SrcPkg id -> let p = CudfAdd.inttopkg U.univ id in let num_builddeps = List.length (G.succ g v) in let neededby = G.pred g v in let builddepof = List.fold_left (fun acc s -> (G.pred g s)@acc) [] neededby in (p, num_builddeps, BGE.pkglist_of_vlist neededby, (BootstrapCommon.CudfSet.elements (CudfAdd.to_set (BGE.pkglist_of_vlist builddepof))))::acc | _ -> acc ) g [] in List.sort ~cmp:(fun (p1,a1,_,a2) (p2,b1,_,b2) -> let num_comp = compare ((float_of_int b1)/.(float_of_int (List.length b2))) ((float_of_int a1)/.(float_of_int (List.length a2))) in match num_comp with | 0 -> CudfAdd.compare p1 p2 | n -> n ) src_vertices let ratio_binary g = let bin_vertices = G.fold_vertex (fun v acc -> let vertex = BuildGraph.Unique.value v in match vertex with | BuildGraph.InstSet (id,_) -> let p = CudfAdd.inttopkg U.univ id in let num_srcpkgs = List.length (G.succ g v) in let builddepof = G.pred g v in (p, num_srcpkgs, BGE.pkglist_of_vlist builddepof)::acc | _ -> acc ) g [] in List.sort ~cmp:(fun (p1,a1,a2) (p2,b1,b2) -> let num_comp = compare ((float_of_int b1)/.(float_of_int (List.length b2))) ((float_of_int a1)/.(float_of_int (List.length a2))) in match num_comp with | 0 -> CudfAdd.compare p1 p2 | n -> n ) bin_vertices let only_weak_missing weak_deps_set g = let only_weak = G.fold_vertex (fun v acc -> let vertex = BuildGraph.Unique.value v in match vertex with | BuildGraph.SrcPkg id -> let p = CudfAdd.inttopkg U.univ id in let bd = G.fold_succ (fun v2 acc -> let vertex2 = BuildGraph.Unique.value v2 in match vertex2 with | BuildGraph.InstSet (id,_) -> (CudfAdd.inttopkg U.univ id)::acc | _ -> failwith "impossible" ) g v [] in let bds = List.fold_left (fun acc p -> StringSet.add (p.Cudf.package) acc ) StringSet.empty bd in if StringSet.subset bds weak_deps_set then (p,bd)::acc else acc | _ -> acc ) g [] in List.sort ~cmp:(fun (s1,l1) (s2,l2) -> let num_comp = compare (List.length l2) (List.length l1) in match num_comp with | 0 -> CudfAdd.compare s1 s2 | n -> n ) only_weak end