chiark / gitweb /
48d93d77954256085eb3d44c0dcf0eb52272d065
[topbloke-formulae.git] / strategy.tex
1 Here we describe the update algorithm.  This is responsible for
2 refreshing patches against updated versions of their dependencies,
3 for merging different versions of the various braches created by
4 distributed development, and for implementing decisions to add and
5 remove dependencies from patches.
6
7 Broadly speaking the update proceeds as follows: during the Ranking
8 phase we construct the intended graph of dependencies between patches
9 (and incidentally select a merge order for the base branch of each
10 patch).  Then during the Traversal phase we walk that graph from the
11 bottom up, constructing for each patch by a series of merges and other
12 operations first a new base branch head commit and then a new tip
13 branch head commit.  These new head commits are maximums - that is,
14 each has as ancestors all of its branches' sources and indeed all
15 relevant commits in that branch.
16
17 We have two possible strategies for constructing new base branch
18 heads: we can either Merge (works incrementally even if there the
19 patch has multiple dependencies, but may sometimes not be possible) or
20 we can Regenerate (trivial if there is a single dependency, and is
21 always possible, but may involve the user re-resolving conflicts if
22 there are multiple dependencies).
23
24 \section{Notation}
25
26 \begin{basedescript}{
27 \desclabelwidth{5em}
28 \desclabelstyle{\nextlinelabel}
29 }
30 \item[ $\depsreqof{K}$ ]
31 The set of direct dependencies (in the form $\py$)
32 requested in the commit $K$ ($K \in \pn$) for the patch $\p$.
33
34 \item[ $\pc \hasdirdep \p$ ]
35 The patch $\pc$ has as a direct dependency the
36 patch $\p$.  This is an acyclic relation.
37
38 \item[ $\p \hasdep \pq$ ]
39 The patch $\p$ has as direct or indirect dependency the
40 patch $\pq$.
41 Acyclic; the completion of $\hasdirdep$ into a
42 partial order.
43
44 \item[ $\pendsof{\set J}{\p}$ ]
45 Convenience notation for
46 the $\le$-maximal elements of $\bigcup_{J \in \set J} \pendsof{J}{\p}$
47 (where $\set J$ is some set of commits).
48
49 \item[ $\pendsof{\set X}{\p} \le T$ ]
50 Convenience notation for
51 $\bigforall_{E \in \pendsof{\set X}{\p}} E \le T$
52
53 %\item[ $\set E_{\pc}$ ]
54 %$ \bigcup_i \pendsof{S_{\pc,i}}{\pc} $.
55 %All the ends of $\pc$ in the sources.
56
57 %\item[ $ \tipzc, \tipcc, \tipuc, \tipfc $ ]
58 %The git ref for the Topbloke commit set $\pc$: respectively,
59 %the original, current, updated, and final values.
60
61 \end{basedescript}
62
63 \stdsection{Inputs to the update algorithm}
64
65 \begin{basedescript}{
66 \desclabelwidth{5em}
67 \desclabelstyle{\nextlinelabel}
68 }
69 \item[ $\pc_0$ ]
70 The topmost patch which we are trying to update.  This and
71 all of its dependencies will be updated.
72
73 \item[ $h : \pc^{+/-} \mapsto \set H_{\pc^{+/-}}$ ]
74 Function for getting the existing heads $\set H$ of the branch $\pc^{+/-}$.
75 These are the heads which will be merged and used in this update.
76 This will include the current local and remote git refs, as desired.
77
78 \item[ $g : \pc, \Gamma \mapsto \Gamma'$ ]
79 Function to allow explicit adjustment of the direct dependencies
80 of $\pc$.  It is provided with a putative set of direct dependencies
81 $\Gamma$ computed as an appropriate merge of the dependencies requested by the
82 sources and should return the complete actual set $\Gamma'$ of direct
83 dependencies to use.  This allows the specification of any desired
84 (acyclic) relations $\hasdirdep$ and $\hasdep$.
85
86 \end{basedescript}
87
88 \stdsection{Important variables and values in the update algorithm}
89
90 \begin{basedescript}{
91 \desclabelwidth{5em}
92 \desclabelstyle{\nextlinelabel}
93 }
94 \item[ $\Gamma_{\pc}$ ]
95 The desired direct dependencies of $\pc$, a set of patches.
96
97 \item[ $\allpatches$ ]
98 The set of all the patches we are dealing with (constructed
99 during the update algorithm).
100
101 \end{basedescript}
102
103 \section{Ranking phase}
104
105 We run the following algorithm:
106 \begin{enumerate}
107 \item Set $\allpatches = \{ \}$.
108 \item Repeatedly:
109 \begin{enumerate}
110 \item Clear out the graph $\hasdirdep$ so it has no edges.
111 \item Execute $\alg{Rank-Recurse}(\pc_0)$
112 \item Until $\allpatches$ remains unchanged.
113 \end{enumerate}
114 \end{enumerate}
115
116 $\alg{Rank-Recurse}(\pc)$ is:
117 \begin{enumerate}
118
119 \item If we have already done $\alg{Rank-Recurse}(\pc)$ in this
120 ranking iteration, do nothing.  Otherwise:
121
122 \item Add $\pc$ to $\allpatches$ if it is not there already.
123
124 \item Set
125 $$
126   \set S \iassign h(\pcn)
127      \cup 
128         \bigcup_{\p \in \allpatches}
129         \bigcup_{H \in h(\pn) \lor H \in h(\py)}
130          \{ \baseof{E} \; | \; E \in \pendsof{H}{\pcy} \}
131 $$
132
133 and $W \iassign w(h(\pcn))$
134
135 \item While $\exists_{S \in \set S} S \ge W$,
136 update $W \assign S$ and $\set S \assign \set S \, \backslash \{ S \}$
137
138 (This will often remove $W$ from $\set S$.  Afterwards, $\set S$
139 is a collection of heads to be merged into $W$.)
140
141 \item Choose an ordering of $\set S$, $S_i$ for $i=1 \ldots n$.
142
143 \item For each $S_i$ in turn, choose a corresponding $M_i$
144 such that $$
145    M_i \le S_i \land \left[
146    M_i \le W \lor \bigexists_{j<i} M_i \le S_j
147    \right]
148 $$
149
150 \item Set $\Gamma \iassign \depsreqof{W}$.
151
152 If there are multiple candidates we prefer $M_i \in \pcn$
153 if available.
154
155 \item For each $i \ldots 1..n$, update our putative direct
156 dependencies:
157 $$
158 \Gamma \assign \alg{set-merge}\left[\Gamma,
159  \left( \begin{cases} 
160   M_i \in \pcn :     & \depsreqof{M_i} \\
161   M_i \not\in \pcn : & \{ \}
162  \end{cases} \right),
163  \depsreqof{S_i}
164  \right]
165 $$
166
167 TODO define $\alg{set-merge}$
168
169 \item Finalise our putative direct dependencies
170 $
171 \Gamma \assign g(\pc, \Gamma)
172 $
173
174 \item For each direct dependency $\pd \in \Gamma$,
175
176 \begin{enumerate}
177 \item Add an edge $\pc \hasdirdep \pd$ to the digraph (adding nodes
178 as necessary).
179 If this results in a cycle, abort entirely (as the function $g$ is
180 inappropriate; a different $g$ could work).
181 \end{enumerate}
182 \item Run $\alg{Rank-Recurse}(\pd)$.
183
184 \end{enumerate}
185
186 \subsection{Results of the ranking phase}
187
188 By the end of the ranking phase, we have recorded the following
189 information:
190
191 \begin{itemize}
192 \item
193 $ \allpatches, \hasdirdep $ and hence the completion of $\hasdirdep$
194 into the partial order $\hasdep$.
195
196 \item
197 For each $\pc \in \allpatches$,
198 the base branch starting point commit $W^{\pcn} = W$.
199
200 \item
201 For each $\pc$,
202 the direct dependencies $\Gamma^{\pc} = \Gamma$.
203
204 \item
205 For each $\pc$,
206 the ordered set of base branch sources $\set S^{\pcn} = \set S,
207 S^{\pcn}_i = S_i$
208 and corresponding merge bases $M^{\pcn}_i = M_i$.
209
210 \end{itemize}
211
212 \section{Traversal phase}
213
214 For each patch $C \in \allpatches$ in topological order by $\hasdep$,
215 lowest first:
216
217 \begin{enumerate}
218
219 \item Optionally, attempt $\alg{Merge-Base}(\pc)$.
220
221 \end{enumerate}
222
223
224 \section{Planning phase}
225
226 The results of the planning phase consist of: 
227 \begin{itemize*}
228 \item{ The relation $\hasdirdep$ and hence the partial order $\hasdep$. }
229 \item{ For each commit set $\pc$, a confirmed set of sources $\set S_{\pc}$. }
230 \item{ For each commit set $\pc$, the order in which to merge the sources
231         $E_{\pc,j} \in \set E_{\pc}$. }
232 \item{ For each $E_{\pc,j}$ an intended merge base $M_{\pc,j}$. }
233 \end{itemize*}
234
235 We use a recursive planning algorith, recursing over Topbloke commit
236 sets (ie, sets $\py$ or $\pn$).  We'll call the commit set we're
237 processing at each step $\pc$.
238 At each recursive step 
239 we make a plan to merge all $\set E_{\pc} = \{ E_{\pc,j \ldots} \}$
240 and all the direct contributors of $\pc$ (as determined below)
241 into $\tipzc$, to make $\tipfc$.
242
243 We start with $\pc = \pl$ where $\pl = \patchof{L}$.
244
245
246 \subsection{Direct contributors for $\pc = \pcn$}
247
248 The direct contributors of $\pcn$ are the commit sets corresponding to
249 the tip branches for the direct dependencies of the patch $\pc$.  We
250 need to calculate what the direct dependencies are going to be.
251
252 Choose an (arbitrary, but ideally somehow optimal in
253 a way not discussed here) ordering of $\set E_{\pc}$, $E_{\pc,j}$
254 ($j = 1 \ldots m$).
255 For brevity we will write $E_j$ for $E_{\pc,j}$.
256 Remove from that set (and ordering) any $E_j$ which
257 are $\le$ and $\neq$ some other $E_k$.
258
259 Initially let $\set D_0 = \depsreqof{\tipzc}$.
260 For each $E_j$ starting with $j=1$ choose a corresponding intended
261 merge base $M_j$ such that $M_j \le E_j \land M_j \le T_{\pc,j-1}$.
262 Calculate $\set D_j$ as the 3-way merge of the sets $\set D_{j-1}$ and
263 $\depsreqof{E_j}$ using as a base $\depsreqof{M_j}$.  This will
264 generate $D_m$ as the putative direct contributors of $\pcn$.
265
266 However, the invocation may give instructions that certain direct
267 dependencies are definitely to be included, or excluded.  As a result
268 the set of actual direct contributors is some arbitrary set of patches
269 (strictly, some arbitrary set of Topbloke tip commit sets).
270
271 \subsection{Direct contributors for $\pc = \pcy$}
272
273 The sole direct contributor of $\pcy$ is $\pcn$.
274
275 \subsection{Recursive step}
276
277 For each direct contributor $\p$, we add the edge $\pc \hasdirdep \p$
278 and augment the ordering $\hasdep$ accordingly.
279
280 If this would make a cycle in $\hasdep$, we abort . The operation must
281 then be retried by the user, if desired, but with different or
282 additional instructions for modifying the direct contributors of some
283 $\pqn$ involved in the cycle.
284
285 For each such $\p$, after updating $\hasdep$, we recursively make a plan
286 for $\pc' = \p$.
287
288
289
290 \section{Execution phase}
291
292 We process commit sets from the bottom up according to the relation
293 $\hasdep$.  For each commit set $\pc$ we construct $\tipfc$ from
294 $\tipzc$, as planned.  By construction, $\hasdep$ has $\patchof{L}$
295 as its maximum, so this operation will finish by updating
296 $\tipca{\patchof{L}}$ with $\tipfa{\patchof{L}}$.
297
298 After we are done with each commit set $\pc$, the
299 new tip $\tipfc$ has the following properties:
300 \[ \eqn{Tip Sources}{
301   \bigforall_{E_i \in \set E_{\pc}} \tipfc \ge E_i
302 }\]
303 \[ \eqn{Tip Dependencies}{
304   \bigforall_{\pc \hasdep \p} \tipfc \ge \tipfa \p
305 }\]
306 \[ \eqn{Perfect Contents}{
307   \tipfc \haspatch \p \equiv \pc \hasdep \py
308 }\]
309
310 For brevity we will sometimes write $\tipu$ for $\tipuc$, etc.  We will start
311 out with $\tipc = \tipz$, and at each step of the way construct some
312 $\tipu$ from $\tipc$.  The final $\tipu$ becomes $\tipf$.
313
314 \subsection{Preparation}
315
316 Firstly, we will check each $E_i$ for being $\ge \tipc$.  If
317 it is, are we fast forward to $E_i$
318 --- formally, $\tipu = \text{max}(\tipc, E_i)$ ---
319 and drop $E_i$ from the planned ordering.
320
321 Then we will merge the direct contributors and the sources' ends.
322 This generates more commits $\tipuc \in \pc$, but none in any other
323 commit set.  We maintain
324 $$
325  \bigforall_{\p \isdep \pc}
326  \pancsof{\tipcc}{\p} \subset
327    \pancsof{\tipfa \p}{\p}
328 $$
329 \proof{
330  For $\tipcc = \tipzc$, $T$ ...WRONG WE NEED $\tipfa \p$ TO BE IN $\set E$ SOMEHOW
331 }
332
333 \subsection{Merge Contributors for $\pcy$}
334
335 Merge $\pcn$ into $\tipc$.  That is, merge with
336 $L = \tipc, R = \tipfa{\pcn}, M = \baseof{\tipc}$.
337 to construct $\tipu$.
338
339 Merge conditions:
340
341 Ingredients satisfied by construction.
342 Tip Merge satisfied by construction.  Merge Acyclic follows
343 from Perfect Contents and $\hasdep$ being acyclic.
344
345 Removal Merge Ends: For $\p = \pc$, $M \nothaspatch \p$; OK.
346 For $\p \neq \pc$, by Tip Contents,
347 $M \haspatch \p \equiv L \haspatch \p$, so we need only
348 worry about $X = R, Y = L$; ie $L \haspatch \p$,
349 $M = \baseof{L} \haspatch \p$.
350 By Tip Contents for $L$, $D \le L \equiv D \le M$.  OK.~~$\qed$
351
352 WIP UP TO HERE
353
354 Addition Merge Ends: If $\py \isdep \pcn$, we have already
355 done the execution phase for $\pcn$ and $\py$.  By
356 Perfect Contents for $\pcn$, $\tipfa \pcn \haspatch \p$ i.e.
357 $R \haspatch \p$.  So we only need to worry about $Y = R = \tipfa \pcn$.
358 By Tip Dependencies $\tipfa \pcn \ge \tipfa \py$.
359 And by Tip Sources $\tipfa \py \ge $
360
361 want to prove $E \le \tipfc$ where $E \in \pendsof{\tipcc}{\py}$
362
363 $\pancsof{\tipcc}{\py} = $
364
365
366 computed $\tipfa \py$, and by Perfect Contents for $\py$
367
368
369 with $M=M_j, L=T_{\pc,j-1}, R=E_j$,
370 and calculate what the resulting desired direct dependencies file
371 (ie, the set of patches $\set D_j$)
372 would be.  Eventually we 
373
374 So, formally, we select somehow an order of sources $S_i$.  For each 
375
376
377 Make use of the following recursive algorithm, Plan 
378
379
380
381
382  recursively make a plan to merge all $E = \pends$
383
384 Specifically, in