c6ce277e36a537437a04146c8fa7adebb40428ff
chmalee
  Wed May 15 12:10:42 2024 -0700
Libify some searching code so checkHgFindSpec can use it. Make checkHgFindSpec use the same code path as hgSearch so it can correctly test the search correctly, refs #33731

diff --git src/hg/cgilib/cartTrackDb.c src/hg/cgilib/cartTrackDb.c
index 8fd7fff..13a2e85 100644
--- src/hg/cgilib/cartTrackDb.c
+++ src/hg/cgilib/cartTrackDb.c
@@ -6,30 +6,38 @@
 #include "customTrack.h"
 #include "hash.h"
 #include "hCommon.h"
 #include "hdb.h"
 #include "hgConfig.h"
 #include "hgMaf.h"
 #include "hubConnect.h"
 #include "joiner.h"
 #include "trackHub.h"
 #include "wikiTrack.h"
 
 /* Static globals */
 static boolean useAC = FALSE;
 static struct slRef *accessControlTrackRefList = NULL;
 
+/* Caches used for searching */
+struct trackDb *hgFindTdbList = NULL;
+struct grp *hgFindGrpList = NULL;
+struct hash *hgFindGroupHash = NULL;
+
+/* Also used by hgFind and defined there */
+extern struct hash *hgFindTrackHash;
+
 static struct trackDb *getFullTrackList(struct cart *cart, char *db, struct grp **pHubGroups)
 {
 struct trackDb *list = hTrackDb(db);
 
 /* add wikiTrack if enabled */
 if (wikiTrackEnabled(db, NULL))
     slAddHead(&list, wikiTrackDb());
 slSort(&list, trackDbCmp);
 
 // Add hub tracks at head of list
 struct trackDb *hubTdbList = hubCollectTracks(db, pHubGroups);
 list = slCat(list, hubTdbList);
 
 /* exclude any track with a 'tableBrowser off' setting */
 struct trackDb *tdb, *nextTdb, *newList = NULL;
@@ -485,15 +493,87 @@
                 }
             if (!hashLookup(uniqHash, s))
                 {
                 hashAdd(uniqHash, s, NULL);
                 name = slNameNew(s);
                 slAddHead(&joinedList, name);
                 }
             }
 	}
     slNameSort(&joinedList);
     nameList = slCat(nameList, joinedList);
     }
 hashFree(&uniqHash);
 return nameList;
 }
+
+static struct trackDb *addSupers(struct trackDb *trackList)
+/* Insert supertracks into the hierarchy. */
+{
+struct trackDb *newList = NULL;
+struct trackDb *tdb, *nextTdb;
+struct hash *superHash = newHash(5);
+
+for(tdb = trackList; tdb;  tdb = nextTdb)
+    {
+    nextTdb = tdb->next;
+    if (tdb->parent)
+        {
+        // part of a super track
+        if (hashLookup(superHash, tdb->parent->track) == NULL)
+            {
+            hashStore(superHash, tdb->parent->track);
+
+            slAddHead(&newList, tdb->parent);
+            }
+        slAddTail(&tdb->parent->subtracks, tdb);
+        }
+    else
+        slAddHead(&newList, tdb);
+    }
+slReverse(&newList);
+return newList;
+}
+
+static void hashTdbNames(struct trackDb *tdb, struct hash *trackHash)
+/* Store the track names for lookup, except for knownGene which gets its own special
+ * category in the UI */
+{
+struct trackDb *tmp;
+for (tmp = tdb; tmp != NULL; tmp = tmp->next)
+    {
+    if (tmp->subtracks)
+        hashTdbNames(tmp->subtracks, trackHash);
+    if (!sameString(tmp->table, tmp->track))
+        hashAdd(trackHash, tmp->track, tmp);
+    hashAdd(trackHash, tmp->table, tmp);
+    }
+}
+
+
+void hashTracksAndGroups(struct cart *cart, char *db)
+/* get the list of tracks available for this assembly, along with their group names
+ * and visibility-ness. Note that this implicitly makes connected hubs show up
+ * in the trackList struct, which means we get item search for connected
+ * hubs for free */
+{
+if (hgFindTdbList != NULL && hgFindGrpList != NULL)
+    return;
+
+if (!hgFindTrackHash)
+    hgFindTrackHash = hashNew(0);
+if (!hgFindGroupHash)
+    hgFindGroupHash = hashNew(0);
+cartTrackDbInit(cart, &hgFindTdbList, &hgFindGrpList, FALSE);
+if (!hgFindTdbList)
+    errAbort("Error getting tracks for %s", db);
+if (!hgFindGrpList)
+    errAbort("Error getting groups for %s", db);
+struct trackDb *superList = addSupers(hgFindTdbList);
+hgFindTdbList = superList;
+hashTdbNames(superList, hgFindTrackHash);
+struct grp *g;
+for (g = hgFindGrpList; g != NULL; g = g->next)
+    if (!sameString(g->name, "allTracks") && !sameString(g->name, "allTables"))
+        hashStore(hgFindGroupHash, g->name);
+}
+