0689a6e26d5552dd64fdd4263985e1857236fd92
braney
  Wed Oct 31 12:21:17 2018 -0700
enable view caching on native tracks

diff --git src/hg/lib/trackDbCustom.c src/hg/lib/trackDbCustom.c
index a6d2919..12bb0f9 100644
--- src/hg/lib/trackDbCustom.c
+++ src/hg/lib/trackDbCustom.c
@@ -402,90 +402,102 @@
 struct trackDb *trackDbFromRa(char *raFile, char *releaseTag)
 /* Load track info from ra file into list.  If releaseTag is non-NULL
  * then only load tracks that mesh with release. */
 {
 struct lineFile *lf = udcWrapShortLineFile(raFile, NULL, 16*1024*1024);
 struct trackDb *tdbList = trackDbFromOpenRa(lf, releaseTag);
 lineFileClose(&lf);
 return tdbList;
 }
 
 struct hash *trackDbHashSettings(struct trackDb *tdb)
 /* Force trackDb to hash up it's settings.  Usually this is just
  * done on demand. Returns settings hash. */
 {
 if (tdb->settingsHash == NULL)
-    tdb->settingsHash = trackDbSettingsFromString(tdb->settings);
+    tdb->settingsHash = trackDbSettingsFromString(tdb, tdb->settings);
 return tdb->settingsHash;
 }
 
-struct hash *trackDbSettingsFromString(char *string)
+struct hash *trackDbSettingsFromString(struct trackDb *tdb, char *string)
 /* Return hash of key/value pairs from string.  Differs
  * from raFromString in that it passes the key/val
  * pair through the backwards compatability routines. */
 {
 char *dupe = cloneString(string);
 char *s = dupe, *lineEnd;
 struct hash *hash = newHash(7);
 char *key, *val;
 
 for (;;)
     {
     s = skipLeadingSpaces(s);
     if (s == NULL || s[0] == 0)
         break;
     lineEnd = strchr(s, '\n');
     if (lineEnd != NULL)
         *lineEnd++ = 0;
     key = nextWord(&s);
     val = skipLeadingSpaces(s);
     trackDbUpdateOldTag(&key, &val);
     s = lineEnd;
     val = lmCloneString(hash->lm, val);
     hashAdd(hash, key, val);
+    if (tdb && startsWith("subGroup", key))
+        {
+        char *storeValue = cloneString(val);
+        char *ptr = strchr(val, ' ');
+        if (ptr)
+            *ptr = 0;
+        if (tdb->viewHash == NULL)
+            tdb->viewHash = newHash(5);
+        hashAdd(tdb->viewHash, val, storeValue);
+        if (ptr)
+            *ptr = ' ';
+        }
     }
 freeMem(dupe);
 return hash;
 }
 
 char *trackDbViewSetting(struct trackDb *tdb, char *name)
 /* Return view setting from tdb, but *not* any of it's parents. */
 {
 if (tdb == NULL)
     errAbort("Program error: null tdb passed to trackDbSetting.");
 if (tdb->viewHash == NULL)
     return NULL;
 return hashFindVal(tdb->viewHash, name);
 }
 
 char *trackDbLocalSetting(struct trackDb *tdb, char *name)
 /* Return setting from tdb, but *not* any of it's parents. */
 {
 if (tdb == NULL)
     errAbort("Program error: null tdb passed to trackDbSetting.");
 if (tdb->settingsHash == NULL)
-    tdb->settingsHash = trackDbSettingsFromString(tdb->settings);
+    tdb->settingsHash = trackDbSettingsFromString(tdb, tdb->settings);
 return hashFindVal(tdb->settingsHash, name);
 }
 
 struct slName *trackDbLocalSettingsWildMatch(struct trackDb *tdb, char *expression)
 // Return local settings that match expression else NULL.  In alpha order.
 {
 if (tdb == NULL)
     errAbort("Program error: null tdb passed to trackDbSetting.");
 if (tdb->settingsHash == NULL)
-    tdb->settingsHash = trackDbSettingsFromString(tdb->settings);
+    tdb->settingsHash = trackDbSettingsFromString(tdb, tdb->settings);
 
 struct slName *slFoundVars = NULL;
 struct hashCookie brownie = hashFirst(tdb->settingsHash);
 struct hashEl* el = NULL;
 while ((el = hashNext(&brownie)) != NULL)
     {
     if (wildMatch(expression, el->name))
         slNameAddHead(&slFoundVars, el->name);
     }
 
 if (slFoundVars != NULL)
     slNameSort(&slFoundVars);
 
 return slFoundVars;
 }