d1a11e955077906d793c5f6ca9eee3c40a77f1b0
braney
  Wed Feb 19 14:24:48 2020 -0800
use a name index in a bigBed if available and there are identifiers in hgTables and
the region is whole genome

diff --git src/hg/hgTables/bigBed.c src/hg/hgTables/bigBed.c
index de4de9e..f6b1419 100644
--- src/hg/hgTables/bigBed.c
+++ src/hg/hgTables/bigBed.c
@@ -216,55 +216,93 @@
 /* Open up bigBed file. */
 char *fileName = bigBedFileName(table, conn);
 struct bbiFile *bbi = bigBedFileOpen(fileName);
 struct asObject *as = bigBedAsOrDefault(bbi);
 struct asFilter *filter = NULL;
 
 if (anyFilter())
     {
     filter = asFilterFromCart(cart, db, table, as);
     if (filter)
         {
 	fprintf(f, "# Filtering on %d columns\n", slCount(filter->columnList));
 	}
     }
 
+struct bptFile *bpt = NULL;
+int fieldIx;
+
+if (idHash && isRegionWholeGenome())
+    bpt = bigBedOpenExtraIndex(bbi, "name", &fieldIx);
+
+char *row[bbi->fieldCount];
+char startBuf[16], endBuf[16];
+if (bpt) // if we have an index it means we're whole genome and don't need to filter based on regions
+    {
+    struct slName *nameList = hashSlNameFromHash(idHash);
+    int count = slCount(nameList);
+    char *names[count];
+    int ii;
+    for (ii=0; ii < count; ii++)
+    {
+        names[ii] = nameList->name;
+        nameList = nameList->next;
+    }
+
+    struct lm *lm = lmInit(0);
+    struct bigBedInterval *ivList = bigBedMultiNameQuery(bbi, bpt, fieldIx, names, count, lm);
+    char chromBuf[4096];
+    struct bigBedInterval *interval, *prevInterval = NULL;
+    for (interval = ivList; interval != NULL; prevInterval = interval, interval = interval->next)
+        {       
+        bigBedIntervalToRowLookupChrom(interval, prevInterval, bbi, chromBuf, sizeof chromBuf, startBuf, endBuf, row, bbi->fieldCount);
+        if (asFilterOnRow(filter, row))
+            {
+            int i;
+            fprintf(f, "%s", row[columnArray[0]]);
+            for (i=1; i<fieldCount; ++i)
+                fprintf(f, "\t%s", row[columnArray[i]]);
+            fprintf(f, "\n");
+            }
+        }
+    }
+else 
+    {
     /* Loop through outputting each region */
     struct region *region, *regionList = getRegions();
     for (region = regionList; region != NULL; region = region->next)
         {
         struct lm *lm = lmInit(0);
         struct bigBedInterval *iv, *ivList = bigBedIntervalQuery(bbi, region->chrom,
             region->start, region->end, 0, lm);
-    char *row[bbi->fieldCount];
-    char startBuf[16], endBuf[16];
         for (iv = ivList; iv != NULL; iv = iv->next)
             {
             bigBedIntervalToRow(iv, region->chrom, startBuf, endBuf, row, bbi->fieldCount);
             if (asFilterOnRow(filter, row))
                 {
                 if ((idHash != NULL) && (hashLookup(idHash, row[3]) == NULL))
                     continue;
                 int i;
                 fprintf(f, "%s", row[columnArray[0]]);
                 for (i=1; i<fieldCount; ++i)
                     fprintf(f, "\t%s", row[columnArray[i]]);
                 fprintf(f, "\n");
                 }
             }
         lmCleanup(&lm);
         }
+    }
 
 /* Clean up and exit. */
 bbiFileClose(&bbi);
 hashFree(&fieldHash);
 freeMem(fieldArray);
 freeMem(columnArray);
 }
 
 static unsigned slCountAtMost(const void *list, unsigned max)
 // return the length of the list, but only count up to max
 {
 struct slList *pt = (struct slList *)list;
 int len = 0;
 
 while (pt != NULL)