Fossil SCM

Define a "leaf" as a check-in with no children in the same branch. The is_a_leaf() function does some complicated SQL to figure this out.

drh 2009-01-22 01:53 trunk
Commit faf09dc7ae5417fd4a8b09cc67c7c6ef9c9793a9
2 files changed +33 -14 +2 -30
+33 -14
--- src/checkin.c
+++ src/checkin.c
@@ -346,26 +346,45 @@
346346
g.aCommitFile[ii-2] = 0;
347347
}
348348
}
349349
350350
/*
351
-** Return true if the check-in with RID=rid has no child
352
-** check-ins which are not tagged with "newbranch". In other words,
353
-** return true if the check-in is a leaf.
351
+** Return true if the check-in with RID=rid is a leaf.
352
+**
353
+** A leaf has no children in the same branch. For the purposes of
354
+** this definition, a two check-ins are in same branch they have the
355
+** same set of propagated symbolic tags.
354356
*/
355357
int is_a_leaf(int rid){
356
- return !db_exists(
357
- "SELECT 1 FROM plink"
358
- " WHERE pid=%d"
359
- " AND NOT EXISTS("
360
- "SELECT 1 FROM tagxref"
361
- " WHERE tagxref.rid=plink.cid"
362
- " AND tagxref.tagid=%d"
363
- " AND tagxref.tagtype=1"
364
- ")",
365
- rid, TAG_NEWBRANCH
366
- );
358
+
359
+ /* This query selects all children in the same branch as rid */
360
+ static const char zSql[] =
361
+ @ SELECT cid FROM plink
362
+ @ WHERE pid=:rid
363
+ @ AND (SELECT group_concat(x) FROM (
364
+ @ SELECT tag.tagid AS x FROM tagxref, tag
365
+ @ WHERE tagxref.rid=:rid AND tagxref.tagtype=2
366
+ @ AND tag.tagid=tagxref.tagid AND tagxref.srcid=0
367
+ @ AND tag.tagname GLOB 'sym-*'
368
+ @ ORDER BY 1)
369
+ @ ) ==
370
+ @ (SELECT group_concat(x) FROM (
371
+ @ SELECT tag.tagid AS x FROM tagxref, tag
372
+ @ WHERE tagxref.rid=plink.cid AND tagxref.tagtype=2
373
+ @ AND tag.tagid=tagxref.tagid
374
+ @ AND tag.tagname GLOB 'sym-*'
375
+ @ ORDER BY 1)
376
+ @ )
377
+ ;
378
+ Stmt q; /* The prepared statement */
379
+ int rc; /* Return code from stepping the prepared statement */
380
+
381
+ db_prepare(&q, zSql);
382
+ db_bind_int(&q, ":rid", rid);
383
+ rc = db_step(&q);
384
+ db_finalize(&q);
385
+ return rc==SQLITE_DONE;
367386
}
368387
369388
/*
370389
** COMMAND: ci
371390
** COMMAND: commit
372391
--- src/checkin.c
+++ src/checkin.c
@@ -346,26 +346,45 @@
346 g.aCommitFile[ii-2] = 0;
347 }
348 }
349
350 /*
351 ** Return true if the check-in with RID=rid has no child
352 ** check-ins which are not tagged with "newbranch". In other words,
353 ** return true if the check-in is a leaf.
 
 
354 */
355 int is_a_leaf(int rid){
356 return !db_exists(
357 "SELECT 1 FROM plink"
358 " WHERE pid=%d"
359 " AND NOT EXISTS("
360 "SELECT 1 FROM tagxref"
361 " WHERE tagxref.rid=plink.cid"
362 " AND tagxref.tagid=%d"
363 " AND tagxref.tagtype=1"
364 ")",
365 rid, TAG_NEWBRANCH
366 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367 }
368
369 /*
370 ** COMMAND: ci
371 ** COMMAND: commit
372
--- src/checkin.c
+++ src/checkin.c
@@ -346,26 +346,45 @@
346 g.aCommitFile[ii-2] = 0;
347 }
348 }
349
350 /*
351 ** Return true if the check-in with RID=rid is a leaf.
352 **
353 ** A leaf has no children in the same branch. For the purposes of
354 ** this definition, a two check-ins are in same branch they have the
355 ** same set of propagated symbolic tags.
356 */
357 int is_a_leaf(int rid){
358
359 /* This query selects all children in the same branch as rid */
360 static const char zSql[] =
361 @ SELECT cid FROM plink
362 @ WHERE pid=:rid
363 @ AND (SELECT group_concat(x) FROM (
364 @ SELECT tag.tagid AS x FROM tagxref, tag
365 @ WHERE tagxref.rid=:rid AND tagxref.tagtype=2
366 @ AND tag.tagid=tagxref.tagid AND tagxref.srcid=0
367 @ AND tag.tagname GLOB 'sym-*'
368 @ ORDER BY 1)
369 @ ) ==
370 @ (SELECT group_concat(x) FROM (
371 @ SELECT tag.tagid AS x FROM tagxref, tag
372 @ WHERE tagxref.rid=plink.cid AND tagxref.tagtype=2
373 @ AND tag.tagid=tagxref.tagid
374 @ AND tag.tagname GLOB 'sym-*'
375 @ ORDER BY 1)
376 @ )
377 ;
378 Stmt q; /* The prepared statement */
379 int rc; /* Return code from stepping the prepared statement */
380
381 db_prepare(&q, zSql);
382 db_bind_int(&q, ":rid", rid);
383 rc = db_step(&q);
384 db_finalize(&q);
385 return rc==SQLITE_DONE;
386 }
387
388 /*
389 ** COMMAND: ci
390 ** COMMAND: commit
391
--- src/descendants.c
+++ src/descendants.c
@@ -62,11 +62,10 @@
6262
*/
6363
void compute_leaves(int iBase, int closeMode){
6464
Bag seen; /* Descendants seen */
6565
Bag pending; /* Unpropagated descendants */
6666
Stmt q1; /* Query to find children of a check-in */
67
- Stmt q2; /* Query to detect if a merge is across branches */
6867
Stmt isBr; /* Query to check to see if a check-in starts a new branch */
6968
Stmt ins; /* INSERT statement for a new record */
7069
7170
/* Create the LEAVES table if it does not already exist. Make sure
7271
** it is empty.
@@ -93,32 +92,10 @@
9392
bag_insert(&pending, iBase);
9493
9594
/* This query returns all non-merge children of check-in :rid */
9695
db_prepare(&q1, "SELECT cid FROM plink WHERE pid=:rid AND isprim");
9796
98
- /* This query returns all merge children of check-in :rid where
99
- ** the child and parent are on same branch. The child and
100
- ** parent are assumed to be on same branch if they have
101
- ** the same set of propagated symbolic tags.
102
- */
103
- db_prepare(&q2,
104
- "SELECT cid FROM plink"
105
- " WHERE pid=:rid AND NOT isprim"
106
- " AND (SELECT group_concat(x) FROM ("
107
- " SELECT tag.tagid AS x FROM tagxref, tag"
108
- " WHERE tagxref.rid=:rid AND tagxref.tagtype=2"
109
- " AND tag.tagid=tagxref.tagid AND tagxref.srcid=0"
110
- " AND tag.tagname GLOB 'sym-*'"
111
- " ORDER BY 1))"
112
- " == (SELECT group_concat(x) FROM ("
113
- " SELECT tag.tagid AS x FROM tagxref, tag"
114
- " WHERE tagxref.rid=plink.cid AND tagxref.tagtype=2"
115
- " AND tag.tagid=tagxref.tagid AND tagxref.srcid=0"
116
- " AND tag.tagname GLOB 'sym-*'"
117
- " ORDER BY 1))"
118
- );
119
-
12097
/* This query returns a single row if check-in :rid is the first
12198
** check-in of a new branch. In other words, it returns a row if
12299
** check-in :rid has the 'newbranch' tag.
123100
*/
124101
db_prepare(&isBr,
@@ -145,26 +122,21 @@
145122
cnt++;
146123
}
147124
db_reset(&isBr);
148125
}
149126
db_reset(&q1);
150
- if( cnt==0 ){
151
- db_bind_int(&q2, ":rid", rid);
152
- if( db_step(&q2)==SQLITE_ROW ){
153
- cnt++;
154
- }
155
- db_reset(&q2);
127
+ if( cnt==0 && !is_a_leaf(rid) ){
128
+ cnt++;
156129
}
157130
if( cnt==0 ){
158131
db_bind_int(&ins, ":rid", rid);
159132
db_step(&ins);
160133
db_reset(&ins);
161134
}
162135
}
163136
db_finalize(&ins);
164137
db_finalize(&isBr);
165
- db_finalize(&q2);
166138
db_finalize(&q1);
167139
bag_clear(&pending);
168140
bag_clear(&seen);
169141
if( closeMode==1 ){
170142
db_multi_exec(
171143
--- src/descendants.c
+++ src/descendants.c
@@ -62,11 +62,10 @@
62 */
63 void compute_leaves(int iBase, int closeMode){
64 Bag seen; /* Descendants seen */
65 Bag pending; /* Unpropagated descendants */
66 Stmt q1; /* Query to find children of a check-in */
67 Stmt q2; /* Query to detect if a merge is across branches */
68 Stmt isBr; /* Query to check to see if a check-in starts a new branch */
69 Stmt ins; /* INSERT statement for a new record */
70
71 /* Create the LEAVES table if it does not already exist. Make sure
72 ** it is empty.
@@ -93,32 +92,10 @@
93 bag_insert(&pending, iBase);
94
95 /* This query returns all non-merge children of check-in :rid */
96 db_prepare(&q1, "SELECT cid FROM plink WHERE pid=:rid AND isprim");
97
98 /* This query returns all merge children of check-in :rid where
99 ** the child and parent are on same branch. The child and
100 ** parent are assumed to be on same branch if they have
101 ** the same set of propagated symbolic tags.
102 */
103 db_prepare(&q2,
104 "SELECT cid FROM plink"
105 " WHERE pid=:rid AND NOT isprim"
106 " AND (SELECT group_concat(x) FROM ("
107 " SELECT tag.tagid AS x FROM tagxref, tag"
108 " WHERE tagxref.rid=:rid AND tagxref.tagtype=2"
109 " AND tag.tagid=tagxref.tagid AND tagxref.srcid=0"
110 " AND tag.tagname GLOB 'sym-*'"
111 " ORDER BY 1))"
112 " == (SELECT group_concat(x) FROM ("
113 " SELECT tag.tagid AS x FROM tagxref, tag"
114 " WHERE tagxref.rid=plink.cid AND tagxref.tagtype=2"
115 " AND tag.tagid=tagxref.tagid AND tagxref.srcid=0"
116 " AND tag.tagname GLOB 'sym-*'"
117 " ORDER BY 1))"
118 );
119
120 /* This query returns a single row if check-in :rid is the first
121 ** check-in of a new branch. In other words, it returns a row if
122 ** check-in :rid has the 'newbranch' tag.
123 */
124 db_prepare(&isBr,
@@ -145,26 +122,21 @@
145 cnt++;
146 }
147 db_reset(&isBr);
148 }
149 db_reset(&q1);
150 if( cnt==0 ){
151 db_bind_int(&q2, ":rid", rid);
152 if( db_step(&q2)==SQLITE_ROW ){
153 cnt++;
154 }
155 db_reset(&q2);
156 }
157 if( cnt==0 ){
158 db_bind_int(&ins, ":rid", rid);
159 db_step(&ins);
160 db_reset(&ins);
161 }
162 }
163 db_finalize(&ins);
164 db_finalize(&isBr);
165 db_finalize(&q2);
166 db_finalize(&q1);
167 bag_clear(&pending);
168 bag_clear(&seen);
169 if( closeMode==1 ){
170 db_multi_exec(
171
--- src/descendants.c
+++ src/descendants.c
@@ -62,11 +62,10 @@
62 */
63 void compute_leaves(int iBase, int closeMode){
64 Bag seen; /* Descendants seen */
65 Bag pending; /* Unpropagated descendants */
66 Stmt q1; /* Query to find children of a check-in */
 
67 Stmt isBr; /* Query to check to see if a check-in starts a new branch */
68 Stmt ins; /* INSERT statement for a new record */
69
70 /* Create the LEAVES table if it does not already exist. Make sure
71 ** it is empty.
@@ -93,32 +92,10 @@
92 bag_insert(&pending, iBase);
93
94 /* This query returns all non-merge children of check-in :rid */
95 db_prepare(&q1, "SELECT cid FROM plink WHERE pid=:rid AND isprim");
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97 /* This query returns a single row if check-in :rid is the first
98 ** check-in of a new branch. In other words, it returns a row if
99 ** check-in :rid has the 'newbranch' tag.
100 */
101 db_prepare(&isBr,
@@ -145,26 +122,21 @@
122 cnt++;
123 }
124 db_reset(&isBr);
125 }
126 db_reset(&q1);
127 if( cnt==0 && !is_a_leaf(rid) ){
128 cnt++;
 
 
 
 
129 }
130 if( cnt==0 ){
131 db_bind_int(&ins, ":rid", rid);
132 db_step(&ins);
133 db_reset(&ins);
134 }
135 }
136 db_finalize(&ins);
137 db_finalize(&isBr);
 
138 db_finalize(&q1);
139 bag_clear(&pending);
140 bag_clear(&seen);
141 if( closeMode==1 ){
142 db_multi_exec(
143

Keyboard Shortcuts

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