081e0431f88cf0536f1c4c56e56c3a0007890ab0
hiram
  Wed Jan 2 13:20:26 2019 -0800
speed up display for codonDefault AA display refs #19937

diff --git src/hg/hgTracks/wigMafTrack.c src/hg/hgTracks/wigMafTrack.c
index d28cc6e..4aded9c 100644
--- src/hg/hgTracks/wigMafTrack.c
+++ src/hg/hgTracks/wigMafTrack.c
@@ -2395,61 +2395,72 @@
 
     line  = lines[i];
     /* TODO: leave lower case in to indicate masking ?
        * NOTE: want to make sure that all sequences are soft-masked
        * if we do this */
     /* HAVE DONE:  David doesn't like lower case by default
      * TODO: casing based on quality values ?? */
     alignSeqToUpperN(line);
     if (complementBases)
         {
 	complement(line, strlen(line));
         }
     /* draw sequence letters for alignment */
     hvGfxSetClip(hvg, x, y-1, width, mi->height);
 
+    /* having these static here will allow the option 'codonDefault'
+     * to run rapidly through the display without extra calls to SQL
+     * for the same answer over and over.  For other codon modes, it
+     * will still need to query the Frames table repeatedly.  Currently this
+     * is slow, perhaps it needs an index on the src column ?
+     */
+    static char * extraPrevious = NULL;
+    static struct mafFrames *mfList = NULL, *mf;
+    static boolean found = FALSE;
     if (framesTable != NULL)
 	{
-        struct mafFrames *mfList = NULL, *mf;
 	char extra[512];
-	boolean found = FALSE;
 
 	if (sameString("codonDefault", codonTransMode))
 	    {
 	    safef(extra, sizeof(extra), "src='%s'",defaultCodonSpecies);
 
 	    found = TRUE;
 	    }
 	else if (sameString("codonFrameDef", codonTransMode))
 	    {
 	    safef(extra, sizeof(extra), "src='%s'",mi->db);
 
 	    found = FALSE;
 	    }
 	else if (sameString("codonFrameNone", codonTransMode))
 	    {
 	    safef(extra, sizeof(extra), "src='%s'",mi->db);
 
 	    found = TRUE;
 	    }
 	else
 	    errAbort("unknown codon translation mode %s",codonTransMode);
 tryagain:
         if (track->isBigBed)
             mfList = getFramesFromBb(  framesTable, chromName, seqStart, seqEnd);
         else
+            if (differentStringNullOk(extraPrevious, extra))
+		{
 		mfList = getFramesFromSql(  framesTable, chromName, seqStart, seqEnd, extra, newTableType);
+		extraPrevious = cloneString(extra);
+		}
 
         if (mfList != NULL)
             found = TRUE;
 
         for(mf = mfList; mf; mf = mf->next)
             {
             int start, end, w;
             int frame;
             if (mf->chromStart < seqStart)
                 start = 0;
             else
                 start = mf->chromStart-seqStart;
             frame = mf->frame;
             if (mf->strand[0] == '-')
                 {