@@ -18,40 +18,45 @@
18 18 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** directed acyclic graph (DAG) of check-ins.
19 19 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
20 20 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#include "config.h"
21 21 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#include "path.h"
22 22 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#include <assert.h>
23 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ #include <math.h>
23 24 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
24 25 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#if INTERFACE
25 26 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* Nodes for the paths through the DAG.
26 27 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
27 28 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
struct PathNode {
28 29 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int rid; /* ID for this node */
29 30 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
u8 fromIsParent; /* True if pFrom is the parent of rid */
30 31 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
u8 isPrim; /* True if primary side of common ancestor */
31 32 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
u8 isHidden; /* Abbreviate output in "fossil bisect ls" */
33 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ char *zBranch; /* Branch name for this node. Might be NULL */
34 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ double mtime; /* Date/time of this check-in */
32 35 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *pFrom; /* Node we came from */
33 36 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
union {
34 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- PathNode *pPeer; /* List of nodes of the same generation */
37 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ double rCost; /* Cost of getting to this node from pStart */
35 38 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *pTo; /* Next on path from beginning to end */
36 39 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
} u;
37 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- PathNode *pAll; /* List of all nodes */
40 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ PathNode *pAll; /* List of all nodes */
38 41 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
};
39 42 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
#endif
40 43 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
41 44 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*
42 45 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** Local variables for this module
43 46 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
44 47 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
static struct {
45 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- PathNode *pCurrent; /* Current generation of nodes */
48 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ PQueue pending; /* Nodes pending review for inclusion in the graph */
46 49 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *pAll; /* All nodes */
47 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Bag seen; /* Nodes seen before */
48 50 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int nStep; /* Number of steps from first to last */
49 51 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int nNotHidden; /* Number of steps not counting hidden nodes */
52 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int brCost; /* Extra cost for moving to a different branch */
53 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int revCost; /* Extra cost for changing directions */
50 54 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *pStart; /* Earliest node */
51 55 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *pEnd; /* Most recent */
52 56 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
} path;
57 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ static int path_debug = 0; /* Flag to enable debugging */
53 58 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
54 59 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*
55 60 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** Return the first (last) element of the computed path.
56 61 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
57 62 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *path_first(void){ return path.pStart; }
@@ -66,25 +71,71 @@
66 71 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** Return the number of non-hidden steps in the computed path.
67 72 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
68 73 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int path_length_not_hidden(void){ return path.nNotHidden; }
69 74 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
70 75 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*
71 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- ** Create a new node
76 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Used for debugging only.
77 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
78 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Given a RID, return the ISO date/time string and branch for the
79 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** corresponding check-in. Memory is held locally and is overwritten
80 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** with each call.
81 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
82 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ char *path_rid_desc(int rid){
83 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ static Stmt q;
84 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ static char *zDesc = 0;
85 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_static_prepare(&q,
86 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "SELECT concat(strftime('%%Y%%m%%d%%H%%M',event.mtime),'/',value)"
87 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ " FROM event, tagxref"
88 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ " WHERE event.objid=:rid"
89 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ " AND tagxref.rid=:rid"
90 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ " AND tagxref.tagid=%d"
91 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ " AND tagxref.tagtype>0",
92 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ TAG_BRANCH
93 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ );
94 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_free(zDesc);
95 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_bind_int(&q, ":rid", rid);
96 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( db_step(&q)==SQLITE_ROW ){
97 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zDesc = fossil_strdup(db_column_text(&q,0));
98 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
99 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_reset(&q);
100 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return zDesc ? zDesc : "???";
101 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
102 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
103 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /*
104 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Create a new node and insert it into the path.pending queue.
72 105 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
73 106 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
static PathNode *path_new_node(int rid, PathNode *pFrom, int isParent){
74 107 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *p;
75 108 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
76 109 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
p = fossil_malloc( sizeof(*p) );
77 110 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
memset(p, 0, sizeof(*p));
111 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p->pAll = path.pAll;
112 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ path.pAll = p;
78 113 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
p->rid = rid;
79 114 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
p->fromIsParent = isParent;
80 115 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
p->pFrom = pFrom;
81 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p->u.pPeer = path.pCurrent;
82 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- path.pCurrent = p;
83 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p->pAll = path.pAll;
84 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- path.pAll = p;
85 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- bag_insert(&path.seen, rid);
116 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p->u.rCost = pFrom ? pFrom->u.rCost : 0.0;
117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( path.brCost ){
118 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p->zBranch = branch_of_rid(rid);
119 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p->mtime = mtime_of_rid(rid, 0.0);
120 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( pFrom ){
121 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p->u.rCost += fabs(pFrom->mtime - p->mtime);
122 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( fossil_strcmp(p->zBranch, pFrom->zBranch)!=0 ){
123 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p->u.rCost += path.brCost;
124 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
125 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
126 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else{
127 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* When brCost==0, we try to minimize the number of nodes
128 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** along the path. The cost is just the number of nodes back
129 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** to the start. We do not need to know the branch name nor
130 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** the mtime */
131 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p->u.rCost += 1.0;
132 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
133 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( path_debug ){
134 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_print("PUSH %-50s cost = %g\n", path_rid_desc(p->rid), p->u.rCost);
135 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
136 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pqueuex_insert_ptr(&path.pending, (void*)p, p->u.rCost);
86 137 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return p;
87 138 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
88 139 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
89 140 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*
90 141 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** Reset memory used by the shortest path algorithm.
@@ -92,13 +143,14 @@
92 143 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
void path_reset(void){
93 144 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *p;
94 145 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
while( path.pAll ){
95 146 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
p = path.pAll;
96 147 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
path.pAll = p->pAll;
148 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_free(p->zBranch);
97 149 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
fossil_free(p);
98 150 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
99 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- bag_clear(&path.seen);
151 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pqueuex_clear(&path.pending);
100 152 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
memset(&path, 0, sizeof(path));
101 153 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
102 154 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
103 155 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*
104 156 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** Construct the path from path.pStart to path.pEnd in the u.pTo fields.
@@ -128,17 +180,19 @@
128 180 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *path_shortest(
129 181 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int iFrom, /* Path starts here */
130 182 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int iTo, /* Path ends here */
131 183 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int directOnly, /* No merge links if true */
132 184 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int oneWayOnly, /* Parent->child only if true */
133 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- Bag *pHidden /* Hidden nodes */
185 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Bag *pHidden, /* Hidden nodes */
186 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int branchCost /* Add extra cost to changing branches */
134 187 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
){
135 188 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Stmt s;
136 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- PathNode *pPrev;
189 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ Bag seen;
137 190 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *p;
138 191 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
139 192 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
path_reset();
193 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ path.brCost = branchCost;
140 194 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
path.pStart = path_new_node(iFrom, 0, 0);
141 195 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( iTo==iFrom ){
142 196 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
path.pEnd = path.pStart;
143 197 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return path.pStart;
144 198 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
@@ -152,44 +206,46 @@
152 206 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
);
153 207 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}else if( directOnly ){
154 208 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_prepare(&s,
155 209 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
"SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim "
156 210 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
"UNION ALL "
157 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- "SELECT pid, 0 FROM plink WHERE cid=:pid AND isprim"
211 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "SELECT pid, 0 FROM plink WHERE :back AND cid=:pid AND isprim"
158 212 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
);
159 213 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}else{
160 214 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_prepare(&s,
161 215 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
"SELECT cid, 1 FROM plink WHERE pid=:pid "
162 216 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
"UNION ALL "
163 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- "SELECT pid, 0 FROM plink WHERE cid=:pid"
217 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ "SELECT pid, 0 FROM plink WHERE :back AND cid=:pid"
164 218 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
);
165 219 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
166 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- while( path.pCurrent ){
167 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- path.nStep++;
168 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- pPrev = path.pCurrent;
169 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- path.pCurrent = 0;
170 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- while( pPrev ){
171 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- db_bind_int(&s, ":pid", pPrev->rid);
172 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- while( db_step(&s)==SQLITE_ROW ){
173 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- int cid = db_column_int(&s, 0);
174 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- int isParent = db_column_int(&s, 1);
175 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if( bag_find(&path.seen, cid) ) continue;
176 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p = path_new_node(cid, pPrev, isParent);
177 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if( pHidden && bag_find(pHidden,cid) ) p->isHidden = 1;
178 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if( cid==iTo ){
179 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- db_finalize(&s);
180 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- path.pEnd = p;
181 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- path_reverse_path();
182 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- for(p=path.pStart->u.pTo; p; p=p->u.pTo ){
183 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if( !p->isHidden ) path.nNotHidden++;
184 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
185 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- return path.pStart;
186 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
187 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
188 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- db_reset(&s);
189 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- pPrev = pPrev->u.pPeer;
190 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
220 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ bag_init(&seen);
221 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ while( (p = pqueuex_extract_ptr(&path.pending))!=0 ){
222 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( path_debug ){
223 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ printf("PULL %s %g\n", path_rid_desc(p->rid), p->u.rCost);
224 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
225 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( p->rid==iTo ){
226 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_finalize(&s);
227 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ path.pEnd = p;
228 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ path_reverse_path();
229 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for(p=path.pStart->u.pTo; p; p=p->u.pTo ){
230 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( !p->isHidden ) path.nNotHidden++;
231 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
232 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return path.pStart;
233 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
234 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( bag_find(&seen, p->rid) ) continue;
235 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ bag_insert(&seen, p->rid);
236 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_bind_int(&s, ":pid", p->rid);
237 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( !oneWayOnly ) db_bind_int(&s, ":back", !p->fromIsParent);
238 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ while( db_step(&s)==SQLITE_ROW ){
239 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int cid = db_column_int(&s, 0);
240 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int isParent = db_column_int(&s, 1);
241 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ PathNode *pNew;
242 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( bag_find(&seen, cid) ) continue;
243 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pNew = path_new_node(cid, p, isParent);
244 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( pHidden && bag_find(pHidden,cid) ) pNew->isHidden = 1;
245 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
246 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_reset(&s);
191 247 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
192 248 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_finalize(&s);
193 249 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
path_reset();
194 250 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return 0;
195 251 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
@@ -215,10 +271,22 @@
215 271 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *p;
216 272 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
p = path.pStart;
217 273 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( p ) p = p->u.pTo;
218 274 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return p;
219 275 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
276 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
277 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /*
278 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Return the branch for a path node.
279 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
280 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Storage space is managed by the path subsystem. The returned value
281 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** is valid until the path is reset.
282 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
283 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const char *path_branch(PathNode *p){
284 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( p==0 ) return 0;
285 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( p->zBranch==0 ) p->zBranch = branch_of_rid(p->rid);
286 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return p->zBranch;
287 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
220 288 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
221 289 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*
222 290 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** Return an estimate of the number of comparisons remaining in order
223 291 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** to bisect path. This is based on the log2() of path.nStep.
224 292 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
@@ -238,11 +306,11 @@
238 306 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int cid /* RID for check-in at the end of the path */
239 307 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
){
240 308 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *pPath;
241 309 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int gen = 0;
242 310 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Stmt ins;
243 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- pPath = path_shortest(cid, origid, 1, 0, 0);
311 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pPath = path_shortest(cid, origid, 1, 0, 0, 0);
244 312 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_multi_exec(
245 313 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
"CREATE TEMP TABLE IF NOT EXISTS ancestor("
246 314 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
" rid INT UNIQUE,"
247 315 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
" generation INTEGER PRIMARY KEY"
248 316 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
");"
@@ -261,58 +329,55 @@
261 329 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
262 330 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
263 331 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*
264 332 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** COMMAND: test-shortest-path
265 333 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
**
266 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- ** Usage: %fossil test-shortest-path ?--no-merge? VERSION1 VERSION2
334 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Usage: %fossil test-shortest-path [OPTIONS] VERSION1 VERSION2
335 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
336 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Report the shortest path between two check-ins. Options:
267 337 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
**
268 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- ** Report the shortest path between two check-ins. If the --no-merge flag
269 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- ** is used, follow only direct parent-child paths and omit merge links.
338 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** --branch-cost N Additional cost N for changing branches
339 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** --debug Show debugging output
340 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** --one-way One-way forwards in time, parent->child only
341 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** --no-merge Follow only direct parent-child paths and omit
342 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** merge links.
270 343 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
271 344 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
void shortest_path_test_cmd(void){
272 345 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int iFrom;
273 346 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int iTo;
274 347 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *p;
275 348 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int n;
276 349 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int directOnly;
277 350 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int oneWay;
351 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ const char *zBrCost;
278 352 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
279 353 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_find_and_open_repository(0,0);
280 354 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
directOnly = find_option("no-merge",0,0)!=0;
281 355 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
oneWay = find_option("one-way",0,0)!=0;
356 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zBrCost = find_option("branch-cost",0,1);
357 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( find_option("debug",0,0)!=0 ) path_debug = 1;
282 358 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( g.argc!=4 ) usage("VERSION1 VERSION2");
283 359 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
iFrom = name_to_rid(g.argv[2]);
284 360 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
iTo = name_to_rid(g.argv[3]);
285 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p = path_shortest(iFrom, iTo, directOnly, oneWay, 0);
361 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p = path_shortest(iFrom, iTo, directOnly, oneWay, 0,
362 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ zBrCost ? atoi(zBrCost) : 0);
286 363 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( p==0 ){
287 364 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
fossil_fatal("no path from %s to %s", g.argv[1], g.argv[2]);
288 365 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
289 366 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
for(n=1, p=path.pStart; p; p=p->u.pTo, n++){
290 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- char *z;
291 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- z = db_text(0,
292 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)"
293 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- " FROM blob, event"
294 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'",
295 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p->rid, p->rid);
296 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- fossil_print("%4d: %5d %s", n, p->rid, z);
297 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- fossil_free(z);
298 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if( p->u.pTo ){
299 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- fossil_print(" is a %s of\n",
300 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p->u.pTo->fromIsParent ? "parent" : "child");
301 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }else{
302 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- fossil_print("\n");
303 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
304 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
367 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ fossil_print("%4d: %s\n", n, path_rid_desc(p->rid));
368 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
369 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ path_debug = 0;
305 370 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
306 371 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
307 372 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/*
308 373 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** Find the closest common ancestor of two nodes. "Closest" means the
309 374 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** fewest number of arcs.
310 375 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
*/
311 376 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int path_common_ancestor(int iMe, int iYou){
312 377 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Stmt s;
313 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- PathNode *pPrev;
378 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ PathNode *pThis;
314 379 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
PathNode *p;
315 380 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Bag me, you;
316 381 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
317 382 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( iMe==iYou ) return iMe;
318 383 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( iMe==0 || iYou==0 ) return 0;
@@ -323,45 +388,40 @@
323 388 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_prepare(&s, "SELECT pid FROM plink WHERE cid=:cid");
324 389 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
bag_init(&me);
325 390 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
bag_insert(&me, iMe);
326 391 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
bag_init(&you);
327 392 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
bag_insert(&you, iYou);
328 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- while( path.pCurrent ){
329 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- pPrev = path.pCurrent;
330 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- path.pCurrent = 0;
331 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- while( pPrev ){
332 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- db_bind_int(&s, ":cid", pPrev->rid);
333 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- while( db_step(&s)==SQLITE_ROW ){
334 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- int pid = db_column_int(&s, 0);
335 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if( bag_find(pPrev->isPrim ? &you : &me, pid) ){
336 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- /* pid is the common ancestor */
337 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- PathNode *pNext;
338 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- for(p=path.pAll; p && p->rid!=pid; p=p->pAll){}
339 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- assert( p!=0 );
340 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- pNext = p;
341 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- while( pNext ){
342 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- pNext = p->pFrom;
343 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p->pFrom = pPrev;
344 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- pPrev = p;
345 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p = pNext;
346 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
347 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if( pPrev==path.pStart ) path.pStart = path.pEnd;
348 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- path.pEnd = pPrev;
349 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- path_reverse_path();
350 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- db_finalize(&s);
351 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- return pid;
352 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }else if( bag_find(&path.seen, pid) ){
353 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- /* pid is just an alternative path on one of the legs */
354 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- continue;
355 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
356 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p = path_new_node(pid, pPrev, 0);
357 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p->isPrim = pPrev->isPrim;
358 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- bag_insert(pPrev->isPrim ? &me : &you, pid);
359 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
360 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- db_reset(&s);
361 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- pPrev = pPrev->u.pPeer;
362 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }
393 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ while( (pThis = pqueuex_extract_ptr(&path.pending))!=0 ){
394 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_bind_int(&s, ":cid", pThis->rid);
395 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ while( db_step(&s)==SQLITE_ROW ){
396 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int pid = db_column_int(&s, 0);
397 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( bag_find(pThis->isPrim ? &you : &me, pid) ){
398 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* pid is the common ancestor */
399 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ PathNode *pNext;
400 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for(p=path.pAll; p && p->rid!=pid; p=p->pAll){}
401 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ assert( p!=0 );
402 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pNext = p;
403 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ while( pNext ){
404 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pNext = p->pFrom;
405 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p->pFrom = pThis;
406 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ pThis = p;
407 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p = pNext;
408 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
409 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( pThis==path.pStart ) path.pStart = path.pEnd;
410 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ path.pEnd = pThis;
411 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ path_reverse_path();
412 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_finalize(&s);
413 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return pid;
414 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else if( bag_find(pThis->isPrim ? &me : &you, pid) ){
415 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* pid is just an alternative path to a node we've already visited */
416 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ continue;
417 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
418 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p = path_new_node(pid, pThis, 0);
419 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p->isPrim = pThis->isPrim;
420 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ bag_insert(pThis->isPrim ? &me : &you, pid);
421 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
422 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ db_reset(&s);
363 423 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
364 424 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_finalize(&s);
365 425 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
path_reset();
366 426 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return 0;
367 427 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
@@ -453,11 +513,11 @@
453 513 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}else if(0==iTo){
454 514 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
fossil_fatal("Invalid 'to' RID: 0");
455 515 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
456 516 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( iFrom==iTo ) return;
457 517 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
path_reset();
458 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- p = path_shortest(iFrom, iTo, 1, revOK==0, 0);
518 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ p = path_shortest(iFrom, iTo, 1, revOK==0, 0, 0);
459 519 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( p==0 ) return;
460 520 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
path_reverse_path();
461 521 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
db_prepare(&q1,
462 522 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
"SELECT pfnid, fnid FROM mlink"
463 523 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
" WHERE mid=:mid AND (pfnid>0 OR fid==0)"
464 524 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!