Fossil SCM

Improvements to the "annotate" algorithm: Only search primary ancestors; ignore branchs.

drh 2011-06-07 15:51 trunk
Commit 621be704940afeef6d02c3615c07a2ee4f54edfc
2 files changed +35 +8 -7
--- src/descendants.c
+++ src/descendants.c
@@ -186,10 +186,45 @@
186186
}
187187
db_reset(&q);
188188
}
189189
bag_clear(&seen);
190190
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
+ }
191226
db_finalize(&ins);
192227
db_finalize(&q);
193228
}
194229
195230
/*
196231
--- 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 @@
758758
** it was checked in (mlink.mid).
759759
*/
760760
static void annotate_file(
761761
Annotator *p, /* The annotator */
762762
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 */
764764
int webLabel, /* Use web-style annotations if true */
765765
int iLimit, /* Limit the number of levels if greater than zero */
766766
int annFlags /* Flags to alter the annotation */
767767
){
768
- Blob toAnnotate; /* Text of the final version of the file */
768
+ Blob toAnnotate; /* Text of the final (mid) version of the file */
769769
Blob step; /* Text of previous revision */
770770
int rid; /* Artifact ID of the file being annotated */
771771
char *zLabel; /* Label to apply to a line */
772772
Stmt q; /* Query returning all ancestor versions */
773773
@@ -778,23 +778,24 @@
778778
}
779779
if( !content_get(rid, &toAnnotate) ){
780780
fossil_panic("unable to retrieve content of artifact #%d", rid);
781781
}
782782
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);
784785
annotation_start(p, &toAnnotate);
785786
786787
db_prepare(&q,
787788
"SELECT mlink.fid,"
788789
" (SELECT uuid FROM blob WHERE rid=mlink.%s),"
789790
" date(event.mtime), "
790791
" coalesce(event.euser,event.user) "
791
- " FROM mlink, event"
792
+ " FROM ancestor, mlink, event"
792793
" 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"
796797
" LIMIT %d",
797798
(annFlags & ANN_FILE_VERS)!=0 ? "fid" : "mid",
798799
fnid,
799800
iLimit>0 ? iLimit : 10000000
800801
);
801802
--- 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

Keyboard Shortcuts

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