dc4dc74eb9e0b860f56347141d6d3e1ae76bd9ad
braney
  Fri May 30 15:09:18 2014 -0700
clean up some code for opening trackHubs, removed hgHubConnectCgiDestUrlcart variable, added ability to tell CGI's to default to a particular
database supported by a hub

diff --git src/hg/lib/trackHub.c src/hg/lib/trackHub.c
index eba6341..918bf30 100644
--- src/hg/lib/trackHub.c
+++ src/hg/lib/trackHub.c
@@ -38,31 +38,32 @@
 #include "twoBit.h"
 #include "dbDb.h"
 #include "net.h"
 #include "bbiFile.h"
 #include "bPlusTree.h"
 #include "hgFind.h"
 #include "hubConnect.h"
 #include "trix.h"
 #include "vcf.h"
 #include "htmshell.h"
 #include "hubConnect.h"
 
 static struct hash *hubCladeHash;  // mapping of clade name to hub pointer
 static struct hash *hubAssemblyHash; // mapping of assembly name to genome struct
 static struct hash *hubOrgHash;   // mapping from organism name to hub pointer
-struct trackHub *globalAssemblyHubList; // list of trackHubs in the user's cart
+static struct trackHub *globalAssemblyHubList; // list of trackHubs in the user's cart
+static struct hash *trackHubHash;
 
 char *trackHubRelativeUrl(char *hubUrl, char *path)
 /* Return full path (in URL form if it's a remote hub) given
  * path possibly relative to hubUrl. Do a freeMem of result
  * when done. */
 {
 /* If path itself is a URL then just return a copy of it. */
 if (hasProtocol(path))
     return cloneString(path);
 
 /* If it's a remote hub, let html path expander handle it. */
 if (hasProtocol(hubUrl))
     return expandUrlOnBase(hubUrl, path);
 
 /* If we got to here hub is local, and so is path.  Do standard
@@ -438,30 +439,32 @@
  * Also add it to hash, which is keyed by genome. */
 {
 struct lineFile *lf = udcWrapShortLineFile(url, NULL, 64*1024*1024);
 struct trackHubGenome *list = NULL, *el;
 struct hash *hash = hub->genomeHash;
 
 struct hash *ra;
 while ((ra = raNextRecord(lf)) != NULL)
     {
     char *twoBitPath = hashFindVal(ra, "twoBitPath");
     char *genome;
     if (twoBitPath != NULL)
 	genome = addHubName(hashFindVal(ra, "genome"), hub->name);
     else
 	genome = hashFindVal(ra, "genome");
+    if (hub->defaultDb == NULL)
+	hub->defaultDb = genome;
     if (genome == NULL)
         badGenomeStanza(lf);
     if (hashLookup(hash, genome) != NULL)
         errAbort("Duplicate genome %s in stanza ending line %d of %s",
 		genome, lf->lineIx, lf->fileName);
     char *trackDb = hashFindVal(ra, "trackDb");
     if (trackDb == NULL)
         badGenomeStanza(lf);
     AllocVar(el);
     el->name = cloneString(genome);
     el->trackDbFile = trackHubRelativeUrl(url, trackDb);
     el->trackHub = hub;
     hashAdd(hash, el->name, el);
     slAddHead(&list, el);
     char *groups = hashFindVal(ra, "groups");
@@ -501,104 +504,137 @@
 char *trackHubSetting(struct trackHub *hub, char *name)
 /* Return setting if it exists, otherwise NULL. */
 {
 return hashFindVal(hub->settings, name);
 }
 
 char *trackHubRequiredSetting(struct trackHub *hub, char *name)
 /* Return named setting.  Abort with error message if not found. */
 {
 char *val = trackHubSetting(hub, name);
 if (val == NULL)
     errAbort("Missing required setting '%s' from %s", name, hub->url);
 return val;
 }
 
+static struct trackHub *grabHashedHub(char *hubName)
+/* see if a trackHub with this name is in the cache */
+{
+if ( trackHubHash == NULL)
+    trackHubHash = newHash(5);
+
+return  (struct trackHub *)hashFindVal(trackHubHash, hubName); 
+}
+
+static void cacheHub(struct trackHub *hub)
+{
+/* put this trackHub in the trackHub hash */
+if ( trackHubHash == NULL)
+    trackHubHash = newHash(5);
+
+hashAdd(trackHubHash, hub->name, hub);
+}
+
+void uncacheHub(struct trackHub *hub)
+/* take this trackHub out of the trackHub hash */
+{
+if ( trackHubHash == NULL)
+    return;
+
+hashMustRemove(trackHubHash, hub->name);
+}
+
 struct trackHub *trackHubOpen(char *url, char *hubName)
 /* Open up a track hub from url.  Reads and parses hub.txt and the genomesFile. 
  * The hubName is generally just the asciified ID number. */
 {
+struct trackHub *hub = grabHashedHub(hubName);
+
+if (hub != NULL)
+    return hub;
+
 struct lineFile *lf = udcWrapShortLineFile(url, NULL, 256*1024);
 struct hash *hubRa = raNextRecord(lf);
 if (hubRa == NULL)
     errAbort("empty %s in trackHubOpen", url);
 if (raNextRecord(lf) != NULL)
     errAbort("multiple records in %s", url);
 
 /* Allocate hub and fill in settings field and url. */
-struct trackHub *hub;
 AllocVar(hub);
 hub->url = cloneString(url);
 hub->name = cloneString(hubName);
 hub->settings = hubRa;
 
 /* Fill in required fields from settings. */
 trackHubRequiredSetting(hub, "hub");
 trackHubRequiredSetting(hub, "email");
 hub->shortLabel = trackHubRequiredSetting(hub, "shortLabel");
 hub->longLabel = trackHubRequiredSetting(hub, "longLabel");
 hub->genomesFile = trackHubRequiredSetting(hub, "genomesFile");
 char *descriptionUrl = trackHubSetting(hub, "descriptionUrl");
 if (descriptionUrl != NULL)
     hub->descriptionUrl = trackHubRelativeUrl(hub->url, descriptionUrl);
 
 lineFileClose(&lf);
 char *genomesUrl = trackHubRelativeUrl(hub->url, hub->genomesFile);
 
 hub->genomeHash = hashNew(8);
 hub->genomeList = trackHubGenomeReadRa(genomesUrl, hub);
 freez(&genomesUrl);
 
+cacheHub(hub);
 return hub;
 }
 
 void trackHubClose(struct trackHub **pHub)
 /* Close up and free resources from hub. */
 {
 struct trackHub *hub = *pHub;
 if (hub != NULL)
     {
     trackHubGenomeFreeList(hub);
     freeMem(hub->url);
     hashFree(&hub->settings);
     hashFree(&hub->genomeHash);
+    uncacheHub(hub);
     freez(pHub);
     }
 }
 
 void trackHubGenomeFree(struct trackHubGenome **pGenome)
 /* Free up genome info. */
 {
 struct trackHubGenome *genome = *pGenome;
 if (genome != NULL)
     {
     freeMem(genome->name);
     freeMem(genome->trackDbFile);
     freez(pGenome);
     }
 }
 
 void trackHubGenomeFreeList(struct trackHub *hub)
 /* Free a list of dynamically allocated trackHubGenome's */
 {
 struct trackHubGenome *el, *next;
 
 for (el = hub->genomeList; el != NULL; el = next)
     {
     next = el->next;
     if (el->twoBitPath != NULL)
-	deleteAssembly(hub->name, el, hub);
+	deleteAssembly(el->name, el, hub);
     trackHubGenomeFree(&el);
     }
 hub->genomeList = NULL;
 }
 
 static char *requiredSetting(struct trackHub *hub, struct trackHubGenome *genome,
 	struct trackDb *tdb, char *setting)
 /* Fetch setting or give an error message, a little more specific than the
  * error message from trackDbRequiredSetting(). */
 {
 char *val = trackDbSetting(tdb, setting);
 if (val == NULL)
     errAbort("Missing required '%s' setting in hub %s genome %s track %s", setting,
     	hub->url, genome->name, tdb->track);
 return val;