9956f8a4abe10ace2c6da838141fe71112761bd6 max Tue Jun 18 11:11:16 2013 -0700 fixed performance bug #6833, forgot to check for dense mode diff --git src/hg/hgTracks/pubsTracks.c src/hg/hgTracks/pubsTracks.c index 0d678a1..893bfbf 100644 --- src/hg/hgTracks/pubsTracks.c +++ src/hg/hgTracks/pubsTracks.c @@ -1,27 +1,33 @@ /* pubsTracks - code for the publications tracks */ #include "common.h" #include "hgTracks.h" #include "hgFind.h" #include "bedCart.h" // we distinguish between four levels of impact factors <1, <3, <10 and >10 static struct rgbColor impact1Color = {80, 80, 80}; static struct rgbColor impact2Color = {0, 80, 255}; static struct rgbColor impact3Color = {0, 100, 0}; static struct rgbColor impact4Color = {255, 255, 0}; +// the cgi can handle "old" or "new" table formats +// seqTableFormat can be is either 0 (=uninitialized), 1 (=old) or 2(=new) +int seqTableFormat = 0; +#define SEQTABLE_NEW 1 +#define SEQTABLE_OLD 2 + static char *pubsArticleTable(struct track *tg) /* return the name of the pubs articleTable, either * the value from the trackDb statement 'articleTable' * or the default value: Article */ { char *articleTable = trackDbSettingClosestToHome(tg->tdb, "pubsArticleTable"); if (isEmpty(articleTable)) { char buf[256]; safef(buf, sizeof(buf), "%sArticle", tg->track); articleTable = cloneString(buf); } return articleTable; } @@ -95,78 +101,84 @@ static char *pubsFeatureLabel(char *author, char *year) /* create label given authors and year strings */ { char *authorYear = NULL; if (isEmpty(author)) author = "NoAuthor"; if (isEmpty(year)) year = "NoYear"; authorYear = catTwoStrings(author, year); return authorYear; } +static void setFormatFlag(struct sqlConnection* conn, char* tableName) +/* We support two different storage places for article data: either the bed table directly + * includes the title + author of the article or we have to look it up from the articles + * table. Having a copy of the title in the bed table is faster + * This function sets the flag to indicate the version we have in our table. + * */ +{ +if (seqTableFormat!=0) + return; +if (sqlColumnExists(conn, tableName, "title")) + seqTableFormat = SEQTABLE_NEW; +else + seqTableFormat = SEQTABLE_OLD; +} + static struct pubsExtra *pubsMakeExtra(struct track* tg, char *articleTable, struct sqlConnection* conn, struct linkedFeatures* lf) /* bad solution: a function that is called before the extra field is * accessed and that fills it from a sql query. Will need to redo this like gencode, * drawing from atom, variome and bedLoadN or bedDetails */ { char query[LARGEBUF]; struct sqlResult *sr = NULL; char **row = NULL; struct pubsExtra *extra = NULL; -/* support two different storage places for article data: either the bed table directly - * includes the title + author of the article or we have to look it up from the articles - * table. Having a copy of the title in the bed table is faster */ -bool newFormat = FALSE; -if (sqlColumnExists(conn, tg->table, "title")) - { +setFormatFlag(conn, tg->table); +if (seqTableFormat==SEQTABLE_NEW) sqlSafef(query, sizeof(query), "SELECT firstAuthor, year, title, impact, classes FROM %s " "WHERE chrom = '%s' and chromStart = '%d' and name='%s'", tg->table, chromName, lf->start, lf->name); - newFormat = TRUE; - } else - { sqlSafef(query, sizeof(query), "SELECT firstAuthor, year, title FROM %s WHERE articleId = '%s'", articleTable, lf->name); - newFormat = FALSE; - } sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) { char *firstAuthor = row[0]; char *year = row[1]; char *title = row[2]; char *impact = NULL; char *classes = NULL; extra = needMem(sizeof(struct pubsExtra)); extra->label = pubsFeatureLabel(firstAuthor, year); if (isEmpty(title)) extra->mouseOver = extra->label; else extra->mouseOver = cloneString(title); extra->color = NULL; extra->shade = -1; - if (newFormat) + if (seqTableFormat==SEQTABLE_NEW) { impact = row[3]; classes = row[4]; if (!isEmpty(impact)) { char *colorBy = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "pubsColorBy"); if ((colorBy==NULL) || strcmp(colorBy,"topic")==0) { char *classCopy = classes; char *mainClass = cloneNextWordByDelimiter(&classes, ','); classes = classCopy; if (mainClass!=NULL) { struct rgbColor *col = (struct rgbColor*) hashFindVal(pubsClassColors, mainClass); extra->color = col; @@ -211,30 +223,36 @@ //extra->color = shadesOfGray[yearShade]; } } } } } sqlFreeResult(&sr); return extra; } static void pubsAddExtra(struct track* tg, struct linkedFeatures* lf) /* add authorYear and title to linkedFeatures->extra */ { +// no extra field if we're in dense mode +if (tg->limitedVis == tvDense) + { + return; + } + char *articleTable = trackDbSettingClosestToHome(tg->tdb, "pubsArticleTable"); if(isEmpty(articleTable)) return; if (lf->extra != NULL) return; struct sqlConnection *conn = hAllocConn(database); struct pubsExtra* extra = pubsMakeExtra(tg, articleTable, conn, lf); lf->extra = extra; hFreeConn(&conn); } static void sqlDyStringPrintfWithSep(struct dyString *ds, char* sep, char *format, ...) /* Printf to end of dyString. Prefix with sep if dyString is not empty. */ { @@ -263,30 +281,31 @@ // convert list to hash struct hash *hashA = hashNew(0); struct slName *el; for (el = artIds; el != NULL; el = el->next) hashAddInt(hashA, el->name, 1); freeMem(keywords); slFreeList(artIds); return hashA; } static void pubsLoadKeywordYearItems(struct track *tg) /* load items that fulfill keyword and year filter */ { pubsParseClassColors(); struct sqlConnection *conn = hAllocConn(database); +setFormatFlag(conn, tg->table); char *keywords = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "pubsFilterKeywords"); char *yearFilter = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "pubsFilterYear"); char *publFilter = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "pubsFilterPublisher"); char *articleTable = pubsArticleTable(tg); if(sameOk(yearFilter, "anytime")) yearFilter = NULL; if(sameOk(publFilter, "all")) publFilter = NULL; if(isNotEmpty(keywords)) keywords = makeMysqlMatchStr(keywords); if (isEmpty(yearFilter) && isEmpty(keywords) && isEmpty(publFilter)) { @@ -298,31 +317,31 @@ // without the keywords specified in hgTrackUi char *oldLabel = tg->longLabel; tg->longLabel = catTwoStrings(oldLabel, " (filter activated)"); freeMem(oldLabel); char **row; struct linkedFeatures *lfList = NULL; struct trackDb *tdb = tg->tdb; int scoreMin = atoi(trackDbSettingClosestToHomeOrDefault(tdb, "scoreMin", "0")); int scoreMax = atoi(trackDbSettingClosestToHomeOrDefault(tdb, "scoreMax", "1000")); boolean useItemRgb = bedItemRgb(tdb); char *extra = NULL; struct dyString *extraDy = dyStringNew(0); struct hash *articleIds = searchForKeywords(conn, articleTable, keywords); - if (sqlColumnExists(conn, tg->table, "year")) + if (seqTableFormat==SEQTABLE_NEW) // new table schema: filter fields are on main bed table { if (isNotEmpty(yearFilter)) sqlDyStringPrintfWithSep(extraDy, " AND ", " year >= '%s'", yearFilter); if (isNotEmpty(publFilter)) sqlDyStringPrintfWithSep(extraDy, " AND ", " publisher = '%s'", publFilter); } else // old table schema, filter by doing a join on article table { if(isNotEmpty(yearFilter)) sqlDyStringPrintfFrag(extraDy, "name IN (SELECT articleId FROM %s WHERE year>='%s')", articleTable, \ yearFilter); }