Fossil SCM
In graph layout, if we run out of rails for new graph elements, do the best as we can, but continue to try to show a graph. Better to draw a goofy graph than to not show the graph at all.
Commit
a8c6f3a47038eaba1c6b1c6127155d46cb759f5c7348594aefba1e3bfca29d62
Parent
5bc31db11a8e611…
1 file changed
+29
-11
+29
-11
| --- src/graph.c | ||
| +++ src/graph.c | ||
| @@ -59,11 +59,11 @@ | ||
| 59 | 59 | ** check-ins and many files. For this reason, we make the identifier |
| 60 | 60 | ** a 64-bit integer, to dramatically reduce the risk of an overflow. |
| 61 | 61 | */ |
| 62 | 62 | typedef sqlite3_int64 GraphRowId; |
| 63 | 63 | |
| 64 | -#define GR_MAX_RAIL 60 /* Max number of "rails" to display */ | |
| 64 | +#define GR_MAX_RAIL 64 /* Max number of "rails" to display */ | |
| 65 | 65 | |
| 66 | 66 | /* The graph appears vertically beside a timeline. Each row in the |
| 67 | 67 | ** timeline corresponds to a row in the graph. GraphRow.idx is 0 for |
| 68 | 68 | ** the top-most row and increases moving down. Hence (in the absence of |
| 69 | 69 | ** time skew) parents have a larger index than their children. |
| @@ -118,10 +118,11 @@ | ||
| 118 | 118 | char **azBranch; /* Names of the branches */ |
| 119 | 119 | int nRow; /* Number of rows */ |
| 120 | 120 | int nHash; /* Number of slots in apHash[] */ |
| 121 | 121 | u8 hasOffsetMergeRiser; /* Merge arrow from leaf goes up on a different |
| 122 | 122 | ** rail that the node */ |
| 123 | + u8 bOverfull; /* Unable to allocate sufficient rails */ | |
| 123 | 124 | u64 mergeRail; /* Rails used for merge lines */ |
| 124 | 125 | GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */ |
| 125 | 126 | u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */ |
| 126 | 127 | }; |
| 127 | 128 | |
| @@ -336,11 +337,18 @@ | ||
| 336 | 337 | iBestDist = dist; |
| 337 | 338 | iBest = i; |
| 338 | 339 | } |
| 339 | 340 | } |
| 340 | 341 | } |
| 341 | - if( iBestDist>1000 ) p->nErr++; | |
| 342 | + if( iBestDist>1000 ){ | |
| 343 | + p->bOverfull = 1; | |
| 344 | + iBest = GR_MAX_RAIL; | |
| 345 | + } | |
| 346 | + if( iBest>GR_MAX_RAIL ){ | |
| 347 | + p->bOverfull = 1; | |
| 348 | + iBest = GR_MAX_RAIL; | |
| 349 | + } | |
| 342 | 350 | if( iBest>p->mxRail ) p->mxRail = iBest; |
| 343 | 351 | if( bMergeRail ) p->mergeRail |= BIT(iBest); |
| 344 | 352 | return iBest; |
| 345 | 353 | } |
| 346 | 354 | |
| @@ -709,11 +717,11 @@ | ||
| 709 | 717 | if( pRow->iRail>=0 ) continue; |
| 710 | 718 | if( pRow->isDup ) continue; |
| 711 | 719 | if( pRow->nParent<0 ) continue; |
| 712 | 720 | if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){ |
| 713 | 721 | pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin,0,0); |
| 714 | - if( p->mxRail>=GR_MAX_RAIL ) return; | |
| 722 | + /* if( p->mxRail>=GR_MAX_RAIL ) return; */ | |
| 715 | 723 | mask = BIT(pRow->iRail); |
| 716 | 724 | if( !omitDescenders ){ |
| 717 | 725 | int n = RISER_MARGIN; |
| 718 | 726 | pRow->bDescender = pRow->nParent>0; |
| 719 | 727 | for(pLoop=pRow; pLoop && (n--)>0; pLoop=pLoop->pNext){ |
| @@ -744,28 +752,38 @@ | ||
| 744 | 752 | assert( pRow->nParent>0 ); |
| 745 | 753 | parentRid = pRow->aParent[0]; |
| 746 | 754 | pParent = hashFind(p, parentRid); |
| 747 | 755 | if( pParent==0 ){ |
| 748 | 756 | pRow->iRail = ++p->mxRail; |
| 749 | - if( p->mxRail>=GR_MAX_RAIL ) return; | |
| 757 | + if( p->mxRail>=GR_MAX_RAIL ){ | |
| 758 | + pRow->iRail = p->mxRail = GR_MAX_RAIL; | |
| 759 | + p->bOverfull = 1; | |
| 760 | + } | |
| 750 | 761 | pRow->railInUse = BIT(pRow->iRail); |
| 751 | 762 | continue; |
| 752 | 763 | } |
| 753 | 764 | if( pParent->idx>pRow->idx ){ |
| 754 | 765 | /* Common case: Child occurs after parent and is above the |
| 755 | 766 | ** parent in the timeline */ |
| 756 | 767 | pRow->iRail = findFreeRail(p, pRow->idxTop, pParent->idx, |
| 757 | 768 | pParent->iRail, 0); |
| 758 | - if( p->mxRail>=GR_MAX_RAIL ) return; | |
| 769 | + /* if( p->mxRail>=GR_MAX_RAIL ) return; */ | |
| 759 | 770 | pParent->aiRiser[pRow->iRail] = pRow->idx; |
| 760 | 771 | }else{ |
| 761 | 772 | /* Timewarp case: Child occurs earlier in time than parent and |
| 762 | 773 | ** appears below the parent in the timeline. */ |
| 763 | 774 | int iDownRail = ++p->mxRail; |
| 764 | 775 | if( iDownRail<1 ) iDownRail = ++p->mxRail; |
| 776 | + if( p->mxRail>GR_MAX_RAIL ){ | |
| 777 | + iDownRail = p->mxRail = GR_MAX_RAIL; | |
| 778 | + p->bOverfull = 1; | |
| 779 | + } | |
| 765 | 780 | pRow->iRail = ++p->mxRail; |
| 766 | - if( p->mxRail>=GR_MAX_RAIL ) return; | |
| 781 | + if( p->mxRail>=GR_MAX_RAIL ){ | |
| 782 | + pRow->iRail = p->mxRail = GR_MAX_RAIL; | |
| 783 | + p->bOverfull = 1; | |
| 784 | + } | |
| 767 | 785 | pRow->railInUse = BIT(pRow->iRail); |
| 768 | 786 | pParent->aiRiser[iDownRail] = pRow->idx; |
| 769 | 787 | mask = BIT(iDownRail); |
| 770 | 788 | for(pLoop=p->pFirst; pLoop; pLoop=pLoop->pNext){ |
| 771 | 789 | pLoop->railInUse |= mask; |
| @@ -824,11 +842,11 @@ | ||
| 824 | 842 | break; |
| 825 | 843 | } |
| 826 | 844 | } |
| 827 | 845 | if( iMrail==-1 ){ |
| 828 | 846 | iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1); |
| 829 | - if( p->mxRail>=GR_MAX_RAIL ) return; | |
| 847 | + /*if( p->mxRail>=GR_MAX_RAIL ) return;*/ | |
| 830 | 848 | mergeRiserFrom[iMrail] = parentRid; |
| 831 | 849 | } |
| 832 | 850 | iReuseIdx = p->nRow+1; |
| 833 | 851 | iReuseRail = iMrail; |
| 834 | 852 | mask = BIT(iMrail); |
| @@ -856,11 +874,11 @@ | ||
| 856 | 874 | pDesc->mergeUpto = pDesc->idx; |
| 857 | 875 | } |
| 858 | 876 | }else{ |
| 859 | 877 | /* Create a new merge for an on-screen node */ |
| 860 | 878 | createMergeRiser(p, pDesc, pRow, isCherrypick); |
| 861 | - if( p->mxRail>=GR_MAX_RAIL ) return; | |
| 879 | + /* if( p->mxRail>=GR_MAX_RAIL ) return; */ | |
| 862 | 880 | if( iReuseIdx<0 |
| 863 | 881 | && pDesc->nMergeChild==1 |
| 864 | 882 | && (pDesc->iRail!=pDesc->mergeOut || pDesc->isLeaf) |
| 865 | 883 | ){ |
| 866 | 884 | iReuseIdx = pDesc->idx; |
| @@ -872,17 +890,17 @@ | ||
| 872 | 890 | } |
| 873 | 891 | |
| 874 | 892 | /* |
| 875 | 893 | ** Insert merge rails from primaries to duplicates. |
| 876 | 894 | */ |
| 877 | - if( hasDup ){ | |
| 895 | + if( hasDup && p->mxRail<GR_MAX_RAIL ){ | |
| 878 | 896 | int dupRail; |
| 879 | 897 | int mxRail; |
| 880 | 898 | find_max_rail(p); |
| 881 | 899 | mxRail = p->mxRail; |
| 882 | 900 | dupRail = mxRail+1; |
| 883 | - if( p->mxRail>=GR_MAX_RAIL ) return; | |
| 901 | + /* if( p->mxRail>=GR_MAX_RAIL ) return; */ | |
| 884 | 902 | for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ |
| 885 | 903 | if( !pRow->isDup ) continue; |
| 886 | 904 | pRow->iRail = dupRail; |
| 887 | 905 | pDesc = hashFind(p, pRow->rid); |
| 888 | 906 | assert( pDesc!=0 && pDesc!=pRow ); |
| @@ -893,11 +911,11 @@ | ||
| 893 | 911 | dupRail = mxRail+1; |
| 894 | 912 | for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ |
| 895 | 913 | if( pRow->isDup ) pRow->iRail = dupRail; |
| 896 | 914 | } |
| 897 | 915 | } |
| 898 | - if( mxRail>=GR_MAX_RAIL ) return; | |
| 916 | + /* if( mxRail>=GR_MAX_RAIL ) return; */ | |
| 899 | 917 | } |
| 900 | 918 | |
| 901 | 919 | /* |
| 902 | 920 | ** Find the maximum rail number. |
| 903 | 921 | */ |
| 904 | 922 |
| --- src/graph.c | |
| +++ src/graph.c | |
| @@ -59,11 +59,11 @@ | |
| 59 | ** check-ins and many files. For this reason, we make the identifier |
| 60 | ** a 64-bit integer, to dramatically reduce the risk of an overflow. |
| 61 | */ |
| 62 | typedef sqlite3_int64 GraphRowId; |
| 63 | |
| 64 | #define GR_MAX_RAIL 60 /* Max number of "rails" to display */ |
| 65 | |
| 66 | /* The graph appears vertically beside a timeline. Each row in the |
| 67 | ** timeline corresponds to a row in the graph. GraphRow.idx is 0 for |
| 68 | ** the top-most row and increases moving down. Hence (in the absence of |
| 69 | ** time skew) parents have a larger index than their children. |
| @@ -118,10 +118,11 @@ | |
| 118 | char **azBranch; /* Names of the branches */ |
| 119 | int nRow; /* Number of rows */ |
| 120 | int nHash; /* Number of slots in apHash[] */ |
| 121 | u8 hasOffsetMergeRiser; /* Merge arrow from leaf goes up on a different |
| 122 | ** rail that the node */ |
| 123 | u64 mergeRail; /* Rails used for merge lines */ |
| 124 | GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */ |
| 125 | u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */ |
| 126 | }; |
| 127 | |
| @@ -336,11 +337,18 @@ | |
| 336 | iBestDist = dist; |
| 337 | iBest = i; |
| 338 | } |
| 339 | } |
| 340 | } |
| 341 | if( iBestDist>1000 ) p->nErr++; |
| 342 | if( iBest>p->mxRail ) p->mxRail = iBest; |
| 343 | if( bMergeRail ) p->mergeRail |= BIT(iBest); |
| 344 | return iBest; |
| 345 | } |
| 346 | |
| @@ -709,11 +717,11 @@ | |
| 709 | if( pRow->iRail>=0 ) continue; |
| 710 | if( pRow->isDup ) continue; |
| 711 | if( pRow->nParent<0 ) continue; |
| 712 | if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){ |
| 713 | pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin,0,0); |
| 714 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 715 | mask = BIT(pRow->iRail); |
| 716 | if( !omitDescenders ){ |
| 717 | int n = RISER_MARGIN; |
| 718 | pRow->bDescender = pRow->nParent>0; |
| 719 | for(pLoop=pRow; pLoop && (n--)>0; pLoop=pLoop->pNext){ |
| @@ -744,28 +752,38 @@ | |
| 744 | assert( pRow->nParent>0 ); |
| 745 | parentRid = pRow->aParent[0]; |
| 746 | pParent = hashFind(p, parentRid); |
| 747 | if( pParent==0 ){ |
| 748 | pRow->iRail = ++p->mxRail; |
| 749 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 750 | pRow->railInUse = BIT(pRow->iRail); |
| 751 | continue; |
| 752 | } |
| 753 | if( pParent->idx>pRow->idx ){ |
| 754 | /* Common case: Child occurs after parent and is above the |
| 755 | ** parent in the timeline */ |
| 756 | pRow->iRail = findFreeRail(p, pRow->idxTop, pParent->idx, |
| 757 | pParent->iRail, 0); |
| 758 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 759 | pParent->aiRiser[pRow->iRail] = pRow->idx; |
| 760 | }else{ |
| 761 | /* Timewarp case: Child occurs earlier in time than parent and |
| 762 | ** appears below the parent in the timeline. */ |
| 763 | int iDownRail = ++p->mxRail; |
| 764 | if( iDownRail<1 ) iDownRail = ++p->mxRail; |
| 765 | pRow->iRail = ++p->mxRail; |
| 766 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 767 | pRow->railInUse = BIT(pRow->iRail); |
| 768 | pParent->aiRiser[iDownRail] = pRow->idx; |
| 769 | mask = BIT(iDownRail); |
| 770 | for(pLoop=p->pFirst; pLoop; pLoop=pLoop->pNext){ |
| 771 | pLoop->railInUse |= mask; |
| @@ -824,11 +842,11 @@ | |
| 824 | break; |
| 825 | } |
| 826 | } |
| 827 | if( iMrail==-1 ){ |
| 828 | iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1); |
| 829 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 830 | mergeRiserFrom[iMrail] = parentRid; |
| 831 | } |
| 832 | iReuseIdx = p->nRow+1; |
| 833 | iReuseRail = iMrail; |
| 834 | mask = BIT(iMrail); |
| @@ -856,11 +874,11 @@ | |
| 856 | pDesc->mergeUpto = pDesc->idx; |
| 857 | } |
| 858 | }else{ |
| 859 | /* Create a new merge for an on-screen node */ |
| 860 | createMergeRiser(p, pDesc, pRow, isCherrypick); |
| 861 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 862 | if( iReuseIdx<0 |
| 863 | && pDesc->nMergeChild==1 |
| 864 | && (pDesc->iRail!=pDesc->mergeOut || pDesc->isLeaf) |
| 865 | ){ |
| 866 | iReuseIdx = pDesc->idx; |
| @@ -872,17 +890,17 @@ | |
| 872 | } |
| 873 | |
| 874 | /* |
| 875 | ** Insert merge rails from primaries to duplicates. |
| 876 | */ |
| 877 | if( hasDup ){ |
| 878 | int dupRail; |
| 879 | int mxRail; |
| 880 | find_max_rail(p); |
| 881 | mxRail = p->mxRail; |
| 882 | dupRail = mxRail+1; |
| 883 | if( p->mxRail>=GR_MAX_RAIL ) return; |
| 884 | for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ |
| 885 | if( !pRow->isDup ) continue; |
| 886 | pRow->iRail = dupRail; |
| 887 | pDesc = hashFind(p, pRow->rid); |
| 888 | assert( pDesc!=0 && pDesc!=pRow ); |
| @@ -893,11 +911,11 @@ | |
| 893 | dupRail = mxRail+1; |
| 894 | for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ |
| 895 | if( pRow->isDup ) pRow->iRail = dupRail; |
| 896 | } |
| 897 | } |
| 898 | if( mxRail>=GR_MAX_RAIL ) return; |
| 899 | } |
| 900 | |
| 901 | /* |
| 902 | ** Find the maximum rail number. |
| 903 | */ |
| 904 |
| --- src/graph.c | |
| +++ src/graph.c | |
| @@ -59,11 +59,11 @@ | |
| 59 | ** check-ins and many files. For this reason, we make the identifier |
| 60 | ** a 64-bit integer, to dramatically reduce the risk of an overflow. |
| 61 | */ |
| 62 | typedef sqlite3_int64 GraphRowId; |
| 63 | |
| 64 | #define GR_MAX_RAIL 64 /* Max number of "rails" to display */ |
| 65 | |
| 66 | /* The graph appears vertically beside a timeline. Each row in the |
| 67 | ** timeline corresponds to a row in the graph. GraphRow.idx is 0 for |
| 68 | ** the top-most row and increases moving down. Hence (in the absence of |
| 69 | ** time skew) parents have a larger index than their children. |
| @@ -118,10 +118,11 @@ | |
| 118 | char **azBranch; /* Names of the branches */ |
| 119 | int nRow; /* Number of rows */ |
| 120 | int nHash; /* Number of slots in apHash[] */ |
| 121 | u8 hasOffsetMergeRiser; /* Merge arrow from leaf goes up on a different |
| 122 | ** rail that the node */ |
| 123 | u8 bOverfull; /* Unable to allocate sufficient rails */ |
| 124 | u64 mergeRail; /* Rails used for merge lines */ |
| 125 | GraphRow **apHash; /* Hash table of GraphRow objects. Key: rid */ |
| 126 | u8 aiRailMap[GR_MAX_RAIL]; /* Mapping of rails to actually columns */ |
| 127 | }; |
| 128 | |
| @@ -336,11 +337,18 @@ | |
| 337 | iBestDist = dist; |
| 338 | iBest = i; |
| 339 | } |
| 340 | } |
| 341 | } |
| 342 | if( iBestDist>1000 ){ |
| 343 | p->bOverfull = 1; |
| 344 | iBest = GR_MAX_RAIL; |
| 345 | } |
| 346 | if( iBest>GR_MAX_RAIL ){ |
| 347 | p->bOverfull = 1; |
| 348 | iBest = GR_MAX_RAIL; |
| 349 | } |
| 350 | if( iBest>p->mxRail ) p->mxRail = iBest; |
| 351 | if( bMergeRail ) p->mergeRail |= BIT(iBest); |
| 352 | return iBest; |
| 353 | } |
| 354 | |
| @@ -709,11 +717,11 @@ | |
| 717 | if( pRow->iRail>=0 ) continue; |
| 718 | if( pRow->isDup ) continue; |
| 719 | if( pRow->nParent<0 ) continue; |
| 720 | if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){ |
| 721 | pRow->iRail = findFreeRail(p, pRow->idxTop, pRow->idx+riserMargin,0,0); |
| 722 | /* if( p->mxRail>=GR_MAX_RAIL ) return; */ |
| 723 | mask = BIT(pRow->iRail); |
| 724 | if( !omitDescenders ){ |
| 725 | int n = RISER_MARGIN; |
| 726 | pRow->bDescender = pRow->nParent>0; |
| 727 | for(pLoop=pRow; pLoop && (n--)>0; pLoop=pLoop->pNext){ |
| @@ -744,28 +752,38 @@ | |
| 752 | assert( pRow->nParent>0 ); |
| 753 | parentRid = pRow->aParent[0]; |
| 754 | pParent = hashFind(p, parentRid); |
| 755 | if( pParent==0 ){ |
| 756 | pRow->iRail = ++p->mxRail; |
| 757 | if( p->mxRail>=GR_MAX_RAIL ){ |
| 758 | pRow->iRail = p->mxRail = GR_MAX_RAIL; |
| 759 | p->bOverfull = 1; |
| 760 | } |
| 761 | pRow->railInUse = BIT(pRow->iRail); |
| 762 | continue; |
| 763 | } |
| 764 | if( pParent->idx>pRow->idx ){ |
| 765 | /* Common case: Child occurs after parent and is above the |
| 766 | ** parent in the timeline */ |
| 767 | pRow->iRail = findFreeRail(p, pRow->idxTop, pParent->idx, |
| 768 | pParent->iRail, 0); |
| 769 | /* if( p->mxRail>=GR_MAX_RAIL ) return; */ |
| 770 | pParent->aiRiser[pRow->iRail] = pRow->idx; |
| 771 | }else{ |
| 772 | /* Timewarp case: Child occurs earlier in time than parent and |
| 773 | ** appears below the parent in the timeline. */ |
| 774 | int iDownRail = ++p->mxRail; |
| 775 | if( iDownRail<1 ) iDownRail = ++p->mxRail; |
| 776 | if( p->mxRail>GR_MAX_RAIL ){ |
| 777 | iDownRail = p->mxRail = GR_MAX_RAIL; |
| 778 | p->bOverfull = 1; |
| 779 | } |
| 780 | pRow->iRail = ++p->mxRail; |
| 781 | if( p->mxRail>=GR_MAX_RAIL ){ |
| 782 | pRow->iRail = p->mxRail = GR_MAX_RAIL; |
| 783 | p->bOverfull = 1; |
| 784 | } |
| 785 | pRow->railInUse = BIT(pRow->iRail); |
| 786 | pParent->aiRiser[iDownRail] = pRow->idx; |
| 787 | mask = BIT(iDownRail); |
| 788 | for(pLoop=p->pFirst; pLoop; pLoop=pLoop->pNext){ |
| 789 | pLoop->railInUse |= mask; |
| @@ -824,11 +842,11 @@ | |
| 842 | break; |
| 843 | } |
| 844 | } |
| 845 | if( iMrail==-1 ){ |
| 846 | iMrail = findFreeRail(p, pRow->idx, p->pLast->idx, 0, 1); |
| 847 | /*if( p->mxRail>=GR_MAX_RAIL ) return;*/ |
| 848 | mergeRiserFrom[iMrail] = parentRid; |
| 849 | } |
| 850 | iReuseIdx = p->nRow+1; |
| 851 | iReuseRail = iMrail; |
| 852 | mask = BIT(iMrail); |
| @@ -856,11 +874,11 @@ | |
| 874 | pDesc->mergeUpto = pDesc->idx; |
| 875 | } |
| 876 | }else{ |
| 877 | /* Create a new merge for an on-screen node */ |
| 878 | createMergeRiser(p, pDesc, pRow, isCherrypick); |
| 879 | /* if( p->mxRail>=GR_MAX_RAIL ) return; */ |
| 880 | if( iReuseIdx<0 |
| 881 | && pDesc->nMergeChild==1 |
| 882 | && (pDesc->iRail!=pDesc->mergeOut || pDesc->isLeaf) |
| 883 | ){ |
| 884 | iReuseIdx = pDesc->idx; |
| @@ -872,17 +890,17 @@ | |
| 890 | } |
| 891 | |
| 892 | /* |
| 893 | ** Insert merge rails from primaries to duplicates. |
| 894 | */ |
| 895 | if( hasDup && p->mxRail<GR_MAX_RAIL ){ |
| 896 | int dupRail; |
| 897 | int mxRail; |
| 898 | find_max_rail(p); |
| 899 | mxRail = p->mxRail; |
| 900 | dupRail = mxRail+1; |
| 901 | /* if( p->mxRail>=GR_MAX_RAIL ) return; */ |
| 902 | for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ |
| 903 | if( !pRow->isDup ) continue; |
| 904 | pRow->iRail = dupRail; |
| 905 | pDesc = hashFind(p, pRow->rid); |
| 906 | assert( pDesc!=0 && pDesc!=pRow ); |
| @@ -893,11 +911,11 @@ | |
| 911 | dupRail = mxRail+1; |
| 912 | for(pRow=p->pFirst; pRow; pRow=pRow->pNext){ |
| 913 | if( pRow->isDup ) pRow->iRail = dupRail; |
| 914 | } |
| 915 | } |
| 916 | /* if( mxRail>=GR_MAX_RAIL ) return; */ |
| 917 | } |
| 918 | |
| 919 | /* |
| 920 | ** Find the maximum rail number. |
| 921 | */ |
| 922 |