Fossil

Check-in [95d6ddc3]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Combine multiple merge lines to the bottomn of the page when they reference the same source check-in.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 95d6ddc3a0a63d21dd6500b34b1cf11dc3109865
User & Date: drh 2016-10-27 15:35:16
References
2016-12-14
01:09
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. check-in: 9ed13436 user: drh tags: trunk
Context
2016-10-28
05:29
Alternative to check-in [a4bb89ba08], make FuseFS act just like the JSON feature in 'auto.def'. check-in: feb202f5 user: mistachkin tags: trunk
04:27
Alternative to check-in [a4bb89ba08], make FuseFS act just like the JSON feature in 'auto.def'. Closed-Leaf check-in: 6a80a2f2 user: mistachkin tags: altFuseFsDef
2016-10-27
15:35
Combine multiple merge lines to the bottomn of the page when they reference the same source check-in. check-in: 95d6ddc3 user: drh tags: trunk
15:34
Add another entry to the graph-test-1.wiki checklist for this case. Closed-Leaf check-in: 58d4f3c0 user: drh tags: baruch-timeline-fix
05:28
Now that FuseFS support is conditional, permit config.h to be included so FOSSIL_HAVE_FUSEFS can be correctly included from autoconfig.h to avoid linker failure to find fusefs_cmd. check-in: a4bb89ba user: andybradford tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/graph.c.

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
...
342
343
344
345
346
347
348
349
350
351
352


353
354
355
356
357
358
359
...
364
365
366
367
368
369
370

371
372
373
374
375
376
377
...
456
457
458
459
460
461
462



463
464
465
466
467
468
469
...
534
535
536
537
538
539
540








541
542


543
544
545
546
547
548
549
*/
static void assignChildrenToRail(GraphRow *pBottom){
  int iRail = pBottom->iRail;
  GraphRow *pCurrent;
  GraphRow *pPrior;
  u64 mask = ((u64)1)<<iRail;

  pBottom->iRail = iRail;
  pBottom->railInUse |= mask;
  pPrior = pBottom;
  for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
    assert( pPrior->idx > pCurrent->idx );
    assert( pCurrent->iRail<0 );
    pCurrent->iRail = iRail;
    pCurrent->railInUse |= mask;
................................................................................


/*
** Compute the complete graph
*/
void graph_finish(GraphContext *p, int omitDescenders){
  GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
  int i;
  u64 mask;
  int hasDup = 0;      /* True if one or more isDup entries */
  const char *zTrunk;



  if( p==0 || p->pFirst==0 || p->nErr ) return;
  p->nErr = 1;   /* Assume an error until proven otherwise */

  /* Initialize all rows */
  p->nHash = p->nRow*2 + 1;
  p->apHash = safeMalloc( sizeof(p->apHash[0])*p->nHash );
................................................................................
    if( (pDup = hashFind(p, pRow->rid))!=0 ){
      hasDup = 1;
      pDup->isDup = 1;
    }
    hashInsert(p, pRow, 1);
  }
  p->mxRail = -1;


  /* Purge merge-parents that are out-of-graph if descenders are not
  ** drawn.
  **
  ** Each node has one primary parent and zero or more "merge" parents.
  ** A merge parent is a prior check-in from which changes were merged into
  ** the current check-in.  If a merge parent is not in the visible section
................................................................................
        }else{
          pRow->iRail = ++p->mxRail;
        }
        if( p->mxRail>=GR_MAX_RAIL ) return;
        mask = BIT(pRow->iRail);
        if( !omitDescenders ){
          pRow->bDescender = pRow->nParent>0;



          for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
            pLoop->railInUse |= mask;
          }
        }
        assignChildrenToRail(pRow);
      }
    }
................................................................................
  */
  for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
    for(i=1; i<pRow->nParent; i++){
      int parentRid = pRow->aParent[i];
      pDesc = hashFind(p, parentRid);
      if( pDesc==0 ){
        /* Merge from a node that is off-screen */








        int iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
        if( p->mxRail>=GR_MAX_RAIL ) return;


        mask = BIT(iMrail);
        pRow->mergeIn[iMrail] = 1;
        pRow->mergeDown |= mask;
        for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){
          pLoop->railInUse |= mask;
        }
      }else{







<







 







|



>
>







 







>







 







>
>
>







 







>
>
>
>
>
>
>
>
|
|
>
>







256
257
258
259
260
261
262

263
264
265
266
267
268
269
...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
...
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
*/
static void assignChildrenToRail(GraphRow *pBottom){
  int iRail = pBottom->iRail;
  GraphRow *pCurrent;
  GraphRow *pPrior;
  u64 mask = ((u64)1)<<iRail;


  pBottom->railInUse |= mask;
  pPrior = pBottom;
  for(pCurrent=pBottom->pChild; pCurrent; pCurrent=pCurrent->pChild){
    assert( pPrior->idx > pCurrent->idx );
    assert( pCurrent->iRail<0 );
    pCurrent->iRail = iRail;
    pCurrent->railInUse |= mask;
................................................................................


/*
** Compute the complete graph
*/
void graph_finish(GraphContext *p, int omitDescenders){
  GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
  int i, j;
  u64 mask;
  int hasDup = 0;      /* True if one or more isDup entries */
  const char *zTrunk;
  int railRid[GR_MAX_RAIL]; /* Maps rails to rids for lines 
                               that enter from bottom of screen */

  if( p==0 || p->pFirst==0 || p->nErr ) return;
  p->nErr = 1;   /* Assume an error until proven otherwise */

  /* Initialize all rows */
  p->nHash = p->nRow*2 + 1;
  p->apHash = safeMalloc( sizeof(p->apHash[0])*p->nHash );
................................................................................
    if( (pDup = hashFind(p, pRow->rid))!=0 ){
      hasDup = 1;
      pDup->isDup = 1;
    }
    hashInsert(p, pRow, 1);
  }
  p->mxRail = -1;
  memset(railRid, 0, sizeof(railRid));

  /* Purge merge-parents that are out-of-graph if descenders are not
  ** drawn.
  **
  ** Each node has one primary parent and zero or more "merge" parents.
  ** A merge parent is a prior check-in from which changes were merged into
  ** the current check-in.  If a merge parent is not in the visible section
................................................................................
        }else{
          pRow->iRail = ++p->mxRail;
        }
        if( p->mxRail>=GR_MAX_RAIL ) return;
        mask = BIT(pRow->iRail);
        if( !omitDescenders ){
          pRow->bDescender = pRow->nParent>0;
          if( pRow->bDescender ){
            railRid[pRow->iRail] = pRow->aParent[0];
          }
          for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
            pLoop->railInUse |= mask;
          }
        }
        assignChildrenToRail(pRow);
      }
    }
................................................................................
  */
  for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
    for(i=1; i<pRow->nParent; i++){
      int parentRid = pRow->aParent[i];
      pDesc = hashFind(p, parentRid);
      if( pDesc==0 ){
        /* Merge from a node that is off-screen */
        int iMrail = -1;
        for(j=0; j<GR_MAX_RAIL; j++){
          if( railRid[j]==parentRid ){
            iMrail = j;
            break;
          }
        }
        if( iMrail==-1 ){
          iMrail = findFreeRail(p, pRow->idx, p->nRow, 0);
          if( p->mxRail>=GR_MAX_RAIL ) return;
          railRid[iMrail] = parentRid;
        }
        mask = BIT(iMrail);
        pRow->mergeIn[iMrail] = 1;
        pRow->mergeDown |= mask;
        for(pLoop=pRow->pNext; pLoop; pLoop=pLoop->pNext){
          pLoop->railInUse |= mask;
        }
      }else{

Changes to src/timeline.c.

735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
        pRow->iRail,                    /* r */
        pRow->bDescender,               /* d */
        pRow->mergeOut,                 /* mo */
        pRow->mergeUpto,                /* mu */
        pRow->aiRiser[pRow->iRail],     /* u */
        pRow->isLeaf ? 1 : 0            /* f */
      );
      /* u */
      cSep = '[';
      for(i=0; i<GR_MAX_RAIL; i++){
        if( i==pRow->iRail ) continue;
        if( pRow->aiRiser[i]>0 ){
          cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]);
          cSep = ',';
        }







|







735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
        pRow->iRail,                    /* r */
        pRow->bDescender,               /* d */
        pRow->mergeOut,                 /* mo */
        pRow->mergeUpto,                /* mu */
        pRow->aiRiser[pRow->iRail],     /* u */
        pRow->isLeaf ? 1 : 0            /* f */
      );
      /* au */
      cSep = '[';
      for(i=0; i<GR_MAX_RAIL; i++){
        if( i==pRow->iRail ) continue;
        if( pRow->aiRiser[i]>0 ){
          cgi_printf("%c%d,%d", cSep, i, pRow->aiRiser[i]);
          cSep = ',';
        }

Changes to test/graph-test-1.wiki.

64
65
66
67
68
69
70



71
72
73
74
75
76
77
     Merge on the same branch does not result in a leaf.
     </a>
  *  <a href="../../../timeline?c=20015206bc"
     target="testwindow">
     This timeline has a hidden commit.</a> Click Unhide to reveal.
  *  <a href="../../../timeline?y=ci&n=15&b=2a4e4cf03e"
     target="testwindow">Isolated check-ins.</a>




External:

  *  <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
     target="testwindow">Timewarp due to a mis-configured system clock.</a>
  *  <a href="http://core.tcl.tk/tk/finfo?name=tests/id.test"
     target="testwindow">Show all three separate deletions of "id.test".







>
>
>







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
     Merge on the same branch does not result in a leaf.
     </a>
  *  <a href="../../../timeline?c=20015206bc"
     target="testwindow">
     This timeline has a hidden commit.</a> Click Unhide to reveal.
  *  <a href="../../../timeline?y=ci&n=15&b=2a4e4cf03e"
     target="testwindow">Isolated check-ins.</a>
  *  <a href="../../../timeline?b=0fa60142&n=50"
     target="testwindow">Single branch raiser from bottom of page
     up to checkins 057e4b and d3cc6d</a>

External:

  *  <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
     target="testwindow">Timewarp due to a mis-configured system clock.</a>
  *  <a href="http://core.tcl.tk/tk/finfo?name=tests/id.test"
     target="testwindow">Show all three separate deletions of "id.test".