91985b1a5c608e152a16816d7533f95ced20a1a5
max
  Tue Mar 27 13:30:58 2012 -0700
fixing performance issue with itemName/mapItem in squish/dense mode, loading extra fields now lazily in itemName/mapItem instead of loadItems
diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index ed90237..f11e128 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -12169,96 +12169,85 @@
         matchStr[i++] = *str;
     for(;*str && isspace(*str);str++)
         ;
     }
 matchStr[i++] = 0;
 return matchStr;
 }
 
 struct pubsExtra 
 /* additional info needed for publication blat linked features: author+year and title */
 {
     char* label;
     char* mouseOver;
 };
 
-static char* pubsFeatureLabel(char* authors, char* year) 
+static char* pubsFeatureLabel(char* author, char* year) 
 /* create label <author><year> given authors and year strings */
 {
 char* authorYear = NULL;
 
-char* author = firstWordInLine(authors);
-stripChar(author, ',');
-stripChar(author, ';');
-
 if (isEmpty(author))
     author = "NoAuthor";
 if (isEmpty(year))
     year = "NoYear";
 authorYear  = catTwoStrings(author, year);
 
 return authorYear;
 }
 
 static struct pubsExtra *pubsMakeExtra(char* articleTable, struct sqlConnection* conn, 
     struct linkedFeatures* lf)
 {
 char query[LARGEBUF];
 struct sqlResult *sr = NULL;
 char **row = NULL;
 struct pubsExtra *extra = NULL;
 
-safef(query, sizeof(query), "SELECT authors, year, title FROM %s WHERE articleId = '%s'", 
+safef(query, sizeof(query), "SELECT firstAuthor, year, title FROM %s WHERE articleId = '%s'", 
     articleTable, lf->name);
 sr = sqlGetResult(conn, query);
 if ((row = sqlNextRow(sr)) != NULL)
 {
-    char* authors = row[0];
+    char* firstAuthor = row[0];
     char* year    = row[1];
     char* title   = row[2];
 
     extra = needMem(sizeof(struct pubsExtra));
-    extra->label = pubsFeatureLabel(authors, year);
+    extra->label = pubsFeatureLabel(firstAuthor, year);
     if (isEmpty(title))
         extra->mouseOver = extra->label;
     else
         extra->mouseOver = cloneString(title);
 }
 
 sqlFreeResult(&sr);
 return extra;
 }
 
-static void pubsLookupAuthors(struct track *tg)
-/* add authorYear and title to all linkedFeatures->extra */
+static void pubsAddExtra(struct track* tg, struct linkedFeatures* lf)
+/* add authorYear and title to linkedFeatures->extra */
 {
-enum trackVisibility vis = tg->visibility;
-if (vis == tvDense || vis == tvSquish) 
-    return;
-
-char *articleTable = pubsArticleTable(tg);
+char *articleTable = trackDbSettingClosestToHome(tg->tdb, "pubsArticleTable");
 if(isEmpty(articleTable))
     return;
-
-struct linkedFeatures *lf = NULL;
+if (lf->extra != NULL)
+    return;
 
 struct sqlConnection *conn = hAllocConn(database);
-for (lf = tg->items; lf != NULL; lf = lf->next)
-{
     struct pubsExtra* extra = pubsMakeExtra(articleTable, conn, lf);
     lf->extra = extra;
-}
 hFreeConn(&conn);
 }
 
 static void pubsLoadKeywordYearItems(struct track *tg)
 /* load items that fulfill keyword and year filter */
 {
 struct sqlConnection *conn = hAllocConn(database);
 char *keywords = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "pubsKeywords");
 char *yearFilter = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "pubsYear");
 char *articleTable = pubsArticleTable(tg);
 
 if(yearFilter == NULL || sameWord(yearFilter, "anytime"))
     yearFilter = NULL;
 
 if(isNotEmpty(keywords))
@@ -12322,62 +12311,57 @@
  * into the cart and activate the track.
  */
 {
 char *articleId = cgiOptionalString(PUBSFILTERNAME);
 //if (articleId==NULL) 
     //articleId = cartOptionalString(cart, PUBSFILTERNAME);
 
 if (articleId!=NULL) 
 {
     cartSetString(cart, PUBSFILTERNAME, articleId);
     tdbSetCartVisibility(tg->tdb, cart, hCarefulTrackOpenVis(database, tg->track));
     tg->visibility=tvPack;
 }
 }
 
-static void pubsLoadItems(struct track *tg)
-/* filter items and stuff item data from other tables (author name, title) into extra field */
-{
-pubsLoadKeywordYearItems(tg);
-pubsLookupAuthors(tg);
-}
-
 char *pubsItemName(struct track *tg, void *item)
 /* get author/year from extra field */
 {
 struct linkedFeatures *lf = item;
+pubsAddExtra(tg, lf);
+
 struct pubsExtra* extra = lf->extra;
 if (extra!=NULL)
     return extra->label;
 else
     return lf->name;
+
 }
 
 static void pubsMapItem(struct track *tg, struct hvGfx *hvg, void *item,
 				char *itemName, char *mapItemName, int start, int end,
 				int x, int y, int width, int height)
 /* create mouse over with title for pubs blat features. */
 {
 if (!theImgBox || tg->limitedVis != tvDense || !tdbIsCompositeChild(tg->tdb)) 
 {
     struct linkedFeatures *lf = item;
-    char* mouseOver = NULL;
-    if (lf->extra != NULL) 
-    {
+    pubsAddExtra(tg, lf);
         struct pubsExtra *extra = lf->extra;
+    char* mouseOver = NULL;
+    if (extra != NULL) 
         mouseOver = extra->mouseOver;
-    }
     else
         mouseOver = itemName;
 
     mapBoxHc(hvg, start, end, x, y, width, height, tg->track, mapItemName, mouseOver); 
 }
 }
 
 static void pubsLoadMarkerItem (struct track *tg)
 /* copy item names into extra field */
 {
 //loadSimpleBed(tg);
 loadSimpleBedAsLinkedFeaturesPerBase(tg);
 //tg->items = simpleBedListToLinkedFeatures(tg->items, tg->bedSize, TRUE, FALSE);
 //if (! (hashFindVal(tdb->settingsHash, "pubsMarkerTable")))
 enum trackVisibility vis = tg->visibility;
@@ -12420,31 +12404,31 @@
         selectValSql = "concat(substr(sequence,1,4),\"...\",substr(sequence,-4))";
 
     safef(query, sizeof(query), "SELECT annotId, %s  FROM %s WHERE articleId='%s' ", 
         selectValSql, sequenceTable, articleId);
     struct hash *seqIdHash = sqlQuickHash(conn, query);
     //freeMem(sequenceTable); // XX Why does this crash??
     return seqIdHash;
 }
 
 static char *pubsArticleDispId(struct track *tg, struct sqlConnection *conn, char* articleId)
 /* given an articleId, lookup author and year and create <author><year> label for it */
 {
 char* dispLabel = NULL;
 char *articleTable = pubsArticleTable(tg);
 char query[LARGEBUF];
-safef(query, sizeof(query), "SELECT authors, year FROM %s WHERE articleId = '%s'", 
+safef(query, sizeof(query), "SELECT firstAuthor, year FROM %s WHERE articleId = '%s'", 
     articleTable, articleId);
 struct sqlResult *sr = sqlGetResult(conn, query);
 if (sr!=NULL)
 {
     char **row = NULL;
     row = sqlNextRow(sr);
     if (row != NULL)
         dispLabel = pubsFeatureLabel(row[0], row[1]);
     else
         dispLabel = articleId;
 }
 else
     dispLabel = articleId;
 sqlFreeResult(&sr);
 return dispLabel;
@@ -12496,31 +12480,31 @@
 hFreeConn(&conn);
 }
 
 static void pubsBlatPslMethods(struct track *tg)
 /* a track that shows only the indiv matches for one single article */
 {
 activatePslTrackIfCgi(tg);
 tg->loadItems = pubsPslLoadItems;
 tg->itemName  = pubsItemName;
 tg->mapItem   = pubsMapItem;
 }
 
 static void pubsBlatMethods(struct track *tg)
 /* publication blat tracks are bed12+2 tracks of sequences in text, mapped with BLAT */
 {
-tg->loadItems = pubsLoadItems;
+tg->loadItems = pubsLoadKeywordYearItems;
 tg->itemName  = pubsItemName;
 tg->mapItem   = pubsMapItem;
 }
 
 static void pubsMarkerMethods(struct track *tg)
 /* publication marker tracks are bed5 tracks of genome marker occurences like rsXXXX found in text*/
 {
 tg->bedSize   = 5;
 tg->loadItems = pubsLoadMarkerItem;
 tg->mapItem   = pubsMarkerMapItem;
 tg->itemName  = pubsMarkerItemName;
 }
 
 void fillInFromType(struct track *track, struct trackDb *tdb)
 /* Fill in various function pointers in track from type field of tdb. */