01dd700b0b41f2e24a587722bc68fe931283ae05 tdreszer Tue Oct 25 17:27:57 2011 -0700 No functional change. Just better commenting and some name changing as requested by Brian in code review. diff --git src/hg/lib/fileUi.c src/hg/lib/fileUi.c index 72972a1..a4afa16 100644 --- src/hg/lib/fileUi.c +++ src/hg/lib/fileUi.c @@ -20,96 +20,87 @@ { while (pFileList && *pFileList) { struct fileDb *oneFile = slPopHead(pFileList); freeMem(oneFile->fileName); freeMem(oneFile->fileType); freeMem(oneFile->fileDate); freeMem(oneFile->sortFields); freeMem(oneFile->reverse); mdbObjsFree(&(oneFile->mdb)); freeMem(oneFile); } } -static struct fileDb *fileDbReadFromCache(char *db, char *dir, char *subDir) +static struct fileDb *fileDbReadFromBackup(char *db, char *dir, char *subDir) { -struct tempName cacheFile; -boolean exists = trashDirReusableFile(&cacheFile, dir, subDir, db); // encodeDCC/composite.db +struct tempName buFile; +boolean exists = trashDirReusableFile(&buFile, dir, subDir, db); // encodeDCC/composite.db if (!exists) return NULL; -//warn("Reading: %s",cacheFile.forCgi); struct fileDb *fileList = NULL; struct fileDb *oneFile = NULL; -struct lineFile *lf = lineFileOpen(cacheFile.forCgi, TRUE); +struct lineFile *lf = lineFileOpen(buFile.forCgi, TRUE); char *words[4]; while (lineFileChop(lf, words) >= 3) { AllocVar(oneFile); oneFile->fileName = cloneString(words[0]); oneFile->fileSize = sqlUnsignedLong(words[1]); oneFile->fileDate = cloneString(words[2]); slAddHead(&fileList,oneFile); } lineFileClose(&lf); if (fileList == NULL) - unlink(cacheFile.forCgi); // remove empty file + unlink(buFile.forCgi); // remove empty file return fileList; } // Cache is not faster, so just use it as a backup //#define CACHE_IS_FASTER_THAN_RSYNC #ifdef CACHE_IS_FASTER_THAN_RSYNC -static boolean fileDbCacheAvailable(char *db, char *dir, char *subDir) +static boolean fileDbBackupAvailable(char *db, char *dir, char *subDir) { // Checks if there is a recent enough cache file // TODO: Add some other trick to invalidate cache at will. -struct tempName cacheFile; -boolean exists = trashDirReusableFile(&cacheFile, dir, subDir, db); // encodeDCC/composite.db +struct tempName buFile; +boolean exists = trashDirReusableFile(&buFile, dir, subDir, db); // encodeDCC/composite.db if (exists) { - //char *clearCache = cartOptionalString(cart,"clearCache"); // where is cart coming from? - //if (clearCache && sameWord(clearCache,subDir)) - // { - // cartRemove(cart,"clearCache"); - // unlink(cacheFile.forCgi); // remove empty file - // return FALSE; - // } struct stat mystat; ZeroVar(&mystat); - if (stat(cacheFile.forCgi,&mystat)==0) + if (stat(buFile.forCgi,&mystat)==0) { // how old is old? int secs = (clock1() - mystat.st_ctime); // seconds since created if (secs < (24 * 60 * 60)) // one date return TRUE; } } return FALSE; } #endif///def CACHE_IS_FASTER_THAN_RSYNC -static void fileDbWriteToCache(char *db, char *dir, char *subDir,struct fileDb *fileList) +static void fileDbWriteToBackup(char *db, char *dir, char *subDir,struct fileDb *fileList) { -struct tempName cacheFile; -(void)trashDirReusableFile(&cacheFile, dir, subDir, db); // encodeDCC/composite.db -//warn("Writing: %s",cacheFile.forCgi); +struct tempName buFile; +(void)trashDirReusableFile(&buFile, dir, subDir, db); // encodeDCC/composite.db FILE *fd = NULL; -if ((fd = fopen(cacheFile.forCgi, "w")) != NULL) +if ((fd = fopen(buFile.forCgi, "w")) != NULL) { struct fileDb *oneFile = fileList; for(;oneFile != NULL;oneFile=oneFile->next) { char buf[1024]; safef(buf,sizeof buf,"%s %ld %s\n",oneFile->fileName,oneFile->fileSize,oneFile->fileDate); fwrite(buf, strlen(buf), 1, fd); } fclose(fd); } } struct fileDb *fileDbGet(char *db, char *dir, char *subDir, char *fileName) // Returns NULL or if found a fileDb struct with name, size and date filled in. { @@ -118,34 +109,32 @@ static char *savedSubDir = NULL; static struct fileDb *foundFiles = NULL;// Use static list to save excess IO struct fileDb *oneFile = NULL; if (foundFiles == NULL || savedDb == NULL || differentString(savedDb, db) || savedDir == NULL || differentString(savedDir,dir) || savedSubDir == NULL || differentString(savedSubDir,subDir)) { // free up any static mem freeMem(savedDb); freeMem(savedDir); freeMem(savedSubDir); fileDbFree(&foundFiles); #ifdef CACHE_IS_FASTER_THAN_RSYNC - if (fileDbCacheAvailable(db, dir, subDir)) // check cache first - { - foundFiles = fileDbReadFromCache(db, dir, subDir); - } + if (fileDbBackupAvailable(db, dir, subDir)) // check backup first + foundFiles = fileDbReadFromBackup(db, dir, subDir); else #endif///def CACHE_IS_FASTER_THAN_RSYNC { FILE *scriptOutput = NULL; char buf[1024]; char cmd[512]; char *words[10]; char *server = hDownloadsServer(); boolean useRsync = TRUE; // Works: rsync -avn rsync://hgdownload.cse.ucsc.edu/goldenPath/hg18/encodeDCC/wgEncodeBroadChipSeq/ if (hIsBetaHost()) safef(cmd,sizeof(cmd),"rsync -n rsync://hgdownload-test.cse.ucsc.edu/goldenPath/%s/%s/%s/beta/", db, dir, subDir); // NOTE: Force this case because beta may think it's downloads server is "hgdownload.cse.ucsc.edu" else safef(cmd,sizeof(cmd),"rsync -n rsync://%s/goldenPath/%s/%s/%s/", server, db, dir, subDir); @@ -174,42 +163,42 @@ { //-rw-rw-r-- 26420982 2009/09/29 14:53:30 wgEncodeBroadChipSeq/wgEncodeBroadChipSeqSignalNhlfH4k20me1.wig.gz AllocVar(oneFile); oneFile->fileSize = sqlUnsignedLong(words[1]); oneFile->fileDate = cloneString(words[2]); strSwapChar(oneFile->fileDate,'/','-');// Standardize YYYY-MM-DD, no time oneFile->fileName = cloneString(words[4]); slAddHead(&foundFiles,oneFile); } //warn("File:%s size:%ld",foundFiles->fileName,foundFiles->fileSize); } } pclose(scriptOutput); if (foundFiles == NULL) { - foundFiles = fileDbReadFromCache(db, dir, subDir); + foundFiles = fileDbReadFromBackup(db, dir, subDir); if (foundFiles == NULL) { AllocVar(oneFile); oneFile->fileName = cloneString("No files found!"); oneFile->fileDate = cloneString(cmd); slAddHead(&foundFiles,oneFile); warn("No files found for command:\n%s",cmd); } } else - fileDbWriteToCache(db, dir, subDir,foundFiles); + fileDbWriteToBackup(db, dir, subDir,foundFiles); } // mark this as done to avoid excessive io savedDb = cloneString(db); savedDir = cloneString(dir); savedSubDir = cloneString(subDir); if (foundFiles == NULL) return NULL; } // special code that only gets called in debug mode if (sameString(fileName,"listAll")) { for(oneFile=foundFiles;oneFile;oneFile=oneFile->next) @@ -478,30 +467,37 @@ { char *var = sortOrder->column[sIx]; enum cvSearchable searchBy = cvSearchMethod(var); //#define FILTERBY_ALL_SEARCHABLE #ifdef FILTERBY_ALL_SEARCHABLE if (searchBy == cvNotSearchable) #else///ifndef FILTERBY_ALL_SEARCHABLE if (searchBy == cvNotSearchable || searchBy == cvSearchByFreeText) #endif///ndef FILTERBY_ALL_SEARCHABLE continue; // Only single selects and multi-select make good candidates for filtering // get all vals for var, then convert to tag/label pairs for filterBys struct slName *vals = mdbObjsFindAllVals(mdbObjs, var, CV_LABEL_EMPTY_IS_NONE); if (searchBy != cvSearchByMultiSelect && searchBy != cvSearchBySingleSelect) { + // We can't be too ambitious about creating filterboxes on the fly so some limitations: + // If there are more than 80 options, the filterBy is way too large and of limited use + // If there is a distinct val for each file in the table, then the filterBy is the same size + // as the table and of no help. Really the number of options should be half the number of rows + // but we are being lenient and cutting off at 0.8 not 0.5 + // If there is any non-alphanum char in a value then the filterBy will fail in js code. + // Those filterBy's are abandoned a but further down. int valCount = slCount(vals); if (valCount > 80 || valCount > (slCount(mdbObjs) * 0.8)) { slNameFreeList(&vals); continue; } } struct slPair *tagLabelPairs = NULL; while(vals != NULL) { char buf[256]; struct slName *term = slPopHead(&vals); char *tag = (char *)cvTag(var,term->name); if (tag == NULL) // Does not require cv defined! { @@ -535,32 +531,32 @@ slPairValSortCase(&tagLabelPairs); char extraClasses[256]; safef(extraClasses,sizeof extraClasses,"filterTable %s",var); #ifdef NEW_JQUERY char *dropDownHtml = cgiMakeMultiSelectDropList(var,tagLabelPairs,NULL,"All",extraClasses,"onchange='filterTable(this);' style='font-size:.9em;'"); #else///ifndef NEW_JQUERY char *dropDownHtml = cgiMakeMultiSelectDropList(var,tagLabelPairs,NULL,"All",extraClasses,"onchange='filterTable();' onclick='filterTableExclude(this);'"); #endif///ndef NEW_JQUERY // Note filterBox has classes: filterBy & {var} if (dropDownHtml) { dyStringPrintf(dyFilters,"\n%s:
\n%s \n", labelWithVocabLink(var,sortOrder->title[sIx],tagLabelPairs,TRUE),dropDownHtml); // TRUE were sending tags, not values freeMem(dropDownHtml); count++; + if (sIx < 64) // avoid bit overflow but 64 filterBoxes? I don't think so filterableBits |= (0x1<<(sIx)); - //warn("count:%d sIx:%d retBits:%X",count,sIx,filterableBits); } } if (tagLabelPairs != NULL) slPairFreeValsAndList(&tagLabelPairs); } // Finally ready to print the filterBys out if (count) { webIncludeResourceFile("ui.dropdownchecklist.css"); jsIncludeFile("ui.dropdownchecklist.js",NULL); #define FILTERBY_HELP_LINK "help" cgiDown(0.9); printf("Filter files by: (select multiple %sitems - %s)\n\n", (count >= 1 ? "categories and ":""),FILTERBY_HELP_LINK);