Fossil SCM

In the graph, when a merge riser comes up out of a leaf on a different rail, try to shift the branch rail to be directly underneath the merge riser.

drh 2022-03-22 15:53 trunk
Commit 1e70f826b912a2c4e9582340bb63fdfd61bd530f54f3618b6145da42a33167aa
1 file changed +69 -2
+69 -2
--- src/graph.c
+++ src/graph.c
@@ -82,11 +82,12 @@
8282
int idx; /* Row index. Top row is smallest. */
8383
int idxTop; /* Direct descendent highest up on the graph */
8484
GraphRow *pChild; /* Child immediately above this node */
8585
u8 isDup; /* True if this is duplicate of a prior entry */
8686
u8 isLeaf; /* True if this is a leaf node */
87
- u8 isStepParent; /* pChild is actually a step-child */
87
+ u8 isStepParent; /* pChild is actually a step-child. The thick
88
+ ** arrow up to the child is dashed, not solid */
8889
u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
8990
u8 timeWarp; /* Child is earlier in time */
9091
u8 bDescender; /* True if riser from bottom of graph to here. */
9192
u8 selfUp; /* Space above this node but belonging */
9293
i8 iRail; /* Which rail this check-in appears on. 0-based.*/
@@ -109,10 +110,12 @@
109110
GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
110111
int nBranch; /* Number of distinct branches */
111112
char **azBranch; /* Names of the branches */
112113
int nRow; /* Number of rows */
113114
int nHash; /* Number of slots in apHash[] */
115
+ u8 hasOffsetMergeRiser; /* Merge arrow from leaf goes up on a different
116
+ ** rail that the node */
114117
u64 mergeRail; /* Rails used for merge lines */
115118
GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
116119
u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */
117120
};
118121
@@ -417,10 +420,11 @@
417420
pParent->mergeOut = pParent->iRail;
418421
}else{
419422
/* The thin merge arrow riser is taller than the thick primary
420423
** child riser, so use separate rails. */
421424
int iTarget = pParent->iRail;
425
+ if( u<0 ) p->hasOffsetMergeRiser = 1;
422426
pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1,
423427
iTarget, 1);
424428
mask = BIT(pParent->mergeOut);
425429
for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
426430
pLoop=pLoop->pNext){
@@ -469,11 +473,10 @@
469473
while( pRow && (n--)>0 ){
470474
pRow->railInUse |= mask;
471475
pRow = pRow->pPrev;
472476
}
473477
}
474
-
475478
476479
/*
477480
** Compute the complete graph
478481
**
479482
** When primary or merge parents are off-screen, normally a line is drawn
@@ -887,10 +890,74 @@
887890
888891
/*
889892
** Find the maximum rail number.
890893
*/
891894
find_max_rail(p);
895
+
896
+ /* If a leaf node has a merge riser going up on a different rail,
897
+ ** try to move the rail of the node (and its ancestors) to be underneath
898
+ ** the merge riser. This is an optimization that improves the
899
+ ** appearance of graph but is not strictly necessary.
900
+ */
901
+ if( nTimewarp==0 && p->hasOffsetMergeRiser ){
902
+ for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
903
+ GraphRow *pBottom; /* Bottom row of a branch */
904
+ GraphRow *pRoot; /* Node off of which the branch diverges */
905
+ int iFrom; /* Proposed to move from this rail */
906
+ int iTo; /* Move the branch to this rail */
907
+
908
+ iFrom = pRow->iRail;
909
+ if( pRow->aiRiser[iFrom]>=0 ) continue; /* Not a leaf */
910
+ if( pRow->mergeOut<0 ) continue; /* No merge riser */
911
+ if( pRow->mergeOut==iFrom ) continue; /* Riser already aligned */
912
+ iTo = pRow->mergeOut;
913
+
914
+ /* Find the bottom (oldest) node in the branch */
915
+ pBottom = 0;
916
+ for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
917
+ if( pLoop->idxTop==pRow->idx ) pBottom = pLoop;
918
+ }
919
+ if( pBottom==0 ) continue; /* Not possible */
920
+
921
+ /* Verify that the rail we want to shift into is clear */
922
+ pLoop = pBottom;
923
+ if( pLoop->pNext ) pLoop = pLoop->pNext;
924
+ if( !railIsClear(pLoop, pRow->idx+1, iTo) ){
925
+ /* Other nodes or risers are already using the space that
926
+ ** we propose to move the pRow branch into. */
927
+ continue;
928
+ }
929
+
930
+ /* Find the "root" of the branch. The root is a different branch
931
+ ** from which the pRow branch emerges. There might not be a root
932
+ ** if the pRow branch started off the bottom of the screen.
933
+ */
934
+ for(pRoot=pBottom->pNext; pRoot; pRoot=pRoot->pNext){
935
+ if( pRoot->aiRiser[iFrom]>=0 ) break;
936
+ }
937
+ if( pRoot && pRoot->iRail==iTo ){
938
+ /* The parent branch from which this branch emerges is on the
939
+ ** same rail as pRow. Do not shift as that would stack a child
940
+ ** branch directly above its parent. */
941
+ continue;
942
+ }
943
+
944
+ /* All clear. Make the translation
945
+ */
946
+ for(pLoop=pRow; pLoop && pLoop->idx<=pBottom->idx; pLoop=pLoop->pNext){
947
+ if( pLoop->iRail==iFrom ){
948
+ pLoop->iRail = iTo;
949
+ pLoop->aiRiser[iTo] = pLoop->aiRiser[iFrom];
950
+ pLoop->aiRiser[iFrom] = -1;
951
+ }
952
+ }
953
+ if( pRoot ){
954
+ pRoot->aiRiser[iTo] = pRoot->aiRiser[iFrom];
955
+ pRoot->aiRiser[iFrom] = -1;
956
+ }
957
+ }
958
+ }
892959
893960
/*
894961
** Compute the rail mapping that tries to put the branch named
895962
** zLeftBranch at the left margin. Other branches that merge
896963
** with zLeftBranch are to the right with merge rails in between.
897964
--- src/graph.c
+++ src/graph.c
@@ -82,11 +82,12 @@
82 int idx; /* Row index. Top row is smallest. */
83 int idxTop; /* Direct descendent highest up on the graph */
84 GraphRow *pChild; /* Child immediately above this node */
85 u8 isDup; /* True if this is duplicate of a prior entry */
86 u8 isLeaf; /* True if this is a leaf node */
87 u8 isStepParent; /* pChild is actually a step-child */
 
88 u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
89 u8 timeWarp; /* Child is earlier in time */
90 u8 bDescender; /* True if riser from bottom of graph to here. */
91 u8 selfUp; /* Space above this node but belonging */
92 i8 iRail; /* Which rail this check-in appears on. 0-based.*/
@@ -109,10 +110,12 @@
109 GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
110 int nBranch; /* Number of distinct branches */
111 char **azBranch; /* Names of the branches */
112 int nRow; /* Number of rows */
113 int nHash; /* Number of slots in apHash[] */
 
 
114 u64 mergeRail; /* Rails used for merge lines */
115 GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
116 u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */
117 };
118
@@ -417,10 +420,11 @@
417 pParent->mergeOut = pParent->iRail;
418 }else{
419 /* The thin merge arrow riser is taller than the thick primary
420 ** child riser, so use separate rails. */
421 int iTarget = pParent->iRail;
 
422 pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1,
423 iTarget, 1);
424 mask = BIT(pParent->mergeOut);
425 for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
426 pLoop=pLoop->pNext){
@@ -469,11 +473,10 @@
469 while( pRow && (n--)>0 ){
470 pRow->railInUse |= mask;
471 pRow = pRow->pPrev;
472 }
473 }
474
475
476 /*
477 ** Compute the complete graph
478 **
479 ** When primary or merge parents are off-screen, normally a line is drawn
@@ -887,10 +890,74 @@
887
888 /*
889 ** Find the maximum rail number.
890 */
891 find_max_rail(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
892
893 /*
894 ** Compute the rail mapping that tries to put the branch named
895 ** zLeftBranch at the left margin. Other branches that merge
896 ** with zLeftBranch are to the right with merge rails in between.
897
--- src/graph.c
+++ src/graph.c
@@ -82,11 +82,12 @@
82 int idx; /* Row index. Top row is smallest. */
83 int idxTop; /* Direct descendent highest up on the graph */
84 GraphRow *pChild; /* Child immediately above this node */
85 u8 isDup; /* True if this is duplicate of a prior entry */
86 u8 isLeaf; /* True if this is a leaf node */
87 u8 isStepParent; /* pChild is actually a step-child. The thick
88 ** arrow up to the child is dashed, not solid */
89 u8 hasNormalOutMerge; /* Is parent of at laest 1 non-cherrypick merge */
90 u8 timeWarp; /* Child is earlier in time */
91 u8 bDescender; /* True if riser from bottom of graph to here. */
92 u8 selfUp; /* Space above this node but belonging */
93 i8 iRail; /* Which rail this check-in appears on. 0-based.*/
@@ -109,10 +110,12 @@
110 GraphRow *pLast; /* Last row in the list. Bottom row of graph. */
111 int nBranch; /* Number of distinct branches */
112 char **azBranch; /* Names of the branches */
113 int nRow; /* Number of rows */
114 int nHash; /* Number of slots in apHash[] */
115 u8 hasOffsetMergeRiser; /* Merge arrow from leaf goes up on a different
116 ** rail that the node */
117 u64 mergeRail; /* Rails used for merge lines */
118 GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */
119 u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */
120 };
121
@@ -417,10 +420,11 @@
420 pParent->mergeOut = pParent->iRail;
421 }else{
422 /* The thin merge arrow riser is taller than the thick primary
423 ** child riser, so use separate rails. */
424 int iTarget = pParent->iRail;
425 if( u<0 ) p->hasOffsetMergeRiser = 1;
426 pParent->mergeOut = findFreeRail(p, pChild->idx, pParent->idx-1,
427 iTarget, 1);
428 mask = BIT(pParent->mergeOut);
429 for(pLoop=pChild->pNext; pLoop && pLoop->rid!=pParent->rid;
430 pLoop=pLoop->pNext){
@@ -469,11 +473,10 @@
473 while( pRow && (n--)>0 ){
474 pRow->railInUse |= mask;
475 pRow = pRow->pPrev;
476 }
477 }
 
478
479 /*
480 ** Compute the complete graph
481 **
482 ** When primary or merge parents are off-screen, normally a line is drawn
@@ -887,10 +890,74 @@
890
891 /*
892 ** Find the maximum rail number.
893 */
894 find_max_rail(p);
895
896 /* If a leaf node has a merge riser going up on a different rail,
897 ** try to move the rail of the node (and its ancestors) to be underneath
898 ** the merge riser. This is an optimization that improves the
899 ** appearance of graph but is not strictly necessary.
900 */
901 if( nTimewarp==0 && p->hasOffsetMergeRiser ){
902 for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
903 GraphRow *pBottom; /* Bottom row of a branch */
904 GraphRow *pRoot; /* Node off of which the branch diverges */
905 int iFrom; /* Proposed to move from this rail */
906 int iTo; /* Move the branch to this rail */
907
908 iFrom = pRow->iRail;
909 if( pRow->aiRiser[iFrom]>=0 ) continue; /* Not a leaf */
910 if( pRow->mergeOut<0 ) continue; /* No merge riser */
911 if( pRow->mergeOut==iFrom ) continue; /* Riser already aligned */
912 iTo = pRow->mergeOut;
913
914 /* Find the bottom (oldest) node in the branch */
915 pBottom = 0;
916 for(pLoop=pRow; pLoop; pLoop=pLoop->pNext){
917 if( pLoop->idxTop==pRow->idx ) pBottom = pLoop;
918 }
919 if( pBottom==0 ) continue; /* Not possible */
920
921 /* Verify that the rail we want to shift into is clear */
922 pLoop = pBottom;
923 if( pLoop->pNext ) pLoop = pLoop->pNext;
924 if( !railIsClear(pLoop, pRow->idx+1, iTo) ){
925 /* Other nodes or risers are already using the space that
926 ** we propose to move the pRow branch into. */
927 continue;
928 }
929
930 /* Find the "root" of the branch. The root is a different branch
931 ** from which the pRow branch emerges. There might not be a root
932 ** if the pRow branch started off the bottom of the screen.
933 */
934 for(pRoot=pBottom->pNext; pRoot; pRoot=pRoot->pNext){
935 if( pRoot->aiRiser[iFrom]>=0 ) break;
936 }
937 if( pRoot && pRoot->iRail==iTo ){
938 /* The parent branch from which this branch emerges is on the
939 ** same rail as pRow. Do not shift as that would stack a child
940 ** branch directly above its parent. */
941 continue;
942 }
943
944 /* All clear. Make the translation
945 */
946 for(pLoop=pRow; pLoop && pLoop->idx<=pBottom->idx; pLoop=pLoop->pNext){
947 if( pLoop->iRail==iFrom ){
948 pLoop->iRail = iTo;
949 pLoop->aiRiser[iTo] = pLoop->aiRiser[iFrom];
950 pLoop->aiRiser[iFrom] = -1;
951 }
952 }
953 if( pRoot ){
954 pRoot->aiRiser[iTo] = pRoot->aiRiser[iFrom];
955 pRoot->aiRiser[iFrom] = -1;
956 }
957 }
958 }
959
960 /*
961 ** Compute the rail mapping that tries to put the branch named
962 ** zLeftBranch at the left margin. Other branches that merge
963 ** with zLeftBranch are to the right with merge rails in between.
964

Keyboard Shortcuts

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