f1464a78ed45c0f2c2c47112d5ec0585e875208e braney Tue Oct 30 15:01:29 2018 -0700 some optimizations to speed up trackDb loads on huge hubs diff --git src/hg/lib/hui.c src/hg/lib/hui.c index 1a184ea..b90bb71 100644 --- src/hg/lib/hui.c +++ src/hg/lib/hui.c @@ -2550,137 +2550,111 @@ static void dimensionsFree(dimensions_t **dimensions) // frees any previously obtained dividers setting { if (dimensions && *dimensions) { freeMem((*dimensions)->setting); freeMem((*dimensions)->names); freeMem((*dimensions)->subgroups); freez(dimensions); } } #define SUBGROUP_MAX 9 -enum filterCompositeType -// Filter composites are drop-down checkbix-lists for selecting subtracks (eg hg19::HAIB TFBS) - { - fctNone=0, // do not offer filter for this dimension - fctOne=1, // filter composite by one or all - fctOneOnly=2, // filter composite by only one - fctMulti=3, // filter composite by multiselect: all, one or many - }; - -typedef struct _members - { - int count; - char * groupTag; - char * groupTitle; - char **tags; - char **titles; - boolean *selected; - char * setting; - int *subtrackCount; // count of subtracks - int *currentlyVisible; // count of visible subtracks - struct slRef **subtrackList; // set of subtracks belonging to each subgroup member - enum filterCompositeType fcType; // fctNone,fctOne,fctMulti - } members_t; - int subgroupCount(struct trackDb *parentTdb) // How many subGroup setting does this parent have? { int ix; int count = 0; for (ix=1;ix<=SUBGROUP_MAX;ix++) { char subGrp[16]; safef(subGrp, ArraySize(subGrp), "subGroup%d",ix); if (trackDbSetting(parentTdb, subGrp) != NULL) count++; } return count; } char * subgroupSettingByTagOrName(struct trackDb *parentTdb, char *groupNameOrTag) // look for a subGroup by name (ie subGroup1) or tag (ie view) and return an unallocated char* { struct trackDb *ancestor; for (ancestor = parentTdb; ancestor != NULL; ancestor = ancestor->parent) { -int ix; char *setting = NULL; if (startsWith("subGroup",groupNameOrTag)) { setting = trackDbSetting(ancestor, groupNameOrTag); if (setting != NULL) return setting; } -for (ix=1;ix<=SUBGROUP_MAX;ix++) - { - char subGrp[16]; - safef(subGrp, ArraySize(subGrp), "subGroup%d",ix); - setting = trackDbSetting(ancestor, subGrp); - if (setting != NULL) // Doesn't require consecutive subgroups - { - if (startsWithWord(groupNameOrTag,setting)) + // these views are cached at trackDb read time + setting = trackDbViewSetting(ancestor, groupNameOrTag); + if (setting != NULL) return setting; } - } -} return NULL; } boolean subgroupingExists(struct trackDb *parentTdb, char *groupNameOrTag) // Does this parent track contain a particular subgrouping? { return (subgroupSettingByTagOrName(parentTdb,groupNameOrTag) != NULL); } static members_t *subgroupMembersGet(struct trackDb *parentTdb, char *groupNameOrTag) // Parse a subGroup setting line into tag,title, names(optional) and values(optional), // returning the count of members or 0 { +members_t *members = tdbExtrasMembers(parentTdb, groupNameOrTag); +if (members != NULL) + return members; + int ix,count; char *setting = subgroupSettingByTagOrName(parentTdb, groupNameOrTag); if (setting == NULL) return NULL; -members_t *members = needMem(sizeof(members_t)); +members = needMem(sizeof(members_t)); members->setting = cloneString(setting); char *words[SMALLBUF]; count = chopLine(members->setting, words); assert(count <= ArraySize(words)); if (count <= 1) { freeMem(members->setting); freeMem(members); return NULL; } members->groupTag = words[0]; members->groupTitle = strSwapChar(words[1],'_',' '); // Titles replace '_' with space members->tags = needMem(count*sizeof(char*)); members->titles = needMem(count*sizeof(char*)); for (ix = 2,members->count=0; ix < count; ix++) { char *name,*value; if (parseAssignment(words[ix], &name, &value)) { members->tags[members->count] = tagEncode(name); members->titles[members->count] = strSwapChar(value,'_',' '); members->count++; } } +tdbExtrasMembersSet(parentTdb, groupNameOrTag, members); + return members; } static int membersSubGroupIx(members_t* members, char *tag) // Returns the index of the subgroup within the members struct (or -1) { int ix = 0; for (ix=0;ix<members->count;ix++) { if (members->tags[ix] != NULL && sameString(members->tags[ix],tag)) return ix; } return -1; } @@ -2751,31 +2725,31 @@ { members->tags[ixIn] = NULL; members->titles[ixIn] = NULL; members->subtrackCount[ixIn] = 0; members->currentlyVisible[ixIn] = 0; //slFreeList(&members->subtrackList[ixIn]); // No freeing at this moment members->subtrackList[ixIn] = NULL; if (members->selected != NULL) members->selected[ixIn] = FALSE; } } members->count = ixOut; if (members->count == 0) // No members of this subgroup had a subtrack { - subgroupMembersFree(&members); + //subgroupMembersFree(&members); // don't bother freeing return NULL; } return members; } enum { dimV=0, // View first dimX=1, // X & Y next dimY=2, dimA=3, // dimA is start of first of the optional non-matrix, non-view dimensions }; typedef struct _membersForAll @@ -3033,30 +3007,32 @@ { // Uses membersForAll which may be in tdbExtraCache. Do not free membersForAll_t* membersForAll = membersForAllSubGroupsGet(parentTdb,NULL); if (membersForAll == NULL) return NULL; int ix = membersForAllFindSubGroupIx(membersForAll,tag); if (ix >= 0) return membersForAll->members[ix]; return NULL; } static void membersForAllSubGroupsFree(struct trackDb *parentTdb, membersForAll_t** membersForAllPtr) // frees memory for membersForAllSubGroups struct { +return; // don't bother freeing things, just takes time for no benefit + if (membersForAllPtr && *membersForAllPtr) { if (parentTdb != NULL) { if (*membersForAllPtr == tdbExtrasMembersForAll(parentTdb)) return; // Don't free something saved to the tdbExtras! } membersForAll_t* membersForAll = *membersForAllPtr; subgroupMembersFree(&(membersForAll->members[dimX])); subgroupMembersFree(&(membersForAll->members[dimY])); subgroupMembersFree(&(membersForAll->members[dimV])); int ix; for (ix=dimA;ix<membersForAll->dimMax;ix++) { //ASSERT(membersForAll->members[ix] != NULL); @@ -3126,31 +3102,31 @@ char *name,*value; if (parseAssignment(words[ix], &name, &value)) { membership->subgroups[membership->count] = name; membership->membership[membership->count] = tagEncode(value); // tags will be used as classes by js members_t* members = subgroupMembersGet(childTdb->parent, name); membership->titles[membership->count] = NULL; // default if (members != NULL) { int ix2 = stringArrayIx(membership->membership[membership->count],members->tags, members->count); if (ix2 != -1) membership->titles[membership->count] = strSwapChar(cloneString(members->titles[ix2]),'_',' '); - subgroupMembersFree(&members); +// subgroupMembersFree(&members); /// don't bother freeing } membership->count++; } } tdbExtrasMembershipSet(childTdb,membership); return membership; } static boolean membershipInAllCurrentABCs(membership_t *membership,membersForAll_t*membersForAll) // looks for a match between a membership set and ABC dimensions currently checked { int mIx,aIx,tIx; for (aIx = dimA; aIx < membersForAll->dimMax; aIx++) // for each ABC subGroup { @@ -3180,46 +3156,46 @@ return TRUE; // passed all tests so must be on all } char *compositeGroupLabel(struct trackDb *tdb, char *group, char *id) // Given ID from group, return corresponding label, looking through parent's subGroupN's // Given group ID, return group label, looking through parent's subGroupN's { members_t *members = subgroupMembersGet(tdb, group); char *result = NULL; int i; for (i=0; i<members->count; ++i) { if (sameString(members->tags[i], id)) result = cloneString(members->titles[i]); } -subgroupMembersFree(&members); +//subgroupMembersFree(&members); /// don't bother freeing return result; } char *compositeGroupId(struct trackDb *tdb, char *group, char *label) // Given label, return id, looking through parent's subGroupN's { members_t *members = subgroupMembersGet(tdb, group); char *result = NULL; int i; for (i=0; i<members->count; ++i) { if (sameString(members->titles[i], label)) result = cloneString(members->tags[i]); } -subgroupMembersFree(&members); +//subgroupMembersFree(&members); /// don't bother freeing return result; } static boolean subtrackInAllCurrentABCs(struct trackDb *childTdb,membersForAll_t*membersForAll) // looks for a match between a membership set and ABC dimensions currently checked { membership_t *membership = subgroupMembershipGet(childTdb); if (membership == NULL) return FALSE; boolean found = membershipInAllCurrentABCs(membership,membersForAll); return found; }