Fossil SCM

Fix the logic that combines merge risers (originally added to trunk by check-in [95d6ddc3]). Add test cases for this fix to graph-test-1.wiki.

drh 2016-12-14 01:09 trunk
Commit 9ed134360bf9b46c46691494b0dec2aecb15ef66
+14 -8
--- src/graph.c
+++ src/graph.c
@@ -340,19 +340,28 @@
340340
}
341341
342342
343343
/*
344344
** Compute the complete graph
345
+**
346
+** When primary or merge parents are off-screen, normally a line is drawn
347
+** from the node down to the bottom of the graph. This line is called a
348
+** "descender". But if the omitDescenders flag is true, then lines down
349
+** to the bottom of the screen are omitted.
345350
*/
346351
void graph_finish(GraphContext *p, int omitDescenders){
347352
GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
348353
int i, j;
349354
u64 mask;
350355
int hasDup = 0; /* True if one or more isDup entries */
351356
const char *zTrunk;
352
- int railRid[GR_MAX_RAIL]; /* Maps rails to rids for lines
353
- that enter from bottom of screen */
357
+
358
+ /* If mergeRiserFrom[X]==Y that means rail X holds a merge riser
359
+ ** coming up from the bottom of the graph from off-screen check-in Y
360
+ ** where Y is the RID. There is no riser on rail X if mergeRiserFrom[X]==0.
361
+ */
362
+ int mergeRiserFrom[GR_MAX_RAIL];
354363
355364
if( p==0 || p->pFirst==0 || p->nErr ) return;
356365
p->nErr = 1; /* Assume an error until proven otherwise */
357366
358367
/* Initialize all rows */
@@ -367,11 +376,11 @@
367376
pDup->isDup = 1;
368377
}
369378
hashInsert(p, pRow, 1);
370379
}
371380
p->mxRail = -1;
372
- memset(railRid, 0, sizeof(railRid));
381
+ memset(mergeRiserFrom, 0, sizeof(mergeRiserFrom));
373382
374383
/* Purge merge-parents that are out-of-graph if descenders are not
375384
** drawn.
376385
**
377386
** Each node has one primary parent and zero or more "merge" parents.
@@ -460,13 +469,10 @@
460469
}
461470
if( p->mxRail>=GR_MAX_RAIL ) return;
462471
mask = BIT(pRow->iRail);
463472
if( !omitDescenders ){
464473
pRow->bDescender = pRow->nParent>0;
465
- if( pRow->bDescender ){
466
- railRid[pRow->iRail] = pRow->aParent[0];
467
- }
468474
for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
469475
pLoop->railInUse |= mask;
470476
}
471477
}
472478
assignChildrenToRail(pRow);
@@ -543,19 +549,19 @@
543549
pDesc = hashFind(p, parentRid);
544550
if( pDesc==0 ){
545551
/* Merge from a node that is off-screen */
546552
int iMrail = -1;
547553
for(j=0; j<GR_MAX_RAIL; j++){
548
- if( railRid[j]==parentRid ){
554
+ if( mergeRiserFrom[j]==parentRid ){
549555
iMrail = j;
550556
break;
551557
}
552558
}
553559
if( iMrail==-1 ){
554560
iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
555561
if( p->mxRail>=GR_MAX_RAIL ) return;
556
- railRid[iMrail] = parentRid;
562
+ mergeRiserFrom[iMrail] = parentRid;
557563
}
558564
mask = BIT(iMrail);
559565
pRow->mergeIn[iMrail] = 1;
560566
pRow->mergeDown |= mask;
561567
for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){
562568
--- src/graph.c
+++ src/graph.c
@@ -340,19 +340,28 @@
340 }
341
342
343 /*
344 ** Compute the complete graph
 
 
 
 
 
345 */
346 void graph_finish(GraphContext *p, int omitDescenders){
347 GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
348 int i, j;
349 u64 mask;
350 int hasDup = 0; /* True if one or more isDup entries */
351 const char *zTrunk;
352 int railRid[GR_MAX_RAIL]; /* Maps rails to rids for lines
353 that enter from bottom of screen */
 
 
 
 
354
355 if( p==0 || p->pFirst==0 || p->nErr ) return;
356 p->nErr = 1; /* Assume an error until proven otherwise */
357
358 /* Initialize all rows */
@@ -367,11 +376,11 @@
367 pDup->isDup = 1;
368 }
369 hashInsert(p, pRow, 1);
370 }
371 p->mxRail = -1;
372 memset(railRid, 0, sizeof(railRid));
373
374 /* Purge merge-parents that are out-of-graph if descenders are not
375 ** drawn.
376 **
377 ** Each node has one primary parent and zero or more "merge" parents.
@@ -460,13 +469,10 @@
460 }
461 if( p->mxRail>=GR_MAX_RAIL ) return;
462 mask = BIT(pRow->iRail);
463 if( !omitDescenders ){
464 pRow->bDescender = pRow->nParent>0;
465 if( pRow->bDescender ){
466 railRid[pRow->iRail] = pRow->aParent[0];
467 }
468 for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
469 pLoop->railInUse |= mask;
470 }
471 }
472 assignChildrenToRail(pRow);
@@ -543,19 +549,19 @@
543 pDesc = hashFind(p, parentRid);
544 if( pDesc==0 ){
545 /* Merge from a node that is off-screen */
546 int iMrail = -1;
547 for(j=0; j<GR_MAX_RAIL; j++){
548 if( railRid[j]==parentRid ){
549 iMrail = j;
550 break;
551 }
552 }
553 if( iMrail==-1 ){
554 iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
555 if( p->mxRail>=GR_MAX_RAIL ) return;
556 railRid[iMrail] = parentRid;
557 }
558 mask = BIT(iMrail);
559 pRow->mergeIn[iMrail] = 1;
560 pRow->mergeDown |= mask;
561 for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){
562
--- src/graph.c
+++ src/graph.c
@@ -340,19 +340,28 @@
340 }
341
342
343 /*
344 ** Compute the complete graph
345 **
346 ** When primary or merge parents are off-screen, normally a line is drawn
347 ** from the node down to the bottom of the graph. This line is called a
348 ** "descender". But if the omitDescenders flag is true, then lines down
349 ** to the bottom of the screen are omitted.
350 */
351 void graph_finish(GraphContext *p, int omitDescenders){
352 GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
353 int i, j;
354 u64 mask;
355 int hasDup = 0; /* True if one or more isDup entries */
356 const char *zTrunk;
357
358 /* If mergeRiserFrom[X]==Y that means rail X holds a merge riser
359 ** coming up from the bottom of the graph from off-screen check-in Y
360 ** where Y is the RID. There is no riser on rail X if mergeRiserFrom[X]==0.
361 */
362 int mergeRiserFrom[GR_MAX_RAIL];
363
364 if( p==0 || p->pFirst==0 || p->nErr ) return;
365 p->nErr = 1; /* Assume an error until proven otherwise */
366
367 /* Initialize all rows */
@@ -367,11 +376,11 @@
376 pDup->isDup = 1;
377 }
378 hashInsert(p, pRow, 1);
379 }
380 p->mxRail = -1;
381 memset(mergeRiserFrom, 0, sizeof(mergeRiserFrom));
382
383 /* Purge merge-parents that are out-of-graph if descenders are not
384 ** drawn.
385 **
386 ** Each node has one primary parent and zero or more "merge" parents.
@@ -460,13 +469,10 @@
469 }
470 if( p->mxRail>=GR_MAX_RAIL ) return;
471 mask = BIT(pRow->iRail);
472 if( !omitDescenders ){
473 pRow->bDescender = pRow->nParent>0;
 
 
 
474 for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
475 pLoop->railInUse |= mask;
476 }
477 }
478 assignChildrenToRail(pRow);
@@ -543,19 +549,19 @@
549 pDesc = hashFind(p, parentRid);
550 if( pDesc==0 ){
551 /* Merge from a node that is off-screen */
552 int iMrail = -1;
553 for(j=0; j<GR_MAX_RAIL; j++){
554 if( mergeRiserFrom[j]==parentRid ){
555 iMrail = j;
556 break;
557 }
558 }
559 if( iMrail==-1 ){
560 iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
561 if( p->mxRail>=GR_MAX_RAIL ) return;
562 mergeRiserFrom[iMrail] = parentRid;
563 }
564 mask = BIT(iMrail);
565 pRow->mergeIn[iMrail] = 1;
566 pRow->mergeDown |= mask;
567 for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){
568
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -69,10 +69,19 @@
6969
* <a href="../../../timeline?y=ci&n=15&b=2a4e4cf03e"
7070
target="testwindow">Isolated check-ins.</a>
7171
* <a href="../../../timeline?b=0fa60142&n=50"
7272
target="testwindow">Single branch raiser from bottom of page
7373
up to checkins 057e4b and d3cc6d</a>
74
+ * <a href="../../../timeline?a=68194175&n=2"
75
+ target="testwindow">Branch riser comes from the bottom of the screen</a>
76
+ * <a href="../../../timeline?a=2bc3cfeb&n=5"
77
+ target="testwindow">Branch risers comes from the bottom of the
78
+ screen, not from the andygoth-crlf branch.</a>
79
+ * <a href="../../../timeline?a=b8c7af5b&n=12"
80
+ target="testwindow">Check-in 2de15c8e has merge arrows from two
81
+ different trunk check-ins. One of the merge risers also branches
82
+ to check-in ea7f3297</a>
7483
7584
External:
7685
7786
* <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
7887
target="testwindow">Timewarp due to a mis-configured system clock.</a>
7988
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -69,10 +69,19 @@
69 * <a href="../../../timeline?y=ci&n=15&b=2a4e4cf03e"
70 target="testwindow">Isolated check-ins.</a>
71 * <a href="../../../timeline?b=0fa60142&n=50"
72 target="testwindow">Single branch raiser from bottom of page
73 up to checkins 057e4b and d3cc6d</a>
 
 
 
 
 
 
 
 
 
74
75 External:
76
77 * <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
78 target="testwindow">Timewarp due to a mis-configured system clock.</a>
79
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -69,10 +69,19 @@
69 * <a href="../../../timeline?y=ci&n=15&b=2a4e4cf03e"
70 target="testwindow">Isolated check-ins.</a>
71 * <a href="../../../timeline?b=0fa60142&n=50"
72 target="testwindow">Single branch raiser from bottom of page
73 up to checkins 057e4b and d3cc6d</a>
74 * <a href="../../../timeline?a=68194175&n=2"
75 target="testwindow">Branch riser comes from the bottom of the screen</a>
76 * <a href="../../../timeline?a=2bc3cfeb&n=5"
77 target="testwindow">Branch risers comes from the bottom of the
78 screen, not from the andygoth-crlf branch.</a>
79 * <a href="../../../timeline?a=b8c7af5b&n=12"
80 target="testwindow">Check-in 2de15c8e has merge arrows from two
81 different trunk check-ins. One of the merge risers also branches
82 to check-in ea7f3297</a>
83
84 External:
85
86 * <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
87 target="testwindow">Timewarp due to a mis-configured system clock.</a>
88

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button