b9b69223f1cd1b8a5b2e67b5ab4d6b04cd18c5d1 braney Sat Aug 18 11:58:43 2012 -0700 fixed #8834 by querying only part of the chrom to get ten items for schema diff --git src/hg/hgTables/bigBed.c src/hg/hgTables/bigBed.c index d0a951d..c20403a 100644 --- src/hg/hgTables/bigBed.c +++ src/hg/hgTables/bigBed.c @@ -232,41 +232,96 @@ 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) + { + len += 1; + pt = pt->next; + if (len == max) + break; + } +return len; +} + +static struct bigBedInterval *getTenElements(struct bbiFile *bbi, + struct bbiChromInfo *chromList, struct lm *lm) +// get up to ten sample rows from the first chrom listed in the bigBed. +// will return less than ten if there are less than ten on the first chrom. +{ +struct bigBedInterval *ivList = NULL; +// start out requesting only 10k bp so we don't hang if the bigBed is huge +int currentLen = 10000; +// look about 2/3 of the way through the chrom to avoid the telomeres +// and the centromere +int startAddr = 2 * chromList->size / 3; +int endAddr; + +while ((slCountAtMost(ivList,10)) < 10) + { + endAddr = startAddr + currentLen; + + // if we're pointing beyond the end of the chromosome + if (endAddr > chromList->size) + { + // move the start address back + startAddr -= (endAddr - chromList->size); + endAddr = chromList->size; + } + + // if we're pointing to before the start of the chrom + if (startAddr < 0) + startAddr = 0; + + // ask for ten items + ivList = bigBedIntervalQuery(bbi, chromList->name, startAddr, endAddr, 10, lm); + currentLen *= 2; + + if ((startAddr == 0) && (endAddr == chromList->size)) + break; + } + +return ivList; +} + void showSchemaBigBed(char *table) /* Show schema on bigBed. */ { /* Figure out bigBed file name and open it. Get contents for first chromosome as an example. */ struct sqlConnection *conn = hAllocConn(database); char *fileName = bigBedFileName(table, conn); struct bbiFile *bbi = bigBedFileOpen(fileName); struct bbiChromInfo *chromList = bbiChromList(bbi); struct lm *lm = lmInit(0); -struct bigBedInterval *ivList = bigBedIntervalQuery(bbi, chromList->name, 0, - chromList->size, 10, lm); +struct bigBedInterval *ivList = getTenElements(bbi, chromList, lm); /* Get description of columns, making it up from BED records if need be. */ struct asObject *as = bigBedAsOrDefault(bbi); hPrintf("<B>Database:</B> %s", database); hPrintf(" <B>Primary Table:</B> %s<br>", table); hPrintf("<B>Big Bed File:</B> %s", fileName); if (bbi->version >= 2) { hPrintf(" <B>Item Count:</B> "); printLongWithCommas(stdout, bigBedItemCount(bbi)); } hPrintf("<BR>\n"); hPrintf("<B>Format description:</B> %s<BR>", as->comment);