src/hg/makeDb/hgTrackDb/hgTrackDb.c 1.59
1.59 2010/01/09 20:54:15 galt
release alpha/beta was broken. Now that closest-to-home has gone away, it was very easy to implement very-early release pruning, followed later by pruning of orphans with no parent of the correct release. This keeps the code pretty simple which is nice.
Index: src/hg/makeDb/hgTrackDb/hgTrackDb.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/makeDb/hgTrackDb/hgTrackDb.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -b -B -U 4 -r1.58 -r1.59
--- src/hg/makeDb/hgTrackDb/hgTrackDb.c 6 Jan 2010 21:48:19 -0000 1.58
+++ src/hg/makeDb/hgTrackDb/hgTrackDb.c 9 Jan 2010 20:54:15 -0000 1.59
@@ -61,9 +61,9 @@
static char *release = "alpha";
static bool showSettings = FALSE;
static boolean hasNonAsciiChars(char *text)
-/* check if text has any non-printing or non-ascii characters */
+/* Check if text has any non-printing or non-ascii characters */
{
char *c;
for (c = text; *c != '\0'; c++)
{
@@ -76,9 +76,9 @@
}
static struct trackDb *trackDbListFromHash(struct hash *tdHash)
-/* build a list of the tracks in hash. List will be threaded through
+/* Build a list of the tracks in hash. List will be threaded through
* the entries. */
{
struct trackDb *tdbList = NULL;
struct hashCookie cookie = hashFirst(tdHash);
@@ -115,40 +115,8 @@
slReverse(&newList);
return newList;
}
-static boolean releasesCompatible(struct trackDb *a, struct trackDb *b)
-/* Return TRUE if either release is NULL, or if they both exist and match. */
-{
-char *aRelease = trackDbSetting(a, "release");
-char *bRelease = trackDbSetting(b, "release");
-return aRelease == NULL || bRelease == NULL || sameString(aRelease, bRelease);
-}
-
-static void fillInSubtrackParentsRespectingRelease(struct trackDb *tdbList, struct hash *trackHash)
-/* Fill in parent pointers. This just handles a part of the heirarchy, but it does handle releases. */
-{
-/* Loop through looking for parent tracks whenever see the subTrack tag.
- * Try to find parent just in compatible release. */
-struct trackDb *td;
-for (td = tdbList; td != NULL; td = td->next)
- {
- char *parentName = trackDbLocalSetting(td, "subTrack");
- if (parentName != NULL)
- {
- struct hashEl *hel;
- for (hel = hashLookup(trackHash, parentName); hel != NULL; hel = hashLookupNext(hel))
- {
- struct trackDb *p = hel->val;
- if (releasesCompatible(p, td))
- {
- td->parent = p;
- break;
- }
- }
- }
- }
-}
static struct trackDb *pruneEmptyContainers(struct trackDb *tdbList)
/* Remove container tracks (views and compositeTracks) with no children. */
{
@@ -173,14 +141,11 @@
slReverse(&newList);
return newList;
}
-static struct trackDb * pruneRelease(struct trackDb *tdbList, struct hash *trackHash)
-/* prune out alternate track entries for another release */
+static struct trackDb * pruneRelease(struct trackDb *tdbList)
+/* Prune out alternate track entries for another release */
{
-/* Link up parents so that trackDbSettingClosest to home will work. */
-fillInSubtrackParentsRespectingRelease(tdbList, trackHash);
-
/* Build up list that only includes things in this release. Release
* can be inherited from parents. */
struct trackDb *tdb;
struct trackDb *relList = NULL;
@@ -188,27 +153,57 @@
{
char *rel = trackDbSetting(tdb, "release");
if (rel == NULL || sameString(rel, release))
{
- verbose(3,"pruneRelease: adding '%s', release: '%s' =? '%s'\n",
- tdb->tableName, rel, release);
+ /* Remove release tags in remaining tracks, since its purpose is served. */
+ hashRemove(tdb->settingsHash, "release");
slAddHead(&relList, tdb);
}
else
verbose(3,"pruneRelease: removing '%s', release: '%s' != '%s'\n",
tdb->tableName, rel, release);
}
-
-/* Remove release tags in remaining tracks, since its purpose is served. */
-for (tdb = relList; tdb != NULL; tdb = tdb->next)
- hashRemove(tdb->settingsHash, "release");
-
return relList;
}
+static struct trackDb * pruneOrphans(struct trackDb *tdbList, struct hash *trackHash)
+/* Prune out orphans with no parents of the right release */
+{
+boolean done = FALSE;
+struct trackDb *tdb;
+struct trackDb *nonOrphanList = NULL;
+while (!done)
+ {
+ done = TRUE;
+ nonOrphanList = NULL;
+ while ((tdb = slPopHead(&tdbList)) != NULL)
+ {
+ char *parentName = trackDbLocalSetting(tdb, "subTrack");
+ struct hashEl *hel = NULL;
+ if (parentName != NULL)
+ {
+ hel = hashLookup(trackHash, parentName);
+ }
+ if (parentName == NULL || hel != NULL)
+ {
+ slAddHead(&nonOrphanList, tdb);
+ }
+ else
+ {
+ verbose(3,"pruneOrhans: removing '%s'\n",
+ tdb->tableName);
+ hashRemove(trackHash, tdb->tableName);
+ done = FALSE;
+ }
+ }
+ tdbList = nonOrphanList;
+ }
+return tdbList;
+}
+
static void applyOverride(struct hash *trackHash,
struct trackDb *overTd)
-/* apply a trackDb override to a track, if it exists */
+/* Apply a trackDb override to a track, if it exists */
{
struct trackDb *tdb = hashFindVal(trackHash, overTd->tableName);
if (tdb != NULL)
trackDbOverride(tdb, overTd);
@@ -219,23 +214,19 @@
/* Read in tracks from raName and add them to table, pruning as required. Call
* top-down so that track override will work. */
{
struct trackDb *tdbList = trackDbFromRa(raName), *tdb;
+/* prune records of the incorrect release */
+tdbList= pruneRelease(tdbList);
/* load tracks, replacing higher-level ones with lower-level and
* applying overrides*/
while ((tdb = slPopHead(&tdbList)) != NULL)
{
if (tdb->overrides != NULL)
applyOverride(trackHash, tdb);
else
- {
- struct hashEl *hel = hashLookup(trackHash, tdb->tableName);
- if (hel != NULL)
- verbose(2,"addVersionRa: warning duplicate tableName: '%s'\n",
- tdb->tableName);
- hashAdd(trackHash, tdb->tableName, tdb);
- }
+ hashStore(trackHash, tdb->tableName)->val = tdb;
}
}
void updateBigTextField(struct sqlConnection *conn, char *table,
@@ -309,9 +300,9 @@
for (td = tdbList; td != NULL; td = td->next)
{
if (isEmpty(td->html))
{
- char *htmlName = trackDbSettingClosestToHome(td, "html");
+ char *htmlName = trackDbSetting(td, "html");
if (htmlName == NULL)
htmlName = td->tableName;
safef(fileName, sizeof(fileName), "%s/%s.html", dirName, htmlName);
if (fileExists(fileName))
@@ -472,18 +463,18 @@
}
}
static void checkSubGroups(struct trackDb *tdbList)
-/* check integrity of subGroup clauses */
+/* Check integrity of subGroup clauses */
{
struct hash *compositeHash = buildCompositeHash(tdbList);
verifySubTracks(tdbList, compositeHash);
}
static void prioritizeContainerItems(struct trackDb *tdbList)
-/* set priorities in containers if they have no priorities already set
+/* Set priorities in containers if they have no priorities already set
priorities are based upon 'sortOrder' setting or else shortLabel */
{
int countOfSortedContainers = 0;
@@ -605,9 +596,9 @@
static struct trackDb *buildTrackDb(char *org, char *database, char *hgRoot,
char *visibilityRa, char *priorityRa,
boolean strict)
-/* build trackDb objects from files. */
+/* Build trackDb objects from files. */
{
struct hash *trackHash = newHash(0);
char rootDir[PATH_LEN], orgDir[PATH_LEN], asmDir[PATH_LEN];
@@ -617,9 +608,10 @@
safef(rootDir, sizeof(rootDir), "%s", hgRoot);
safef(orgDir, sizeof(orgDir), "%s/%s", hgRoot, org);
safef(asmDir, sizeof(asmDir), "%s/%s/%s", hgRoot, org, database);
-// must call these top-down
+/* Must call these top-down.
+ * Also prunes things not in our release. */
layerOnRa(strict, database, rootDir, trackHash, TRUE);
layerOnRa(strict, database, orgDir, trackHash, FALSE);
layerOnRa(strict, database, asmDir, trackHash, FALSE);
@@ -629,12 +621,15 @@
if (priorityRa != NULL)
trackDbOverridePriority(trackHash, priorityRa);
#endif /* OLD */
-/* Represent as list as well as hash, and prune things not in our release from list.
- * After this hash is no longer userful since it contains pruned things, so get rid of it. */
+/* Represent hash as list */
struct trackDb *tdbList = trackDbListFromHash(trackHash);
-tdbList= pruneRelease(tdbList, trackHash);
+
+/* Get rid of orphans with no parent of the correct release. */
+tdbList = pruneOrphans(tdbList, trackHash);
+
+/* After this the hash is no longer needed, so get rid of it. */
hashFree(&trackHash);
/* Read in HTML bits onto what remains. */
layerOnHtml(asmDir, tdbList);