Fossil SCM
Improvements to the "annotate" algorithm: Only search primary ancestors; ignore branchs.
Commit
621be704940afeef6d02c3615c07a2ee4f54edfc
Parent
fbf417b681c35b9…
2 files changed
+35
+8
-7
+35
| --- src/descendants.c | ||
| +++ src/descendants.c | ||
| @@ -186,10 +186,45 @@ | ||
| 186 | 186 | } |
| 187 | 187 | db_reset(&q); |
| 188 | 188 | } |
| 189 | 189 | bag_clear(&seen); |
| 190 | 190 | pqueue_clear(&queue); |
| 191 | + db_finalize(&ins); | |
| 192 | + db_finalize(&q); | |
| 193 | +} | |
| 194 | + | |
| 195 | +/* | |
| 196 | +** Compute up to N direct ancestors (merge ancestors do not count) | |
| 197 | +** for the check-in rid and put them in a table named "ancestor". | |
| 198 | +** Label each generation with consecutive integers going backwards | |
| 199 | +** in time such that rid has the smallest generation number and the oldest | |
| 200 | +** direct ancestor as the largest generation number. | |
| 201 | +*/ | |
| 202 | +void compute_direct_ancestors(int rid, int N){ | |
| 203 | + Stmt ins; | |
| 204 | + Stmt q; | |
| 205 | + int gen = 0; | |
| 206 | + db_multi_exec( | |
| 207 | + "CREATE TEMP TABLE ancestor(rid INTEGER, generation INTEGER PRIMARY KEY);" | |
| 208 | + "INSERT INTO ancestor VALUES(%d, 0);", rid | |
| 209 | + ); | |
| 210 | + db_prepare(&ins, "INSERT INTO ancestor VALUES(:rid, :gen)"); | |
| 211 | + db_prepare(&q, | |
| 212 | + "SELECT pid FROM plink" | |
| 213 | + " WHERE cid=:rid AND isprim" | |
| 214 | + ); | |
| 215 | + while( (N--)>0 ){ | |
| 216 | + db_bind_int(&q, ":rid", rid); | |
| 217 | + if( db_step(&q)!=SQLITE_ROW ) break; | |
| 218 | + rid = db_column_int(&q, 0); | |
| 219 | + db_reset(&q); | |
| 220 | + gen++; | |
| 221 | + db_bind_int(&ins, ":rid", rid); | |
| 222 | + db_bind_int(&ins, ":gen", gen); | |
| 223 | + db_step(&ins); | |
| 224 | + db_reset(&ins); | |
| 225 | + } | |
| 191 | 226 | db_finalize(&ins); |
| 192 | 227 | db_finalize(&q); |
| 193 | 228 | } |
| 194 | 229 | |
| 195 | 230 | /* |
| 196 | 231 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -186,10 +186,45 @@ | |
| 186 | } |
| 187 | db_reset(&q); |
| 188 | } |
| 189 | bag_clear(&seen); |
| 190 | pqueue_clear(&queue); |
| 191 | db_finalize(&ins); |
| 192 | db_finalize(&q); |
| 193 | } |
| 194 | |
| 195 | /* |
| 196 |
| --- src/descendants.c | |
| +++ src/descendants.c | |
| @@ -186,10 +186,45 @@ | |
| 186 | } |
| 187 | db_reset(&q); |
| 188 | } |
| 189 | bag_clear(&seen); |
| 190 | pqueue_clear(&queue); |
| 191 | db_finalize(&ins); |
| 192 | db_finalize(&q); |
| 193 | } |
| 194 | |
| 195 | /* |
| 196 | ** Compute up to N direct ancestors (merge ancestors do not count) |
| 197 | ** for the check-in rid and put them in a table named "ancestor". |
| 198 | ** Label each generation with consecutive integers going backwards |
| 199 | ** in time such that rid has the smallest generation number and the oldest |
| 200 | ** direct ancestor as the largest generation number. |
| 201 | */ |
| 202 | void compute_direct_ancestors(int rid, int N){ |
| 203 | Stmt ins; |
| 204 | Stmt q; |
| 205 | int gen = 0; |
| 206 | db_multi_exec( |
| 207 | "CREATE TEMP TABLE ancestor(rid INTEGER, generation INTEGER PRIMARY KEY);" |
| 208 | "INSERT INTO ancestor VALUES(%d, 0);", rid |
| 209 | ); |
| 210 | db_prepare(&ins, "INSERT INTO ancestor VALUES(:rid, :gen)"); |
| 211 | db_prepare(&q, |
| 212 | "SELECT pid FROM plink" |
| 213 | " WHERE cid=:rid AND isprim" |
| 214 | ); |
| 215 | while( (N--)>0 ){ |
| 216 | db_bind_int(&q, ":rid", rid); |
| 217 | if( db_step(&q)!=SQLITE_ROW ) break; |
| 218 | rid = db_column_int(&q, 0); |
| 219 | db_reset(&q); |
| 220 | gen++; |
| 221 | db_bind_int(&ins, ":rid", rid); |
| 222 | db_bind_int(&ins, ":gen", gen); |
| 223 | db_step(&ins); |
| 224 | db_reset(&ins); |
| 225 | } |
| 226 | db_finalize(&ins); |
| 227 | db_finalize(&q); |
| 228 | } |
| 229 | |
| 230 | /* |
| 231 |
+8
-7
| --- src/diff.c | ||
| +++ src/diff.c | ||
| @@ -758,16 +758,16 @@ | ||
| 758 | 758 | ** it was checked in (mlink.mid). |
| 759 | 759 | */ |
| 760 | 760 | static void annotate_file( |
| 761 | 761 | Annotator *p, /* The annotator */ |
| 762 | 762 | int fnid, /* The name of the file to be annotated */ |
| 763 | - int mid, /* The specific version of the file for this step */ | |
| 763 | + int mid, /* Use the version of the file in this check-in */ | |
| 764 | 764 | int webLabel, /* Use web-style annotations if true */ |
| 765 | 765 | int iLimit, /* Limit the number of levels if greater than zero */ |
| 766 | 766 | int annFlags /* Flags to alter the annotation */ |
| 767 | 767 | ){ |
| 768 | - Blob toAnnotate; /* Text of the final version of the file */ | |
| 768 | + Blob toAnnotate; /* Text of the final (mid) version of the file */ | |
| 769 | 769 | Blob step; /* Text of previous revision */ |
| 770 | 770 | int rid; /* Artifact ID of the file being annotated */ |
| 771 | 771 | char *zLabel; /* Label to apply to a line */ |
| 772 | 772 | Stmt q; /* Query returning all ancestor versions */ |
| 773 | 773 | |
| @@ -778,23 +778,24 @@ | ||
| 778 | 778 | } |
| 779 | 779 | if( !content_get(rid, &toAnnotate) ){ |
| 780 | 780 | fossil_panic("unable to retrieve content of artifact #%d", rid); |
| 781 | 781 | } |
| 782 | 782 | db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)"); |
| 783 | - compute_ancestors(mid, 1000000000); | |
| 783 | + if( iLimit<=0 ) iLimit = 1000000000; | |
| 784 | + compute_direct_ancestors(mid, iLimit); | |
| 784 | 785 | annotation_start(p, &toAnnotate); |
| 785 | 786 | |
| 786 | 787 | db_prepare(&q, |
| 787 | 788 | "SELECT mlink.fid," |
| 788 | 789 | " (SELECT uuid FROM blob WHERE rid=mlink.%s)," |
| 789 | 790 | " date(event.mtime), " |
| 790 | 791 | " coalesce(event.euser,event.user) " |
| 791 | - " FROM mlink, event" | |
| 792 | + " FROM ancestor, mlink, event" | |
| 792 | 793 | " WHERE mlink.fnid=%d" |
| 793 | - " AND mlink.mid IN ok" | |
| 794 | - " AND event.objid=mlink.mid" | |
| 795 | - " ORDER BY event.mtime DESC" | |
| 794 | + " AND mlink.mid=ancestor.rid" | |
| 795 | + " AND event.objid=ancestor.rid" | |
| 796 | + " ORDER BY ancestor.generation ASC" | |
| 796 | 797 | " LIMIT %d", |
| 797 | 798 | (annFlags & ANN_FILE_VERS)!=0 ? "fid" : "mid", |
| 798 | 799 | fnid, |
| 799 | 800 | iLimit>0 ? iLimit : 10000000 |
| 800 | 801 | ); |
| 801 | 802 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -758,16 +758,16 @@ | |
| 758 | ** it was checked in (mlink.mid). |
| 759 | */ |
| 760 | static void annotate_file( |
| 761 | Annotator *p, /* The annotator */ |
| 762 | int fnid, /* The name of the file to be annotated */ |
| 763 | int mid, /* The specific version of the file for this step */ |
| 764 | int webLabel, /* Use web-style annotations if true */ |
| 765 | int iLimit, /* Limit the number of levels if greater than zero */ |
| 766 | int annFlags /* Flags to alter the annotation */ |
| 767 | ){ |
| 768 | Blob toAnnotate; /* Text of the final version of the file */ |
| 769 | Blob step; /* Text of previous revision */ |
| 770 | int rid; /* Artifact ID of the file being annotated */ |
| 771 | char *zLabel; /* Label to apply to a line */ |
| 772 | Stmt q; /* Query returning all ancestor versions */ |
| 773 | |
| @@ -778,23 +778,24 @@ | |
| 778 | } |
| 779 | if( !content_get(rid, &toAnnotate) ){ |
| 780 | fossil_panic("unable to retrieve content of artifact #%d", rid); |
| 781 | } |
| 782 | db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)"); |
| 783 | compute_ancestors(mid, 1000000000); |
| 784 | annotation_start(p, &toAnnotate); |
| 785 | |
| 786 | db_prepare(&q, |
| 787 | "SELECT mlink.fid," |
| 788 | " (SELECT uuid FROM blob WHERE rid=mlink.%s)," |
| 789 | " date(event.mtime), " |
| 790 | " coalesce(event.euser,event.user) " |
| 791 | " FROM mlink, event" |
| 792 | " WHERE mlink.fnid=%d" |
| 793 | " AND mlink.mid IN ok" |
| 794 | " AND event.objid=mlink.mid" |
| 795 | " ORDER BY event.mtime DESC" |
| 796 | " LIMIT %d", |
| 797 | (annFlags & ANN_FILE_VERS)!=0 ? "fid" : "mid", |
| 798 | fnid, |
| 799 | iLimit>0 ? iLimit : 10000000 |
| 800 | ); |
| 801 |
| --- src/diff.c | |
| +++ src/diff.c | |
| @@ -758,16 +758,16 @@ | |
| 758 | ** it was checked in (mlink.mid). |
| 759 | */ |
| 760 | static void annotate_file( |
| 761 | Annotator *p, /* The annotator */ |
| 762 | int fnid, /* The name of the file to be annotated */ |
| 763 | int mid, /* Use the version of the file in this check-in */ |
| 764 | int webLabel, /* Use web-style annotations if true */ |
| 765 | int iLimit, /* Limit the number of levels if greater than zero */ |
| 766 | int annFlags /* Flags to alter the annotation */ |
| 767 | ){ |
| 768 | Blob toAnnotate; /* Text of the final (mid) version of the file */ |
| 769 | Blob step; /* Text of previous revision */ |
| 770 | int rid; /* Artifact ID of the file being annotated */ |
| 771 | char *zLabel; /* Label to apply to a line */ |
| 772 | Stmt q; /* Query returning all ancestor versions */ |
| 773 | |
| @@ -778,23 +778,24 @@ | |
| 778 | } |
| 779 | if( !content_get(rid, &toAnnotate) ){ |
| 780 | fossil_panic("unable to retrieve content of artifact #%d", rid); |
| 781 | } |
| 782 | db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)"); |
| 783 | if( iLimit<=0 ) iLimit = 1000000000; |
| 784 | compute_direct_ancestors(mid, iLimit); |
| 785 | annotation_start(p, &toAnnotate); |
| 786 | |
| 787 | db_prepare(&q, |
| 788 | "SELECT mlink.fid," |
| 789 | " (SELECT uuid FROM blob WHERE rid=mlink.%s)," |
| 790 | " date(event.mtime), " |
| 791 | " coalesce(event.euser,event.user) " |
| 792 | " FROM ancestor, mlink, event" |
| 793 | " WHERE mlink.fnid=%d" |
| 794 | " AND mlink.mid=ancestor.rid" |
| 795 | " AND event.objid=ancestor.rid" |
| 796 | " ORDER BY ancestor.generation ASC" |
| 797 | " LIMIT %d", |
| 798 | (annFlags & ANN_FILE_VERS)!=0 ? "fid" : "mid", |
| 799 | fnid, |
| 800 | iLimit>0 ? iLimit : 10000000 |
| 801 | ); |
| 802 |