3c7a0656f98136df2c2b6c2d5e36baea9e3bf8bc
braney
  Wed Jan 1 14:10:09 2020 -0800
add version number to trackDb cache so if the trackDb structure changes,
the "wrong" cached values won't be used.

diff --git src/hg/lib/trackDbCache.c src/hg/lib/trackDbCache.c
index e2df856..3646442 100644
--- src/hg/lib/trackDbCache.c
+++ src/hg/lib/trackDbCache.c
@@ -158,67 +158,89 @@
 {
 char dirName[4096];
 
 safef(dirName, sizeof dirName, "%s/%s", trackDbCacheDir, string);
 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);
     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");
         mustRemove(fileName);
         continue;
         }
 
     int oflags = O_RDONLY;
     int fd = open(fileName, oflags);
     if (fd < 0)
         {
         cacheLog("cannot open %s", fileName);
         continue;
         }
 
-    unsigned long address = atoi(files->name); // the name of the file is the address it uses
+    char *addressString = cloneString(files->name);
+    char *dot = strchr(addressString, '.');
+    if (dot == NULL)
+        {
+        cacheLog("no dot in  %s", addressString);
+        continue;
+        }
+
+    unsigned cachedStructVersion = atoi(dot + 1);
+    cacheLog("cached trackDb version %d, should be %d in  %s", cachedStructVersion, TRACKDB_VERSION,  addressString);
+
+    if (TRACKDB_VERSION != cachedStructVersion)
+        {
+        cacheLog("wrong cached trackDb version %d, should be %d in  %s", cachedStructVersion, TRACKDB_VERSION,  addressString);
+        continue;
+        }
+
+    *dot = 0;
+    unsigned long address = atoi(addressString); // the name of the file is the address it uses plus TRACKDB_VERSION
     unsigned long size = fileSize(fileName);
 
     u_char *mem = (u_char *) mmap((void *)address, size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
     cacheLog("asked for memory %lx of size %ld, got %lx",address, size, mem);
 
     if ((unsigned long)mem == address)  // make sure we can get this address
         {
         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)
 /* Check to see if this db has a cached trackDb. */
@@ -313,31 +335,31 @@
 
 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", trackDbCacheDir, string, paddress);
+safef(fileName, sizeof fileName, "%s/%s/%ld.%d", trackDbCacheDir, string, 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);
 FILE *stream = mustOpen(fileName, "w");
 fprintf(stream, "%s\n", name);
 carefulClose(&stream);
 }
 
 void trackDbCloneTdbListToSharedMem(char *db, 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);