79ab7bed49d3d2a550d372fb58ab4bb283a6d31e braney Thu Jan 30 00:08:47 2020 -0800 append trackDb names to the end of the db for trackDb cache directory to support comma-separated lists of trackDb tables diff --git src/hg/lib/trackDbCache.c src/hg/lib/trackDbCache.c index dd4046c..e42c047 100644 --- src/hg/lib/trackDbCache.c +++ src/hg/lib/trackDbCache.c @@ -139,53 +139,62 @@ for(tdb = list; tdb; tdb = tdb->next) { struct trackDb *newTdb = lmCloneTdb(lm, tdb, parent, superHash); if (prevTdb) prevTdb->next = newTdb; else newList = newTdb; prevTdb = newTdb; } return newList; } +static char *cacheDirForDbAndTable(char *string, char *tdbPathString) +/* Determine the directory name for the trackDb cache files */ +{ +char dirName[4096]; +if (tdbPathString == NULL) + safef(dirName, sizeof dirName, "%s/%s", trackDbCacheDir, string); +else + safef(dirName, sizeof dirName, "%s/%s.%s", trackDbCacheDir, string, tdbPathString); + +return cloneString(dirName); +} -static struct trackDb *checkCache(char *string, time_t time) +static struct trackDb *checkCache(char *string, char *tdbPathString, time_t time) /* Check to see if this db or hub has a cached trackDb. string is either a db * or a SHA1 calculated from a hubUrl. Use time to see if cache should be flushed. */ { -char dirName[4096]; - -safef(dirName, sizeof dirName, "%s/%s", trackDbCacheDir, string); +char *dirName = cacheDirForDbAndTable(string, tdbPathString); if (!isDirectory(dirName)) { cacheLog("abandoning cache search for %s, no directory", string); return NULL; } // look for files named by the address they use struct slName *files = listDir(dirName, "*"); char fileName[4096]; for(; files; files = files->next) { if (sameString(files->name, "name.txt")) continue; - safef(fileName, sizeof fileName, "%s/%s/%s", trackDbCacheDir, string, files->name); + safef(fileName, sizeof fileName, "%s/%s", dirName, files->name); cacheLog("checking cache file %s", fileName); struct stat statBuf; if (stat(fileName, &statBuf) < 0) { // if we can't stat the shared memory, let's just toss it cacheLog("can't stat file %s, unlinking", fileName); mustRemove(fileName); continue; } if (statBuf.st_mtime < time) { // if the cache is older than the data, toss it cacheLog("cache is older than source, unlinking"); @@ -230,74 +239,73 @@ u_char *ret = mem + lmBlockHeaderSize(); maybeTouchFile(fileName); cacheLog("using cache memory at %lx", ret); return (struct trackDb *)ret; } cacheLog("unmapping cache memory at %lx", mem); munmap((void *)mem, size); close(fd); } cacheLog("abandoning cache search for %s", string); return NULL; } -struct trackDb *trackDbCache(char *db, time_t time) +struct trackDb *trackDbCache(char *db, char *tdbPathString, time_t time) /* Check to see if this db has a cached trackDb. */ { -cacheLog("checking for cache for db %s at time %ld", db, time); -return checkCache(db, time); +cacheLog("checking for cache for db %s tdbPathString %s at time %ld", db, tdbPathString, time); +return checkCache(db, tdbPathString, time); } struct trackDb *trackDbHubCache(char *trackDbUrl, time_t time) { cacheLog("checking for cache for hub %s at time %ld", trackDbUrl, time); unsigned char hash[SHA_DIGEST_LENGTH]; SHA1((const unsigned char *)trackDbUrl, strlen(trackDbUrl), hash); char newName[(SHA_DIGEST_LENGTH + 1) * 2]; hexBinaryString(hash, SHA_DIGEST_LENGTH, newName, (SHA_DIGEST_LENGTH + 1) * 2); -return checkCache(newName, time); +return checkCache(newName, NULL, time); } -static void cloneTdbListToSharedMem(char *string, struct trackDb *list, unsigned long size, char *name) +static void cloneTdbListToSharedMem(char *string, char *tdbPathString, struct trackDb *list, unsigned long size, char *name) /* Allocate shared memory and clone trackDb list into it. */ { static int inited = 0; if (inited == 0) { srandom(time(NULL)); inited = 1; } int oflags=O_RDWR | O_CREAT; -char dirName[4096]; -safef(dirName, sizeof dirName, "%s/%s", trackDbCacheDir, string); +char *dirName = cacheDirForDbAndTable(string, tdbPathString); if (!isDirectory(dirName)) { cacheLog("making directory %s", dirName); makeDir(dirName); chmod(dirName, 0777); } char tempFileName[4096]; -safef(tempFileName, sizeof tempFileName, "%s/%s", trackDbCacheDir, rTempName(string, "temp", "")); +safef(tempFileName, sizeof tempFileName, "%s", rTempName(dirName, "temp", "")); int fd = open(tempFileName, oflags, 0666 ); if (fd < 0) { cacheLog("unable to open shared memory %s errno %d", tempFileName, errno); mustRemove(tempFileName); return; } else { cacheLog("open shared memory %s", tempFileName); } ftruncate(fd, 0); ftruncate(fd, size); @@ -335,62 +343,65 @@ lmCloneTdbList(lm, list, NULL, superHash); unsigned long memUsed = lmUsed(lm) + lmBlockHeaderSize(); cacheLog("cloning tdbList %p used %ld bytes called with %ld", list, memUsed, size); msync((void *)paddress, memUsed, MS_SYNC); ftruncate(fd, memUsed); // for the moment we're not unmapping these so multiple attached hubs will get // different addresses //munmap((void *)paddress, size); //close(fd); char fileName[4096]; -safef(fileName, sizeof fileName, "%s/%s/%ld.%d", trackDbCacheDir, string, paddress, TRACKDB_VERSION); +safef(fileName, sizeof fileName, "%s/%ld.%d", dirName, paddress, TRACKDB_VERSION); cacheLog("renaming %s to %s", tempFileName, fileName); mustRename(tempFileName, fileName); // write out the name of the trackDb being cached. -safef(fileName, sizeof fileName, "%s/%s/name.txt", trackDbCacheDir, string); +safef(fileName, sizeof fileName, "%s/name.txt", dirName); FILE *stream = mustOpen(fileName, "w"); +if (tdbPathString == NULL) fprintf(stream, "%s\n", name); +else + fprintf(stream, "%s.%s\n", name,tdbPathString); carefulClose(&stream); } -void trackDbCloneTdbListToSharedMem(char *db, struct trackDb *list, unsigned long size) +void trackDbCloneTdbListToSharedMem(char *db, char *tdbPathString, struct trackDb *list, unsigned long size) /* For this native db, allocate shared memory and clone trackDb list into it. */ { cacheLog("cloning memory for db %s %ld", db, size); -cloneTdbListToSharedMem(db, list, size, db); +cloneTdbListToSharedMem(db, tdbPathString, list, size, db); } void trackDbHubCloneTdbListToSharedMem(char *trackDbUrl, struct trackDb *list, unsigned long size) /* For this hub, Allocate shared memory and clone trackDb list into it. */ { if ((*trackDbUrl == '.') || (list == NULL)) // don't cache empty lists or collections return; cacheLog("cloning memory for hub %s %ld", trackDbUrl, size); unsigned char hash[SHA_DIGEST_LENGTH]; SHA1((const unsigned char *)trackDbUrl, strlen(trackDbUrl), hash); char newName[(SHA_DIGEST_LENGTH + 1) * 2]; hexBinaryString(hash, SHA_DIGEST_LENGTH, newName, (SHA_DIGEST_LENGTH + 1) * 2); -cloneTdbListToSharedMem(newName, list, size, trackDbUrl); +cloneTdbListToSharedMem(newName, NULL, list, size, trackDbUrl); } boolean trackDbCacheOn() /* Check to see if we're caching trackDb contents. */ { static boolean checkedCache = FALSE; static boolean doCache = FALSE; if (!checkedCache) { trackDbCacheDir = cfgOption("cacheTrackDbDir"); if (isNotEmpty(trackDbCacheDir)) { makeDirsOnPath(trackDbCacheDir); doCache = TRUE;