fe16d0f1509b67577e1be5eccd91f5cc205eeec9 tdreszer Tue Nov 29 12:50:01 2011 -0800 Minor efficiency improvements to hgFileUi. Mostly added measureTiming support. diff --git src/hg/lib/fileUi.c src/hg/lib/fileUi.c index a2c0da2..cc3ce3e 100644 --- src/hg/lib/fileUi.c +++ src/hg/lib/fileUi.c @@ -602,33 +602,35 @@ struct fileDb *oneFile = fileDbGet(db, ENCODE_DCC_DOWNLOADS, tdb->track, "supplemental"); if (oneFile != NULL) { printf("<BR>• <B><A HREF='http://%s/goldenPath/%s/%s/%s%s/supplemental/' TARGET=ucscDownloads>supplemental materials</A></B> - any related files provided by the laboratory.\n", server,db,ENCODE_DCC_DOWNLOADS, tdb->track, subDir); } if (hIsPreviewHost()) printf("<BR><b>WARNING</b>: This data is provided for early access via the Preview Browser -- it is unreviewed and subject to change. For high quality reviewed annotations, see the <a target=_blank href='http://%s/cgi-bin/hgTracks?db=%s'>Genome Browser</a>.", "genome.ucsc.edu", db); else printf("<BR><b>NOTE</b>: Early access to additional track data may be available on the <a target=_blank href='http://%s/cgi-bin/hgFileUi?db=%s&g=%s'>Preview Browser</A>.", "genome-preview.ucsc.edu", db, tdb->track); } -static int filesPrintTable(char *db, struct trackDb *parentTdb, struct fileDb *fileList, sortOrder_t *sortOrder,int filterable) +static int filesPrintTable(char *db, struct trackDb *parentTdb, struct fileDb *fileList, sortOrder_t *sortOrder,int filterable,boolean timeIt) // Prints filesList as a sortable table. Returns count { +if (timeIt) + uglyTime("Start table"); // Table class=sortable int columnCount = 0; int restrictedColumn = 0; char *nowrap = (sortOrder->setting != NULL ? " nowrap":""); // Sort order trackDb setting found so rely on <BR> in titles for wrapping printf("<TABLE class='sortable' style='border: 2px outset #006600;'>\n"); printf("<THEAD class='sortable'>\n"); printf("<TR class='sortable' valign='bottom'>\n"); printf("<TD align='center' valign='center'> "); int filesCount = slCount(fileList); if (filesCount > 5) printf("<em><span class='filesCount'></span>%d files</em>",filesCount); //if (sortOrder) // NOTE: This could be done to preserve sort order FIXME: However hgFileUi would need form OR changes would need to be ajaxed over AND hgsid would be needed. // printf("<INPUT TYPE=HIDDEN NAME='%s' class='sortOrder' VALUE=\"%s\">",sortOrder->htmlId, sortOrder->sortOrder); printf("</TD>\n"); @@ -670,148 +672,160 @@ } printf("<TH class='sortable sort%d' align='left' nowrap>Additional Details</TH>\n",++curOrder); columnCount++; printf("</TR></THEAD>\n"); // Now the files... char *server = hDownloadsServer(); char *subDir = ""; if (hIsBetaHost()) { server = "hgdownload-test.cse.ucsc.edu"; // NOTE: Force this case because beta may think it's downloads server is "hgdownload.cse.ucsc.edu" subDir = "/beta"; } struct fileDb *oneFile = fileList; printf("<TBODY class='sortable sorting'>\n"); // 'sorting' is a fib but it conveniently greys the list till the table is initialized. +if (timeIt) + uglyTime("Finished column headers"); for( ;oneFile!= NULL;oneFile=oneFile->next) { oneFile->mdb->next = NULL; // mdbs were in list for generating sortOrder, but list no longer needed char *field = NULL; printf("<TR valign='top'%s>",(filterable != 0) ?" class='filterable'":""); // Download button printf("<TD nowrap>"); if (parentTdb) field = parentTdb->track; else field = mdbObjFindValue(oneFile->mdb,"composite"); assert(field != NULL); printf("<input type='button' value='Download' onclick=\"window.location='http://%s/goldenPath/%s/%s/%s%s/%s';\" title='Download %s ...'>", server,db,ENCODE_DCC_DOWNLOADS, field, subDir, oneFile->fileName, oneFile->fileName); #define SHOW_FOLDER_FRO_COMPOSITE_DOWNLOADS #ifdef SHOW_FOLDER_FRO_COMPOSITE_DOWNLOADS if (parentTdb == NULL) printf(" <A href='../cgi-bin/hgFileUi?db=%s&g=%s' title='Navigate to downloads page for %s set...'><IMG SRC='../images/folderC.png'></a> ", db,field,field); #endif///def SHOW_FOLDER_FRO_COMPOSITE_DOWNLOADS printf("</TD>\n"); // Each of the pulled out mdb vars if (sortOrder) { for(ix=0;ix<sortOrder->count;ix++) { - char *align = (sameString("labVersion",sortOrder->column[ix]) || sameString("softwareVersion",sortOrder->column[ix]) ? " align='left'":" align='center'"); if (sameString("fileSize",sortOrder->column[ix])) { char niceNumber[128]; sprintWithGreekByte(niceNumber, sizeof(niceNumber), oneFile->fileSize); field = oneFile->sortFields[sortOrder->order[ix] - 1]; printf("<TD abbr='%s' align='right' nowrap>%s</td>",field,niceNumber); } else { field = oneFile->sortFields[sortOrder->order[ix] - 1]; - boolean isFieldEmpty = cvTermIsEmpty(sortOrder->column[ix],field); + struct hash *termHash = (struct hash *)cvOneTermHash(sortOrder->column[ix],field); + + boolean isFieldEmpty = isEmpty(field); + if (!isFieldEmpty && termHash && sameString(field,MDB_VAL_ENCODE_EDV_NONE)) + isFieldEmpty = cvTermIsEmpty(sortOrder->column[ix],field); char class[128]; class[0] = '\0'; + if (filterable & (0x1<<ix)) { char *cleanClass = NULL; char buf[256]; if (isFieldEmpty) cleanClass = CV_LABEL_EMPTY_IS_NONE; else { - cleanClass = (char *)cvTag(sortOrder->column[ix],field); // class should be tag + if (termHash) + cleanClass = (char *)hashFindVal((struct hash *)termHash,CV_TAG); if (cleanClass == NULL) { safecpy(buf,sizeof buf,field); cleanClass = buf; eraseNonAlphaNum(cleanClass);// This may not be needed because the filterBy code already eliminated these. } } safef(class,sizeof class," class='%s %s'",sortOrder->column[ix],cleanClass); } + char *align = (sameString("labVersion",sortOrder->column[ix]) || sameString("softwareVersion",sortOrder->column[ix]) ? " align='left'":" align='center'"); if (sameString("dateUnrestricted",sortOrder->column[ix]) && field && dateIsOld(field,"%F")) printf("<TD%s nowrap style='color: #BBBBBB;'%s>%s</td>",align,class,field); else { // use label - if (!isFieldEmpty && cvTermIsCvDefined(sortOrder->column[ix])) - field = (char *)cvLabel(sortOrder->column[ix],field); + if (!isFieldEmpty && termHash) + { + char *label = hashFindVal(termHash,CV_LABEL); + if (label != NULL) + field = label; + } printf("<TD%s nowrap%s>%s</td>",align,class,isFieldEmpty?" ":field); } if (!sameString("fileType",sortOrder->column[ix])) mdbObjRemoveVars(oneFile->mdb,sortOrder->column[ix]); // Remove this from mdb now so that it isn't displayed in "extras' } } } #ifndef INCLUDE_FILENAMES else #endif///ndef INCLUDE_FILENAMES { // fileName printf("<TD nowrap>%s",oneFile->fileName); - //// FIXME: " The "..." encapsulation could be rebuilt so it could be called here - //printf(" <A HREF='#a_meta_%s' onclick='return metadataShowHide(\"%s\",true,true);' title='Show metadata details...'>...</A>", - // oneFile->mdb->obj,oneFile->mdb->obj); - //printf("<DIV id='div_%s_meta' style='display:none;'></div></td>",oneFile->mdb->obj); } // Extras grant=Bernstein; lab=Broad; dataType=ChipSeq; setType=exp; control=std; mdbObjRemoveVars(oneFile->mdb,MDB_VAR_FILENAME " " MDB_VAR_FILEINDEX " " MDB_VAR_COMPOSITE " " MDB_VAR_PROJECT); // Remove this from mdb now so that it isn't displayed in "extras' field = mdbObjVarValPairsAsLine(oneFile->mdb,TRUE,FALSE); printf("<TD nowrap>%s</td>",field?field:" "); printf("</TR>\n"); } +if (timeIt) + uglyTime("Finished files"); printf("</TBODY><TFOOT class='bgLevel1'>\n"); printf("<TR valign='top'>"); // Restriction policy link in first column? if (restrictedColumn == 1) printf("<TH colspan=%d><A HREF='%s' TARGET=BLANK style='font-size:.9em;'>Restriction Policy</A></TH>", (columnCount - restrictedColumn),ENCODE_DATA_RELEASE_POLICY); printf("<TD colspan=%d> ",(restrictedColumn > 1 ? (restrictedColumn - 1) : columnCount)); // Total if (filesCount > 5) printf("<em><span class='filesCount'></span>%d files</em>",filesCount); // Restriction policy link in later column? if (restrictedColumn > 1) printf("</TD><TH colspan=%d align='left'><A HREF='%s' TARGET=BLANK style='font-size:.9em;'>Restriction Policy</A>", columnCount,ENCODE_DATA_RELEASE_POLICY); printf("</TD></TR>\n"); printf("</TFOOT></TABLE>\n"); if (parentTdb == NULL) printf("<script type='text/javascript'>{$(document).ready(function() {sortTableInitialize($('table.sortable')[0],true,true);});}</script>\n"); +if (timeIt) + uglyTime("Finished table"); return filesCount; } static int filesFindInDir(char *db, struct mdbObj **pmdbFiles, struct fileDb **pFileList, char *fileType, int limit,boolean *exceededLimit) // Prints list of files in downloads directories matching mdb search terms. Returns count { int fileCount = 0; // Verify file existance and make fileList of those found struct fileDb *fileList = NULL, *oneFile = NULL; // Will contain found files struct mdbObj *mdbFiles = NULL; // Will caontain a list of mdbs for the found files struct mdbObj *mdbList = *pmdbFiles; while (mdbList && (limit == 0 || fileCount < limit)) { boolean found = FALSE; @@ -934,30 +948,33 @@ if (mdbList != NULL) { if (exceededLimit != NULL) *exceededLimit = TRUE; mdbObjsFree(&mdbList); } return fileCount; } void filesDownloadUi(char *db, struct cart *cart, struct trackDb *tdb) // UI for a "composite like" track: This will list downloadable files associated with // a single trackDb entry (composite or of type "downloadsOnly". The list of files // will have links to their download and have metadata information associated. // The list will be a sortable table and there may be filtering controls. { +boolean timeIt = cartUsualBoolean(cart, "measureTiming",FALSE); +if (timeIt) + uglyTime(NULL); // kicks off timing now boolean debug = cartUsualBoolean(cart,"debug",FALSE); struct sqlConnection *conn = hAllocConn(db); char *mdbTable = mdbTableName(conn,TRUE); // Look for sandBox name first if(mdbTable == NULL) errAbort("TABLE NOT FOUND: '%s.%s'.\n",db,MDB_DEFAULT_NAME); // Get an mdbObj list of all that belong to this track and have a fileName char buf[256]; safef(buf,sizeof(buf),"%s=%s %s=?",MDB_VAR_COMPOSITE,tdb->track,MDB_VAR_FILENAME); struct mdbByVar *mdbVars = mdbByVarsLineParse(buf); struct mdbObj *mdbList = mdbObjsQueryByVars(conn,mdbTable,mdbVars); // Now get Indexes But be sure not to duplicate entries in the list!!! safef(buf,sizeof(buf),"%s=%s %s= %s!=",MDB_VAR_COMPOSITE,tdb->track,MDB_VAR_FILEINDEX,MDB_VAR_FILENAME); @@ -967,30 +984,32 @@ hFreeConn(&conn); if (mdbList) (void)mdbObjsFilter(&mdbList,"objStatus","re*",TRUE); // revoked, replaced, renamed if (slCount(mdbList) == 0) { warn("No files specified in metadata for: %s\n%s",tdb->track,tdb->longLabel); return; } // Verify file existance and make fileList of those found struct fileDb *fileList = NULL; // Will contain found files int fileCount = filesFindInDir(db, &mdbList, &fileList, NULL, 0, NULL); +if (timeIt) + uglyTime("Found %d files in dir",fileCount); assert(fileCount == slCount(fileList)); if (fileCount == 0) { warn("No downloadable files currently available for: %s\n%s",tdb->track,tdb->longLabel); return; // No files so nothing to do. } if (debug) { warn("The following files are in goldenPath/%s/%s/%s/ but NOT in the mdb:",db,ENCODE_DCC_DOWNLOADS, tdb->track); fileDbGet(db, ENCODE_DCC_DOWNLOADS, tdb->track, "listAll"); } jsIncludeFile("hui.js",NULL); jsIncludeFile("ajax.js",NULL); @@ -1002,37 +1021,41 @@ mdbObjReorderByCv(mdbList,FALSE);// Start with cv defined order for visible vars. NOTE: will not need to reorder during print! sortOrder_t *sortOrder = fileSortOrderGet(cart,tdb,mdbList); int filterable = 0; if (sortOrder != NULL) { char *vars = removeCommonMdbVarsNotInSortOrder(mdbList,sortOrder); if (vars) { if (debug) warn("These terms are common:%s",vars); freeMem(vars); } // Fill in and sort fileList fileDbSortList(&fileList,sortOrder); + if (timeIt) + uglyTime("<BR>Sorted %d files on %d columns",fileCount,sortOrder->count); // FilterBoxes filterable = filterBoxesForFilesList(db,mdbList,sortOrder); + if (timeIt && filterable) + uglyTime("Created filter boxes 0x%X",filterable); } // Print table -filesPrintTable(db,tdb,fileList,sortOrder,filterable); +filesPrintTable(db,tdb,fileList,sortOrder,filterable,timeIt); //fileDbFree(&fileList); // Why bother on this very long running cgi? //mdbObjsFree(&mdbList); } int fileSearchResults(char *db, struct sqlConnection *conn, struct slPair *varValPairs, char *fileType) // Prints list of files in downloads directories matching mdb search terms. Returns count { struct sqlConnection *connLocal = conn; if (conn == NULL) connLocal = hAllocConn(db); struct mdbObj *mdbList = mdbObjRepeatedSearch(connLocal,varValPairs,FALSE,TRUE); if (conn == NULL) hFreeConn(&connLocal); @@ -1050,52 +1073,47 @@ mdbObjRemoveHiddenVars(mdbList); #define FOUND_FILE_LIMIT 1000 struct fileDb *fileList = NULL; // Will contain found files int filesExpected = slCount(mdbList); boolean exceededLimit = FALSE; int fileCount = filesFindInDir(db, &mdbList, &fileList, fileType, FOUND_FILE_LIMIT, &exceededLimit); assert(fileCount == slCount(fileList)); if (fileCount == 0) { printf("<DIV id='filesFound'><BR>No files found.<BR></DIV><BR>\n"); return 0; // No files so nothing to do. } -// TODO Could sort on varValPairs by creating a sortOrder struct of them -//// Now update all files with their sortable fields and sort the list +// Now update all files with their sortable fields and sort the list mdbObjReorderByCv(mdbList,FALSE);// Start with cv defined order for visible vars. NOTE: will not need to reorder during print! sortOrder_t *sortOrder = fileSortOrderGet(NULL,NULL,mdbList); // No cart, no tdb if (sortOrder != NULL) { // Fill in and sort fileList fileDbSortList(&fileList,sortOrder); } mdbObjRemoveVars(mdbList,"tableName"); // Remove this from mdb now so that it isn't displayed in "extras' -//jsIncludeFile("hui.js",NULL); -//jsIncludeFile("ajax.js",NULL); - // Print table printf("<DIV id='filesFound'>"); if (exceededLimit) { // What is the expected count? Difficult to say because of comma delimited list in fileName. if (filesExpected <= FOUND_FILE_LIMIT) filesExpected = FOUND_FILE_LIMIT + 1; printf("<DIV class='redBox' style='width: 380px;'>Too many files found. Displaying first %d of at least %d.<BR>Narrow search parameters and try again.</DIV><BR>\n", fileCount,filesExpected); - //warn("Too many files found. Displaying first %d of at least %d.<BR>Narrow search parameters and try again.\n", fileCount,filesExpected); } -fileCount = filesPrintTable(db,NULL,fileList,sortOrder,0); // FALSE=Don't offer more filtering on the file search page +fileCount = filesPrintTable(db,NULL,fileList,sortOrder,0,FALSE); // 0=No columns are 'filtered' on the file search page printf("</DIV><BR>\n"); //fileDbFree(&fileList); // Why bother on this very long running cgi? //mdbObjsFree(&mdbList); return fileCount; }