Fossil SCM

Faster resolution of common symbolic tags such as "trunk".

drh 2021-01-08 15:16 trunk
Commit fdeebddea7abf6addf1640da01804f230e9a10c2b081b0aafdcac1642d0412ba
1 file changed +56 -22
+56 -22
--- src/name.c
+++ src/name.c
@@ -181,10 +181,53 @@
181181
ans = compute_youngest_ancestor_in_branch(rid, zBr);
182182
fossil_free(zBr);
183183
}
184184
return ans;
185185
}
186
+
187
+/*
188
+** Find the RID of the most recent object with symbolic tag zTag
189
+** and having a type that matches zType.
190
+**
191
+** Return 0 if there are no matches.
192
+**
193
+** This is a tricky query to do efficiently.
194
+** If the tag is very common (ex: "trunk") then
195
+** we want to use the query identified below as Q1 - which searching
196
+** the most recent EVENT table entries for the most recent with the tag.
197
+** But if the tag is relatively scarce (anything other than "trunk", basically)
198
+** then we want to do the indexed search show below as Q2.
199
+*/
200
+static int most_recent_event_with_tag(const char *zTag, const char *zType){
201
+ return db_int(0,
202
+ "SELECT objid FROM ("
203
+ /* Q1: Begin by looking for the tag in the 30 most recent events */
204
+ "SELECT objid"
205
+ " FROM (SELECT * FROM event ORDER BY mtime DESC LIMIT 30) AS ex"
206
+ " WHERE type GLOB '%q'"
207
+ " AND EXISTS(SELECT 1 FROM tagxref, tag"
208
+ " WHERE tag.tagname='sym-%q'"
209
+ " AND tagxref.tagid=tag.tagid"
210
+ " AND tagxref.tagtype>0"
211
+ " AND tagxref.rid=ex.objid)"
212
+ " ORDER BY mtime DESC LIMIT 1"
213
+ ") UNION ALL SELECT * FROM ("
214
+ /* Q2: If the tag is not found in the 30 most recent events, then using
215
+ ** the tagxref table to index for the tag */
216
+ "SELECT event.objid"
217
+ " FROM tag, tagxref, event"
218
+ " WHERE tag.tagname='sym-%q'"
219
+ " AND tagxref.tagid=tag.tagid"
220
+ " AND tagxref.tagtype>0"
221
+ " AND event.objid=tagxref.rid"
222
+ " AND event.type GLOB '%q'"
223
+ " ORDER BY event.mtime DESC LIMIT 1"
224
+ ") LIMIT 1;",
225
+ zType, zTag, zTag, zType
226
+ );
227
+}
228
+
186229
187230
/*
188231
** Convert a symbolic name into a RID. Acceptable forms:
189232
**
190233
** * artifact hash (optionally enclosed in [...])
@@ -225,11 +268,10 @@
225268
int i;
226269
int startOfBranch = 0;
227270
const char *zXTag; /* zTag with optional [...] removed */
228271
int nXTag; /* Size of zXTag */
229272
const char *zDate; /* Expanded date-time string */
230
- const char *zTagPrefix = "sym";
231273
232274
if( zType==0 || zType[0]==0 ){
233275
zType = "*";
234276
}else if( zType[0]=='b' ){
235277
zType = "ci";
@@ -301,19 +343,11 @@
301343
return rid;
302344
}
303345
304346
/* "tag:" + symbolic-name */
305347
if( memcmp(zTag, "tag:", 4)==0 ){
306
- rid = db_int(0,
307
- "SELECT event.objid, max(event.mtime)"
308
- " FROM tag, tagxref, event"
309
- " WHERE tag.tagname='sym-%q' "
310
- " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
311
- " AND event.objid=tagxref.rid "
312
- " AND event.type GLOB '%q'",
313
- &zTag[4], zType
314
- );
348
+ rid = most_recent_event_with_tag(&zTag[4], zType);
315349
if( startOfBranch ) rid = start_of_branch(rid,1);
316350
return rid;
317351
}
318352
319353
/* root:BR -> The origin of the branch named BR */
@@ -396,22 +430,22 @@
396430
db_finalize(&q);
397431
if( rid ) return rid;
398432
}
399433
400434
if( zType[0]=='w' ){
401
- zTagPrefix = "wiki";
402
- }
403
- /* Symbolic name */
404
- rid = db_int(0,
405
- "SELECT event.objid, max(event.mtime)"
406
- " FROM tag, tagxref, event"
407
- " WHERE tag.tagname='%q-%q' "
408
- " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
409
- " AND event.objid=tagxref.rid "
410
- " AND event.type GLOB '%q'",
411
- zTagPrefix, zTag, zType
412
- );
435
+ rid = db_int(0,
436
+ "SELECT event.objid, max(event.mtime)"
437
+ " FROM tag, tagxref, event"
438
+ " WHERE tag.tagname='wiki-%q' "
439
+ " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
440
+ " AND event.objid=tagxref.rid "
441
+ " AND event.type GLOB '%q'",
442
+ zTag, zType
443
+ );
444
+ }else{
445
+ rid = most_recent_event_with_tag(zTag, zType);
446
+ }
413447
414448
if( rid>0 ){
415449
if( startOfBranch ) rid = start_of_branch(rid,1);
416450
return rid;
417451
}
418452
--- src/name.c
+++ src/name.c
@@ -181,10 +181,53 @@
181 ans = compute_youngest_ancestor_in_branch(rid, zBr);
182 fossil_free(zBr);
183 }
184 return ans;
185 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
187 /*
188 ** Convert a symbolic name into a RID. Acceptable forms:
189 **
190 ** * artifact hash (optionally enclosed in [...])
@@ -225,11 +268,10 @@
225 int i;
226 int startOfBranch = 0;
227 const char *zXTag; /* zTag with optional [...] removed */
228 int nXTag; /* Size of zXTag */
229 const char *zDate; /* Expanded date-time string */
230 const char *zTagPrefix = "sym";
231
232 if( zType==0 || zType[0]==0 ){
233 zType = "*";
234 }else if( zType[0]=='b' ){
235 zType = "ci";
@@ -301,19 +343,11 @@
301 return rid;
302 }
303
304 /* "tag:" + symbolic-name */
305 if( memcmp(zTag, "tag:", 4)==0 ){
306 rid = db_int(0,
307 "SELECT event.objid, max(event.mtime)"
308 " FROM tag, tagxref, event"
309 " WHERE tag.tagname='sym-%q' "
310 " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
311 " AND event.objid=tagxref.rid "
312 " AND event.type GLOB '%q'",
313 &zTag[4], zType
314 );
315 if( startOfBranch ) rid = start_of_branch(rid,1);
316 return rid;
317 }
318
319 /* root:BR -> The origin of the branch named BR */
@@ -396,22 +430,22 @@
396 db_finalize(&q);
397 if( rid ) return rid;
398 }
399
400 if( zType[0]=='w' ){
401 zTagPrefix = "wiki";
402 }
403 /* Symbolic name */
404 rid = db_int(0,
405 "SELECT event.objid, max(event.mtime)"
406 " FROM tag, tagxref, event"
407 " WHERE tag.tagname='%q-%q' "
408 " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
409 " AND event.objid=tagxref.rid "
410 " AND event.type GLOB '%q'",
411 zTagPrefix, zTag, zType
412 );
413
414 if( rid>0 ){
415 if( startOfBranch ) rid = start_of_branch(rid,1);
416 return rid;
417 }
418
--- src/name.c
+++ src/name.c
@@ -181,10 +181,53 @@
181 ans = compute_youngest_ancestor_in_branch(rid, zBr);
182 fossil_free(zBr);
183 }
184 return ans;
185 }
186
187 /*
188 ** Find the RID of the most recent object with symbolic tag zTag
189 ** and having a type that matches zType.
190 **
191 ** Return 0 if there are no matches.
192 **
193 ** This is a tricky query to do efficiently.
194 ** If the tag is very common (ex: "trunk") then
195 ** we want to use the query identified below as Q1 - which searching
196 ** the most recent EVENT table entries for the most recent with the tag.
197 ** But if the tag is relatively scarce (anything other than "trunk", basically)
198 ** then we want to do the indexed search show below as Q2.
199 */
200 static int most_recent_event_with_tag(const char *zTag, const char *zType){
201 return db_int(0,
202 "SELECT objid FROM ("
203 /* Q1: Begin by looking for the tag in the 30 most recent events */
204 "SELECT objid"
205 " FROM (SELECT * FROM event ORDER BY mtime DESC LIMIT 30) AS ex"
206 " WHERE type GLOB '%q'"
207 " AND EXISTS(SELECT 1 FROM tagxref, tag"
208 " WHERE tag.tagname='sym-%q'"
209 " AND tagxref.tagid=tag.tagid"
210 " AND tagxref.tagtype>0"
211 " AND tagxref.rid=ex.objid)"
212 " ORDER BY mtime DESC LIMIT 1"
213 ") UNION ALL SELECT * FROM ("
214 /* Q2: If the tag is not found in the 30 most recent events, then using
215 ** the tagxref table to index for the tag */
216 "SELECT event.objid"
217 " FROM tag, tagxref, event"
218 " WHERE tag.tagname='sym-%q'"
219 " AND tagxref.tagid=tag.tagid"
220 " AND tagxref.tagtype>0"
221 " AND event.objid=tagxref.rid"
222 " AND event.type GLOB '%q'"
223 " ORDER BY event.mtime DESC LIMIT 1"
224 ") LIMIT 1;",
225 zType, zTag, zTag, zType
226 );
227 }
228
229
230 /*
231 ** Convert a symbolic name into a RID. Acceptable forms:
232 **
233 ** * artifact hash (optionally enclosed in [...])
@@ -225,11 +268,10 @@
268 int i;
269 int startOfBranch = 0;
270 const char *zXTag; /* zTag with optional [...] removed */
271 int nXTag; /* Size of zXTag */
272 const char *zDate; /* Expanded date-time string */
 
273
274 if( zType==0 || zType[0]==0 ){
275 zType = "*";
276 }else if( zType[0]=='b' ){
277 zType = "ci";
@@ -301,19 +343,11 @@
343 return rid;
344 }
345
346 /* "tag:" + symbolic-name */
347 if( memcmp(zTag, "tag:", 4)==0 ){
348 rid = most_recent_event_with_tag(&zTag[4], zType);
 
 
 
 
 
 
 
 
349 if( startOfBranch ) rid = start_of_branch(rid,1);
350 return rid;
351 }
352
353 /* root:BR -> The origin of the branch named BR */
@@ -396,22 +430,22 @@
430 db_finalize(&q);
431 if( rid ) return rid;
432 }
433
434 if( zType[0]=='w' ){
435 rid = db_int(0,
436 "SELECT event.objid, max(event.mtime)"
437 " FROM tag, tagxref, event"
438 " WHERE tag.tagname='wiki-%q' "
439 " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
440 " AND event.objid=tagxref.rid "
441 " AND event.type GLOB '%q'",
442 zTag, zType
443 );
444 }else{
445 rid = most_recent_event_with_tag(zTag, zType);
446 }
447
448 if( rid>0 ){
449 if( startOfBranch ) rid = start_of_branch(rid,1);
450 return rid;
451 }
452

Keyboard Shortcuts

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