Fossil SCM

Change the definition of a "Leaf" to be any node that has no children of any kind (merge or non-merge) in the same branch. A "rebuild" or a "fossil leaves --recompute" is required to recompute the LEAF table after upgrading to this version.

drh 2011-04-25 22:23 trunk
Commit e17fc71319e0534b3c5bf2df9754bc6933c909dd
--- src/checkin.c
+++ src/checkin.c
@@ -466,29 +466,10 @@
466466
}
467467
g.aCommitFile[ii-2] = 0;
468468
}
469469
}
470470
471
-/*
472
-** Return true if the check-in with RID=rid is a leaf.
473
-** A leaf has no primary children in the same branch.
474
-*/
475
-int is_a_leaf(int rid){
476
- int rc;
477
- static const char zSql[] =
478
- @ SELECT 1 FROM plink
479
- @ WHERE pid=%d
480
- @ AND coalesce((SELECT value FROM tagxref
481
- @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
482
- @ =coalesce((SELECT value FROM tagxref
483
- @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
484
- @ AND isprim
485
- ;
486
- rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
487
- return rc==0;
488
-}
489
-
490471
/*
491472
** Make sure the current check-in with timestamp zDate is younger than its
492473
** ancestor identified rid and zUuid. Throw a fatal error if not.
493474
*/
494475
static void checkin_verify_younger(
495476
--- src/checkin.c
+++ src/checkin.c
@@ -466,29 +466,10 @@
466 }
467 g.aCommitFile[ii-2] = 0;
468 }
469 }
470
471 /*
472 ** Return true if the check-in with RID=rid is a leaf.
473 ** A leaf has no primary children in the same branch.
474 */
475 int is_a_leaf(int rid){
476 int rc;
477 static const char zSql[] =
478 @ SELECT 1 FROM plink
479 @ WHERE pid=%d
480 @ AND coalesce((SELECT value FROM tagxref
481 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
482 @ =coalesce((SELECT value FROM tagxref
483 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
484 @ AND isprim
485 ;
486 rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
487 return rc==0;
488 }
489
490 /*
491 ** Make sure the current check-in with timestamp zDate is younger than its
492 ** ancestor identified rid and zUuid. Throw a fatal error if not.
493 */
494 static void checkin_verify_younger(
495
--- src/checkin.c
+++ src/checkin.c
@@ -466,29 +466,10 @@
466 }
467 g.aCommitFile[ii-2] = 0;
468 }
469 }
470
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
471 /*
472 ** Make sure the current check-in with timestamp zDate is younger than its
473 ** ancestor identified rid and zUuid. Throw a fatal error if not.
474 */
475 static void checkin_verify_younger(
476
+1 -1
--- src/graph.c
+++ src/graph.c
@@ -422,11 +422,11 @@
422422
for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
423423
int parentRid;
424424
425425
if( pRow->iRail>=0 ){
426426
if( pRow->pChild==0 && !pRow->timeWarp ){
427
- if( pRow->isLeaf || omitDescenders ){
427
+ if( omitDescenders || count_nonbranch_children(pRow->rid)==0 ){
428428
inUse &= ~(1<<pRow->iRail);
429429
}else{
430430
pRow->aiRiser[pRow->iRail] = 0;
431431
mask = 1<<pRow->iRail;
432432
for(pLoop=pRow; pLoop; pLoop=pLoop->pPrev){
433433
--- src/graph.c
+++ src/graph.c
@@ -422,11 +422,11 @@
422 for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
423 int parentRid;
424
425 if( pRow->iRail>=0 ){
426 if( pRow->pChild==0 && !pRow->timeWarp ){
427 if( pRow->isLeaf || omitDescenders ){
428 inUse &= ~(1<<pRow->iRail);
429 }else{
430 pRow->aiRiser[pRow->iRail] = 0;
431 mask = 1<<pRow->iRail;
432 for(pLoop=pRow; pLoop; pLoop=pLoop->pPrev){
433
--- src/graph.c
+++ src/graph.c
@@ -422,11 +422,11 @@
422 for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
423 int parentRid;
424
425 if( pRow->iRail>=0 ){
426 if( pRow->pChild==0 && !pRow->timeWarp ){
427 if( omitDescenders || count_nonbranch_children(pRow->rid)==0 ){
428 inUse &= ~(1<<pRow->iRail);
429 }else{
430 pRow->aiRiser[pRow->iRail] = 0;
431 mask = 1<<pRow->iRail;
432 for(pLoop=pRow; pLoop; pLoop=pLoop->pPrev){
433
+1 -1
--- src/info.c
+++ src/info.c
@@ -368,11 +368,11 @@
368368
zParent = db_text(0,
369369
"SELECT uuid FROM plink, blob"
370370
" WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim",
371371
rid
372372
);
373
- isLeaf = !db_exists("SELECT 1 FROM plink WHERE pid=%d", rid);
373
+ isLeaf = is_a_leaf(rid);
374374
db_prepare(&q,
375375
"SELECT uuid, datetime(mtime, 'localtime'), user, comment,"
376376
" datetime(omtime, 'localtime')"
377377
" FROM blob, event"
378378
" WHERE blob.rid=%d"
379379
--- src/info.c
+++ src/info.c
@@ -368,11 +368,11 @@
368 zParent = db_text(0,
369 "SELECT uuid FROM plink, blob"
370 " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim",
371 rid
372 );
373 isLeaf = !db_exists("SELECT 1 FROM plink WHERE pid=%d", rid);
374 db_prepare(&q,
375 "SELECT uuid, datetime(mtime, 'localtime'), user, comment,"
376 " datetime(omtime, 'localtime')"
377 " FROM blob, event"
378 " WHERE blob.rid=%d"
379
--- src/info.c
+++ src/info.c
@@ -368,11 +368,11 @@
368 zParent = db_text(0,
369 "SELECT uuid FROM plink, blob"
370 " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim",
371 rid
372 );
373 isLeaf = is_a_leaf(rid);
374 db_prepare(&q,
375 "SELECT uuid, datetime(mtime, 'localtime'), user, comment,"
376 " datetime(omtime, 'localtime')"
377 " FROM blob, event"
378 " WHERE blob.rid=%d"
379
+51 -3
--- src/leaf.c
+++ src/leaf.c
@@ -23,10 +23,59 @@
2323
*/
2424
#include "config.h"
2525
#include "leaf.h"
2626
#include <assert.h>
2727
28
+
29
+/*
30
+** Return true if the check-in with RID=rid is a leaf.
31
+**
32
+** A leaf has no children in the same branch.
33
+*/
34
+int is_a_leaf(int rid){
35
+ int rc;
36
+ static const char zSql[] =
37
+ @ SELECT 1 FROM plink
38
+ @ WHERE pid=%d
39
+ @ AND coalesce((SELECT value FROM tagxref
40
+ @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
41
+ @ =coalesce((SELECT value FROM tagxref
42
+ @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
43
+ ;
44
+ rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
45
+ return rc==0;
46
+}
47
+
48
+/*
49
+** Count the number of primary non-branch children for the given check-in.
50
+**
51
+** A primary child is one where the parent is the primary parent, not
52
+** a merge parent. A "leaf" is a node that has zero children of any
53
+** kind. This routine counts only primary children.
54
+**
55
+** A non-branch child is one which is on the same branch as the parent.
56
+*/
57
+int count_nonbranch_children(int pid){
58
+ int nNonBranch = 0;
59
+ static Stmt q;
60
+ static const char zSql[] =
61
+ @ SELECT count(*) FROM plink
62
+ @ WHERE pid=:pid AND isprim
63
+ @ AND coalesce((SELECT value FROM tagxref
64
+ @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
65
+ @ =coalesce((SELECT value FROM tagxref
66
+ @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
67
+ ;
68
+ db_static_prepare(&q, zSql, TAG_BRANCH, TAG_BRANCH);
69
+ db_bind_int(&q, ":pid", pid);
70
+ if( db_step(&q)==SQLITE_ROW ){
71
+ nNonBranch = db_column_int(&q, 0);
72
+ }
73
+ db_reset(&q);
74
+ return nNonBranch;
75
+}
76
+
2877
2978
/*
3079
** Recompute the entire LEAF table.
3180
**
3281
** This can be expensive (5 seconds or so) for a really large repository.
@@ -40,12 +89,11 @@
4089
" EXCEPT"
4190
" SELECT pid FROM plink"
4291
" WHERE coalesce((SELECT value FROM tagxref"
4392
" WHERE tagid=%d AND rid=plink.pid),'trunk')"
4493
" == coalesce((SELECT value FROM tagxref"
45
- " WHERE tagid=%d AND rid=plink.cid),'trunk')"
46
- " AND isprim",
94
+ " WHERE tagid=%d AND rid=plink.cid),'trunk')",
4795
TAG_BRANCH, TAG_BRANCH
4896
);
4997
}
5098
5199
/*
@@ -63,11 +111,11 @@
63111
static Stmt removeLeaf;
64112
int rc;
65113
66114
db_static_prepare(&checkIfLeaf,
67115
"SELECT 1 FROM plink"
68
- " WHERE pid=:rid AND isprim"
116
+ " WHERE pid=:rid"
69117
" AND coalesce((SELECT value FROM tagxref"
70118
" WHERE tagid=%d AND rid=:rid),'trunk')"
71119
" == coalesce((SELECT value FROM tagxref"
72120
" WHERE tagid=%d AND rid=plink.cid),'trunk');",
73121
TAG_BRANCH, TAG_BRANCH
74122
--- src/leaf.c
+++ src/leaf.c
@@ -23,10 +23,59 @@
23 */
24 #include "config.h"
25 #include "leaf.h"
26 #include <assert.h>
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
29 /*
30 ** Recompute the entire LEAF table.
31 **
32 ** This can be expensive (5 seconds or so) for a really large repository.
@@ -40,12 +89,11 @@
40 " EXCEPT"
41 " SELECT pid FROM plink"
42 " WHERE coalesce((SELECT value FROM tagxref"
43 " WHERE tagid=%d AND rid=plink.pid),'trunk')"
44 " == coalesce((SELECT value FROM tagxref"
45 " WHERE tagid=%d AND rid=plink.cid),'trunk')"
46 " AND isprim",
47 TAG_BRANCH, TAG_BRANCH
48 );
49 }
50
51 /*
@@ -63,11 +111,11 @@
63 static Stmt removeLeaf;
64 int rc;
65
66 db_static_prepare(&checkIfLeaf,
67 "SELECT 1 FROM plink"
68 " WHERE pid=:rid AND isprim"
69 " AND coalesce((SELECT value FROM tagxref"
70 " WHERE tagid=%d AND rid=:rid),'trunk')"
71 " == coalesce((SELECT value FROM tagxref"
72 " WHERE tagid=%d AND rid=plink.cid),'trunk');",
73 TAG_BRANCH, TAG_BRANCH
74
--- src/leaf.c
+++ src/leaf.c
@@ -23,10 +23,59 @@
23 */
24 #include "config.h"
25 #include "leaf.h"
26 #include <assert.h>
27
28
29 /*
30 ** Return true if the check-in with RID=rid is a leaf.
31 **
32 ** A leaf has no children in the same branch.
33 */
34 int is_a_leaf(int rid){
35 int rc;
36 static const char zSql[] =
37 @ SELECT 1 FROM plink
38 @ WHERE pid=%d
39 @ AND coalesce((SELECT value FROM tagxref
40 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
41 @ =coalesce((SELECT value FROM tagxref
42 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
43 ;
44 rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
45 return rc==0;
46 }
47
48 /*
49 ** Count the number of primary non-branch children for the given check-in.
50 **
51 ** A primary child is one where the parent is the primary parent, not
52 ** a merge parent. A "leaf" is a node that has zero children of any
53 ** kind. This routine counts only primary children.
54 **
55 ** A non-branch child is one which is on the same branch as the parent.
56 */
57 int count_nonbranch_children(int pid){
58 int nNonBranch = 0;
59 static Stmt q;
60 static const char zSql[] =
61 @ SELECT count(*) FROM plink
62 @ WHERE pid=:pid AND isprim
63 @ AND coalesce((SELECT value FROM tagxref
64 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
65 @ =coalesce((SELECT value FROM tagxref
66 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
67 ;
68 db_static_prepare(&q, zSql, TAG_BRANCH, TAG_BRANCH);
69 db_bind_int(&q, ":pid", pid);
70 if( db_step(&q)==SQLITE_ROW ){
71 nNonBranch = db_column_int(&q, 0);
72 }
73 db_reset(&q);
74 return nNonBranch;
75 }
76
77
78 /*
79 ** Recompute the entire LEAF table.
80 **
81 ** This can be expensive (5 seconds or so) for a really large repository.
@@ -40,12 +89,11 @@
89 " EXCEPT"
90 " SELECT pid FROM plink"
91 " WHERE coalesce((SELECT value FROM tagxref"
92 " WHERE tagid=%d AND rid=plink.pid),'trunk')"
93 " == coalesce((SELECT value FROM tagxref"
94 " WHERE tagid=%d AND rid=plink.cid),'trunk')",
 
95 TAG_BRANCH, TAG_BRANCH
96 );
97 }
98
99 /*
@@ -63,11 +111,11 @@
111 static Stmt removeLeaf;
112 int rc;
113
114 db_static_prepare(&checkIfLeaf,
115 "SELECT 1 FROM plink"
116 " WHERE pid=:rid"
117 " AND coalesce((SELECT value FROM tagxref"
118 " WHERE tagid=%d AND rid=:rid),'trunk')"
119 " == coalesce((SELECT value FROM tagxref"
120 " WHERE tagid=%d AND rid=plink.cid),'trunk');",
121 TAG_BRANCH, TAG_BRANCH
122
+2 -2
--- src/name.c
+++ src/name.c
@@ -201,12 +201,12 @@
201201
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid="
202202
"(SELECT pid FROM plink WHERE cid=%d AND isprim)",
203203
vid);
204204
}else if( fossil_strcmp(zTag, "next")==0 ){
205205
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid="
206
- "(SELECT cid FROM plink WHERE pid=%d AND isprim"
207
- " ORDER BY mtime DESC)",
206
+ "(SELECT cid FROM plink WHERE pid=%d"
207
+ " ORDER BY isprim DESC, mtime DESC)",
208208
vid);
209209
}
210210
}
211211
}
212212
return zUuid;
213213
--- src/name.c
+++ src/name.c
@@ -201,12 +201,12 @@
201 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid="
202 "(SELECT pid FROM plink WHERE cid=%d AND isprim)",
203 vid);
204 }else if( fossil_strcmp(zTag, "next")==0 ){
205 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid="
206 "(SELECT cid FROM plink WHERE pid=%d AND isprim"
207 " ORDER BY mtime DESC)",
208 vid);
209 }
210 }
211 }
212 return zUuid;
213
--- src/name.c
+++ src/name.c
@@ -201,12 +201,12 @@
201 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid="
202 "(SELECT pid FROM plink WHERE cid=%d AND isprim)",
203 vid);
204 }else if( fossil_strcmp(zTag, "next")==0 ){
205 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid="
206 "(SELECT cid FROM plink WHERE pid=%d"
207 " ORDER BY isprim DESC, mtime DESC)",
208 vid);
209 }
210 }
211 }
212 return zUuid;
213
--- src/timeline.c
+++ src/timeline.c
@@ -97,32 +97,10 @@
9797
}else{
9898
@ %s(zU)
9999
}
100100
}
101101
102
-/*
103
-** Count the number of primary non-branch children for the given check-in.
104
-**
105
-** A primary child is one where the parent is the primary parent, not
106
-** a merge parent.
107
-**
108
-** A non-branch child is one which is on the same branch as the parent.
109
-*/
110
-int count_nonbranch_children(int pid){
111
- int nNonBranch;
112
- static const char zSql[] =
113
- @ SELECT count(*) FROM plink
114
- @ WHERE pid=%d AND isprim
115
- @ AND coalesce((SELECT value FROM tagxref
116
- @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
117
- @ =coalesce((SELECT value FROM tagxref
118
- @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
119
- ;
120
- nNonBranch = db_int(0, zSql, pid, TAG_BRANCH, TAG_BRANCH);
121
- return nNonBranch;
122
-}
123
-
124102
/*
125103
** Allowed flags for the tmFlags argument to www_print_timeline
126104
*/
127105
#if INTERFACE
128106
#define TIMELINE_ARTID 0x0001 /* Show artifact IDs on non-check-in lines */
129107
--- src/timeline.c
+++ src/timeline.c
@@ -97,32 +97,10 @@
97 }else{
98 @ %s(zU)
99 }
100 }
101
102 /*
103 ** Count the number of primary non-branch children for the given check-in.
104 **
105 ** A primary child is one where the parent is the primary parent, not
106 ** a merge parent.
107 **
108 ** A non-branch child is one which is on the same branch as the parent.
109 */
110 int count_nonbranch_children(int pid){
111 int nNonBranch;
112 static const char zSql[] =
113 @ SELECT count(*) FROM plink
114 @ WHERE pid=%d AND isprim
115 @ AND coalesce((SELECT value FROM tagxref
116 @ WHERE tagid=%d AND rid=plink.pid), 'trunk')
117 @ =coalesce((SELECT value FROM tagxref
118 @ WHERE tagid=%d AND rid=plink.cid), 'trunk')
119 ;
120 nNonBranch = db_int(0, zSql, pid, TAG_BRANCH, TAG_BRANCH);
121 return nNonBranch;
122 }
123
124 /*
125 ** Allowed flags for the tmFlags argument to www_print_timeline
126 */
127 #if INTERFACE
128 #define TIMELINE_ARTID 0x0001 /* Show artifact IDs on non-check-in lines */
129
--- src/timeline.c
+++ src/timeline.c
@@ -97,32 +97,10 @@
97 }else{
98 @ %s(zU)
99 }
100 }
101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102 /*
103 ** Allowed flags for the tmFlags argument to www_print_timeline
104 */
105 #if INTERFACE
106 #define TIMELINE_ARTID 0x0001 /* Show artifact IDs on non-check-in lines */
107
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -60,11 +60,13 @@
6060
target="testwindow">
6161
From e663bac6f7 to a298a0e2f9 without merge links.</a>
6262
* <a href="../../../timeline?me=e663bac6f7&you=a298a0e2f9"
6363
target="testwindow">
6464
Common ancestor path of e663bac6f7 to a298a0e2f9.</a>
65
-
65
+ * <a href="../../../timeline?f=65dd90fb95a2af55">
66
+ Merge on the same branch does not result in a leaf.
67
+ </a>
6668
6769
External:
6870
6971
* <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
7072
target="testwindow">Timewarp due to a mis-configured system clock.</a>
7173
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -60,11 +60,13 @@
60 target="testwindow">
61 From e663bac6f7 to a298a0e2f9 without merge links.</a>
62 * <a href="../../../timeline?me=e663bac6f7&you=a298a0e2f9"
63 target="testwindow">
64 Common ancestor path of e663bac6f7 to a298a0e2f9.</a>
65
 
 
66
67 External:
68
69 * <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
70 target="testwindow">Timewarp due to a mis-configured system clock.</a>
71
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -60,11 +60,13 @@
60 target="testwindow">
61 From e663bac6f7 to a298a0e2f9 without merge links.</a>
62 * <a href="../../../timeline?me=e663bac6f7&you=a298a0e2f9"
63 target="testwindow">
64 Common ancestor path of e663bac6f7 to a298a0e2f9.</a>
65 * <a href="../../../timeline?f=65dd90fb95a2af55">
66 Merge on the same branch does not result in a leaf.
67 </a>
68
69 External:
70
71 * <a href="http://www.sqlite.org/src/timeline?c=2010-09-29&nd"
72 target="testwindow">Timewarp due to a mis-configured system clock.</a>
73

Keyboard Shortcuts

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