Improve and augment the "func_dependency" doc

This commit is contained in:
Pierre Labastie 2021-12-30 14:20:43 +01:00
parent f81d8bdb6f
commit abadee36de

View file

@ -17,32 +17,42 @@
# 4 for external # # 4 for external #
# We should consider only edges with weight lower or equal to that # # We should consider only edges with weight lower or equal to that #
# specified by the user, but see below. # # specified by the user, but see below. #
# - we do not want to build the whole book. The user specifies a set of # # - we do not want to build the whole book. The user requests a set of #
# packages, and we have to consider only nodes reachable from this set # # packages, and we'd like to consider only nodes reachable from this set #
# using edges of weight not exceeding the specified weight. # # using edges of weight not exceeding the specified weight. #
# - we do not want to rebuild packages already built. But we still have to #
# generate the full dependency graph, because if A depends on B, which is #
# already built, and B depends on C, which is not built, or needs to be #
# updated, then A may depends on C. We therefore have to remove already #
# built (and up to date) packages from the graph, but need to keep the #
# dependency chain. #
# - when doing the topological sort, we want to consider all the edges and # # - when doing the topological sort, we want to consider all the edges and #
# not only those not exceeding the specified weight: If a package A in the # # not only those not exceeding the specified weight: If a package A in the #
# reachable subgraph depends optionally on another package B in the same # # reachable subgraph depends optionally on another package B in the same #
# subgraph, we want to build B before A. But this means we'll have to # # subgraph, we want to build B before A if possible. But this means we'll #
# remove cycles for all weights. # # have to remove cycles for all weights. #
# - dependencies have another qualifier: before or after. The problem: if a # # - dependencies have another qualifier: before, after, or first. We use #
# package A depends on B with an "after" qualifier, and a package C depends # # it as follows: for "after", we can build the dependency after the #
# on A with a "before" qualifier, C may need B to be able to use A. So the # # package, but if a package A depends on B with an "after" qualifier, and #
# only safe way to consider "after" qualifiers is to consider that they are # # a package C depends on A with a "before" qualifier, C may need B to be #
# "before" deps for any parent of the packages considered. There is an # # able to use A. So the only safe way to consider "after" qualifiers is to #
# exception to that rule: if B depends on C (possibly through a chain of # # consider that they are "before" deps for any parent of the packages #
# several dependencies), then C should still be built before B. # # considered. There is an exception to that rule: if B depends on C #
# (possibly through a chain of several dependencies), then C should still #
# be built before B. For "after", the dependency has to be built both #
# before and after the package. So we duplicate the dependency as a #
# "-pass1" package, and change the graph accordingly. #
# We'll therefore have a 3 pass procedure. First build the set of nodes # # We'll therefore have a 3 pass procedure. First build the set of nodes #
# reachable from the root set. Second, remove dangling edges (those pointing # # reachable from the root set. Second, remove dangling edges (those pointing #
# to packages outside the node set), and move "after" edges to "before" edges # # to packages outside the node set), and move "after" edges to "before" edges #
# originating from the parents. Third remove cycles and generate a # # originating from the parents as well as creating the "-pass1" nodes. Third #
# topological sort. # # remove cycles and generate a topological sort. #
# # # #
# Pass 1: graph generation # # Pass 1: graph generation #
# ======================== # # ======================== #
# Data layout for pass 1 # # Data layout for pass 1 #
# ---------------------- # # ---------------------- #
# A node of the tree is represented by a text file <nodeName>.dep. Each edge # # A node of the graph is represented by a text file <nodeName>.dep. Each edge #
# starting from this node is represented by a line in this file. We keep # # starting from this node is represented by a line in this file. We keep #
# those files in the same directory. We introduce a special node named root, # # those files in the same directory. We introduce a special node named root, #
# whose edges point to the list of nodes requested by the user. Each line # # whose edges point to the list of nodes requested by the user. Each line #
@ -80,8 +90,8 @@
# We now have three loops over nodes of the graph # # We now have three loops over nodes of the graph #
# Loop 1: Remove dead edges # # Loop 1: Remove dead edges #
# ------------------------- # # ------------------------- #
# Since some nodes have not been created because the edge leading to them # # Since some nodes have not been created because the edges leading to them #
# had too high a weight, the edges leading to them have to be suppressed. # # had too high a weight, those edges have to be suppressed. #
# For each existing node file, we make a list of lines to remove by # # For each existing node file, we make a list of lines to remove by #
# testing whether the destination exists. We then remove the lines. # # testing whether the destination exists. We then remove the lines. #
# Another approach would be to make a temporary file and output only # # Another approach would be to make a temporary file and output only #
@ -111,7 +121,23 @@
# Agroupxx as a dependency of root. The problem with this algorithm is # # Agroupxx as a dependency of root. The problem with this algorithm is #
# the search for paths from D to A, which may be exponential in the # # the search for paths from D to A, which may be exponential in the #
# number of nodes in the graph. # # number of nodes in the graph. #
# TODO: document other passes # # #
# Loop 3: Add -pass1 nodes #
# ------------------------ #
# Sometimes there is no way to escape a cycle. A package A needs B, and B #
# needs A. In that case, it is often possible to build a degraded version #
# of package A, then B, then rebuild A. The book indicates this with the #
# following dependency chain, using a qualifier of "first": #
# B---f--->A---b--->X...Y---b--->B #
# where the X...Y notation represents a chain of dependencies from A to B. #
# So the third loop is over nodes containing "f" qualifiers, and does the #
# following: it creates a new node A-pass1, which is a copy of A, and #
# remove from A-pass1 all the dependencies leading to B through a chain, #
# to obtain: #
# A---b--->X...Y---b--->B---b--->A-pass1 #
# It may then happen that nothing depends on A. So this is tested, and A #
# is added to the root node if it is orphaned. #
# TODO: document the third pass #
# TODO: needs also to document the .tree files # # TODO: needs also to document the .tree files #
# TODO: The following is obsolete # # TODO: The following is obsolete #
# Circular dependencies: # # Circular dependencies: #