Fossil SCM

Reducing the leak of annotate even more. I wrote a TODO in the file, for a leak still present and relevant for files modified by many versions, but that requires harder work to get right.

viriketo 2011-09-04 21:39 UTC annotate_noleak
Commit e2ebb1f5cae83e85a03bf4a32a48bb1303e665e8
1 file changed +21 -10
+21 -10
--- src/diff.c
+++ src/diff.c
@@ -637,22 +637,23 @@
637637
int nOrig; /* Number of elements in aOrig[] */
638638
int nNoSrc; /* Number of entries where aOrig[].zSrc==NULL */
639639
int iLevel; /* Current level */
640640
int nVers; /* Number of versions analyzed */
641641
char **azVers; /* Names of versions analyzed */
642
+ Blob toAnnotate;
642643
};
643644
644645
/*
645646
** Initialize the annotation process by specifying the file that is
646647
** to be annotated. The annotator takes control of the input Blob and
647648
** will release it when it is finished with it.
648649
*/
649
-static int annotation_start(Annotator *p, Blob *pInput){
650
+static int annotation_start(Annotator *p){
650651
int i;
651652
652
- memset(p, 0, sizeof(*p));
653
- p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,1);
653
+ p->c.aTo = break_into_lines(blob_str(&p->toAnnotate),
654
+ blob_size(&p->toAnnotate),&p->c.nTo,1);
654655
if( p->c.aTo==0 ){
655656
return 1;
656657
}
657658
p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
658659
for(i=0; i<p->c.nTo; i++){
@@ -679,10 +680,11 @@
679680
680681
/* Prepare the parent file to be diffed */
681682
p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
682683
&p->c.nFrom, 1);
683684
if( p->c.aFrom==0 ){
685
+ free(p->c.aFrom);
684686
return 1;
685687
}
686688
687689
/* Compute the differences going from pParent to the file being
688690
** annotated. */
@@ -696,10 +698,12 @@
696698
iThisLevel = p->iLevel;
697699
for(i=lnTo=0; i<p->c.nEdit; i+=3){
698700
struct AnnLine *x = &p->aOrig[lnTo];
699701
for(j=0; j<p->c.aEdit[i]; j++, lnTo++, x++){
700702
if( x->zSrc==0 || x->iLevel==iPrevLevel ){
703
+ /* TODO: handle zPName so we can free labels
704
+ * if they get totally unreferenced in the Annotator */
701705
x->zSrc = zPName;
702706
x->iLevel = iThisLevel;
703707
}
704708
}
705709
lnTo += p->c.aEdit[i+2];
@@ -722,19 +726,20 @@
722726
723727
/*
724728
** COMMAND: test-annotate-step
725729
*/
726730
void test_annotate_step_cmd(void){
727
- Blob orig, b;
731
+ Blob b = empty_blob;
728732
Annotator x;
729733
int i;
730734
731735
if( g.argc<4 ) usage("RID1 RID2 ...");
732736
db_must_be_within_tree();
733
- blob_zero(&b);
734
- content_get(name_to_rid(g.argv[2]), &orig);
735
- if( annotation_start(&x, &orig) ){
737
+ memset(&x, 0, sizeof(x));
738
+ x.toAnnotate = empty_blob;
739
+ content_get(name_to_rid(g.argv[2]), &x.toAnnotate);
740
+ if( annotation_start(&x) ){
736741
fossil_fatal("binary file");
737742
}
738743
for(i=3; i<g.argc; i++){
739744
blob_zero(&b);
740745
content_get(name_to_rid(g.argv[i]), &b);
@@ -763,11 +768,10 @@
763768
int mid, /* Use the version of the file in this check-in */
764769
int webLabel, /* Use web-style annotations if true */
765770
int iLimit, /* Limit the number of levels if greater than zero */
766771
int annFlags /* Flags to alter the annotation */
767772
){
768
- Blob toAnnotate = empty_blob; /* Text of the final (mid) version of the file */
769773
Blob step = empty_blob; /* Text of previous revision */
770774
int rid; /* Artifact ID of the file being annotated */
771775
char *zLabel; /* Label to apply to a line */
772776
Stmt q; /* Query returning all ancestor versions */
773777
@@ -774,17 +778,19 @@
774778
/* Initialize the annotation */
775779
rid = db_int(0, "SELECT fid FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid);
776780
if( rid==0 ){
777781
fossil_panic("file #%d is unchanged in manifest #%d", fnid, mid);
778782
}
779
- if( !content_get(rid, &toAnnotate) ){
783
+ memset(p, 0, sizeof(*p));
784
+ p->toAnnotate = empty_blob;
785
+ if( !content_get(rid, &p->toAnnotate) ){
780786
fossil_panic("unable to retrieve content of artifact #%d", rid);
781787
}
782788
db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
783789
if( iLimit<=0 ) iLimit = 1000000000;
784790
compute_direct_ancestors(mid, iLimit);
785
- annotation_start(p, &toAnnotate);
791
+ annotation_start(p);
786792
787793
db_prepare(&q,
788794
"SELECT mlink.fid,"
789795
" (SELECT uuid FROM blob WHERE rid=mlink.%s),"
790796
" date(event.mtime), "
@@ -818,10 +824,11 @@
818824
content_get(pid, &step);
819825
annotation_step(p, &step, zLabel);
820826
blob_reset(&step);
821827
}
822828
db_finalize(&q);
829
+ free(p->c.aTo);
823830
}
824831
825832
/*
826833
** WEBPAGE: annotate
827834
**
@@ -914,10 +921,11 @@
914921
}
915922
fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
916923
if( fid==0 ){
917924
fossil_fatal("not part of current checkout: %s", zFilename);
918925
}
926
+ blob_reset(&treename);
919927
mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
920928
if( mid==0 ){
921929
fossil_panic("unable to find manifest");
922930
}
923931
if( fileVers ) annFlags |= ANN_FILE_VERS;
@@ -930,6 +938,9 @@
930938
}
931939
for(i=0; i<ann.nOrig; i++){
932940
fossil_print("%s: %.*s\n",
933941
ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
934942
}
943
+ free(ann.azVers);
944
+ free(ann.aOrig);
945
+ blob_reset(&ann.toAnnotate);
935946
}
936947
--- src/diff.c
+++ src/diff.c
@@ -637,22 +637,23 @@
637 int nOrig; /* Number of elements in aOrig[] */
638 int nNoSrc; /* Number of entries where aOrig[].zSrc==NULL */
639 int iLevel; /* Current level */
640 int nVers; /* Number of versions analyzed */
641 char **azVers; /* Names of versions analyzed */
 
642 };
643
644 /*
645 ** Initialize the annotation process by specifying the file that is
646 ** to be annotated. The annotator takes control of the input Blob and
647 ** will release it when it is finished with it.
648 */
649 static int annotation_start(Annotator *p, Blob *pInput){
650 int i;
651
652 memset(p, 0, sizeof(*p));
653 p->c.aTo = break_into_lines(blob_str(pInput), blob_size(pInput),&p->c.nTo,1);
654 if( p->c.aTo==0 ){
655 return 1;
656 }
657 p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
658 for(i=0; i<p->c.nTo; i++){
@@ -679,10 +680,11 @@
679
680 /* Prepare the parent file to be diffed */
681 p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
682 &p->c.nFrom, 1);
683 if( p->c.aFrom==0 ){
 
684 return 1;
685 }
686
687 /* Compute the differences going from pParent to the file being
688 ** annotated. */
@@ -696,10 +698,12 @@
696 iThisLevel = p->iLevel;
697 for(i=lnTo=0; i<p->c.nEdit; i+=3){
698 struct AnnLine *x = &p->aOrig[lnTo];
699 for(j=0; j<p->c.aEdit[i]; j++, lnTo++, x++){
700 if( x->zSrc==0 || x->iLevel==iPrevLevel ){
 
 
701 x->zSrc = zPName;
702 x->iLevel = iThisLevel;
703 }
704 }
705 lnTo += p->c.aEdit[i+2];
@@ -722,19 +726,20 @@
722
723 /*
724 ** COMMAND: test-annotate-step
725 */
726 void test_annotate_step_cmd(void){
727 Blob orig, b;
728 Annotator x;
729 int i;
730
731 if( g.argc<4 ) usage("RID1 RID2 ...");
732 db_must_be_within_tree();
733 blob_zero(&b);
734 content_get(name_to_rid(g.argv[2]), &orig);
735 if( annotation_start(&x, &orig) ){
 
736 fossil_fatal("binary file");
737 }
738 for(i=3; i<g.argc; i++){
739 blob_zero(&b);
740 content_get(name_to_rid(g.argv[i]), &b);
@@ -763,11 +768,10 @@
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 = empty_blob; /* Text of the final (mid) version of the file */
769 Blob step = empty_blob; /* 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
@@ -774,17 +778,19 @@
774 /* Initialize the annotation */
775 rid = db_int(0, "SELECT fid FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid);
776 if( rid==0 ){
777 fossil_panic("file #%d is unchanged in manifest #%d", fnid, mid);
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), "
@@ -818,10 +824,11 @@
818 content_get(pid, &step);
819 annotation_step(p, &step, zLabel);
820 blob_reset(&step);
821 }
822 db_finalize(&q);
 
823 }
824
825 /*
826 ** WEBPAGE: annotate
827 **
@@ -914,10 +921,11 @@
914 }
915 fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
916 if( fid==0 ){
917 fossil_fatal("not part of current checkout: %s", zFilename);
918 }
 
919 mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
920 if( mid==0 ){
921 fossil_panic("unable to find manifest");
922 }
923 if( fileVers ) annFlags |= ANN_FILE_VERS;
@@ -930,6 +938,9 @@
930 }
931 for(i=0; i<ann.nOrig; i++){
932 fossil_print("%s: %.*s\n",
933 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
934 }
 
 
 
935 }
936
--- src/diff.c
+++ src/diff.c
@@ -637,22 +637,23 @@
637 int nOrig; /* Number of elements in aOrig[] */
638 int nNoSrc; /* Number of entries where aOrig[].zSrc==NULL */
639 int iLevel; /* Current level */
640 int nVers; /* Number of versions analyzed */
641 char **azVers; /* Names of versions analyzed */
642 Blob toAnnotate;
643 };
644
645 /*
646 ** Initialize the annotation process by specifying the file that is
647 ** to be annotated. The annotator takes control of the input Blob and
648 ** will release it when it is finished with it.
649 */
650 static int annotation_start(Annotator *p){
651 int i;
652
653 p->c.aTo = break_into_lines(blob_str(&p->toAnnotate),
654 blob_size(&p->toAnnotate),&p->c.nTo,1);
655 if( p->c.aTo==0 ){
656 return 1;
657 }
658 p->aOrig = fossil_malloc( sizeof(p->aOrig[0])*p->c.nTo );
659 for(i=0; i<p->c.nTo; i++){
@@ -679,10 +680,11 @@
680
681 /* Prepare the parent file to be diffed */
682 p->c.aFrom = break_into_lines(blob_str(pParent), blob_size(pParent),
683 &p->c.nFrom, 1);
684 if( p->c.aFrom==0 ){
685 free(p->c.aFrom);
686 return 1;
687 }
688
689 /* Compute the differences going from pParent to the file being
690 ** annotated. */
@@ -696,10 +698,12 @@
698 iThisLevel = p->iLevel;
699 for(i=lnTo=0; i<p->c.nEdit; i+=3){
700 struct AnnLine *x = &p->aOrig[lnTo];
701 for(j=0; j<p->c.aEdit[i]; j++, lnTo++, x++){
702 if( x->zSrc==0 || x->iLevel==iPrevLevel ){
703 /* TODO: handle zPName so we can free labels
704 * if they get totally unreferenced in the Annotator */
705 x->zSrc = zPName;
706 x->iLevel = iThisLevel;
707 }
708 }
709 lnTo += p->c.aEdit[i+2];
@@ -722,19 +726,20 @@
726
727 /*
728 ** COMMAND: test-annotate-step
729 */
730 void test_annotate_step_cmd(void){
731 Blob b = empty_blob;
732 Annotator x;
733 int i;
734
735 if( g.argc<4 ) usage("RID1 RID2 ...");
736 db_must_be_within_tree();
737 memset(&x, 0, sizeof(x));
738 x.toAnnotate = empty_blob;
739 content_get(name_to_rid(g.argv[2]), &x.toAnnotate);
740 if( annotation_start(&x) ){
741 fossil_fatal("binary file");
742 }
743 for(i=3; i<g.argc; i++){
744 blob_zero(&b);
745 content_get(name_to_rid(g.argv[i]), &b);
@@ -763,11 +768,10 @@
768 int mid, /* Use the version of the file in this check-in */
769 int webLabel, /* Use web-style annotations if true */
770 int iLimit, /* Limit the number of levels if greater than zero */
771 int annFlags /* Flags to alter the annotation */
772 ){
 
773 Blob step = empty_blob; /* Text of previous revision */
774 int rid; /* Artifact ID of the file being annotated */
775 char *zLabel; /* Label to apply to a line */
776 Stmt q; /* Query returning all ancestor versions */
777
@@ -774,17 +778,19 @@
778 /* Initialize the annotation */
779 rid = db_int(0, "SELECT fid FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid);
780 if( rid==0 ){
781 fossil_panic("file #%d is unchanged in manifest #%d", fnid, mid);
782 }
783 memset(p, 0, sizeof(*p));
784 p->toAnnotate = empty_blob;
785 if( !content_get(rid, &p->toAnnotate) ){
786 fossil_panic("unable to retrieve content of artifact #%d", rid);
787 }
788 db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
789 if( iLimit<=0 ) iLimit = 1000000000;
790 compute_direct_ancestors(mid, iLimit);
791 annotation_start(p);
792
793 db_prepare(&q,
794 "SELECT mlink.fid,"
795 " (SELECT uuid FROM blob WHERE rid=mlink.%s),"
796 " date(event.mtime), "
@@ -818,10 +824,11 @@
824 content_get(pid, &step);
825 annotation_step(p, &step, zLabel);
826 blob_reset(&step);
827 }
828 db_finalize(&q);
829 free(p->c.aTo);
830 }
831
832 /*
833 ** WEBPAGE: annotate
834 **
@@ -914,10 +921,11 @@
921 }
922 fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
923 if( fid==0 ){
924 fossil_fatal("not part of current checkout: %s", zFilename);
925 }
926 blob_reset(&treename);
927 mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
928 if( mid==0 ){
929 fossil_panic("unable to find manifest");
930 }
931 if( fileVers ) annFlags |= ANN_FILE_VERS;
@@ -930,6 +938,9 @@
938 }
939 for(i=0; i<ann.nOrig; i++){
940 fossil_print("%s: %.*s\n",
941 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
942 }
943 free(ann.azVers);
944 free(ann.aOrig);
945 blob_reset(&ann.toAnnotate);
946 }
947

Keyboard Shortcuts

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