fe1627a44ee54d0dcffd8cdd27d31f499ca6d5f6 kent Fri Jan 29 16:08:16 2021 -0800 Adding a function that is helpful when using facets on memory tables. diff --git src/hg/lib/facetField.c src/hg/lib/facetField.c index e0d3c42..a41107c 100644 --- src/hg/lib/facetField.c +++ src/hg/lib/facetField.c @@ -1,20 +1,21 @@ #include "common.h" #include "hash.h" #include "linefile.h" #include "jksql.h" +#include "fieldedTable.h" #include "facetField.h" #include "csv.h" int facetValCmpSelectCountDesc(const void *va, const void *vb) /* Compare two facetVal so as to sort them based on selectCount with most used first. * If two have same count, sort alphabetically on facet val. */ { struct facetVal *a = *((struct facetVal **)va); struct facetVal *b = *((struct facetVal **)vb); int result = b->selectCount - a->selectCount; if (result == 0) { result = strcmp(a->val, b->val); } return result; @@ -105,58 +106,60 @@ facetField->valHash = hashNew(0); facetField->allSelected = TRUE; // default to all values selected return facetField; } boolean perRowFacetFields(int fieldCount, char **row, char *nullVal, struct facetField *ffArray[]) /* Process each row of a resultset updating use and select counts. * Returns TRUE if row passes selected facet values filter and should be included in the final result set. */ { boolean result = FALSE; int totalSelectedFacets = 0; int facetCount = 0; // non-NULL facet count int i; for (i=0; i<fieldCount; ++i) { + struct facetField *ff = ffArray[i]; char *val = row[i]; if (val == NULL) val = nullVal; if (val != NULL) { - facetFieldAdd(ffArray[i], val, FALSE); - if (ffArray[i]->currentVal->selected) + facetFieldAdd(ff, val, FALSE); + if (ff->currentVal->selected) ++totalSelectedFacets; ++facetCount; } else { - ffArray[i]->currentVal = NULL; + ff->currentVal = NULL; } } if ((totalSelectedFacets == facetCount) && (facetCount > 0)) { // include this row in the final resultset result = TRUE; } for (i=0; i<fieldCount; ++i) { - if (ffArray[i]->currentVal) // disregard null values + struct facetField *ff = ffArray[i]; + if (ff->currentVal) // disregard null values { // disregard one's self. - if ((totalSelectedFacets - (int)ffArray[i]->currentVal->selected) == (facetCount - 1)) - ffArray[i]->currentVal->selectCount++; + if ((totalSelectedFacets - (int)ff->currentVal->selected) == (facetCount - 1)) + ff->currentVal->selectCount++; // shown on GUI to guide choosing by user } } return result; } #define facetValStringPunc '~' char *linearizeFacetVals(struct facetField *selectedList) /* Linearize selected fields vals into a string. fieldVal must be selected. */ { struct dyString *dy = newDyString(1024); struct facetField *sff = NULL; for (sff = selectedList; sff; sff=sff->next) { @@ -278,30 +281,31 @@ for (el=valList; el; el=el->next) { //uglyf("adding selected field %s val %s\n", selectedFields, el->name); facetFieldAdd(ff, el->name, TRUE); } *spc = ' '; // restore *spc2 = ' '; // restore *end = saveEnd; selectedFields = end+1; } slReverse(&ffList); return ffList; } + struct facetField *facetFieldsFromSqlTableInit(char *fields[], int fieldCount, char *selectedFields, struct facetField *ffArray[]) /* Initialize ffList and ffArray and selected facet values */ { /* Create facetField list and table. */ struct facetField *ffList = NULL, *ff; int i; for (i=0; i<fieldCount; ++i) { ff = ffArray[i] = facetFieldNew(fields[i]); slAddHead(&ffList, ff); } slReverse(&ffList); /* Initialize selected facet values */ if (selectedFields) @@ -374,30 +378,54 @@ if (perRowFacetFields(fieldCount, row, nullVal, ffArray)) ++selectedRowCount; } facetFieldsFromSqlTableFinish(ffList, facetValCmpUseCountDesc); /* Clean up and go home */ dyStringFree(&query); sqlFreeResult(&sr); if (pSelectedRowCount) *pSelectedRowCount = selectedRowCount; return ffList; } +struct facetField *facetFieldsFromFieldedTable(struct fieldedTable *ft, char *selectedFields, + struct facetField *ffArray[], int *retSelectedRowCount) +/* Get a facetField list and initialize arrays based on selected fields from table + * ffArray must be big enough to hold all fields in table */ +{ +struct facetField *ffList = facetFieldsFromSqlTableInit(ft->fields, ft->fieldCount, + selectedFields, ffArray); + +struct fieldedRow *fr; +int selectedRowCount = 0; +int fieldCount = ft->fieldCount; +for (fr = ft->rowList; fr != NULL; fr = fr->next) + { + if (perRowFacetFields(fieldCount, fr->row, "", ffArray)) + ++selectedRowCount; + } + +facetFieldsFromSqlTableFinish(ffList, facetValCmpUseCountDesc); + +if (retSelectedRowCount != NULL) + *retSelectedRowCount = selectedRowCount; +return ffList; +} + struct facetVal *facetValMajorPlusOther(struct facetVal *list, double minRatio) /* Return a list of only the tags that are over minRatio of total tags. * If there are tags that have smaller amounts than this, lump them together * under "other". Returns a new list. Use slFreeList() to free the result. */ { /* Figure out total and minimum count to not be lumped into other */ long total = 0; struct facetVal *tc; for (tc = list; tc != NULL; tc = tc->next) total += tc->useCount; long minCount = round(minRatio * total); /* Loop through and copy ones over threshold to new list, and lump rest * into other */ struct facetVal *newList = NULL, *newTc;