7495791f0d935716eb5a6231e11ba833ef327aed angie Thu Apr 6 10:21:25 2017 -0700 Oops, forgot to implement maxOutRows for annoStreamTab! Thx Chris Lee. refs #12216 diff --git src/lib/annoStreamTab.c src/lib/annoStreamTab.c index 0888834..02f9a9a 100644 --- src/lib/annoStreamTab.c +++ src/lib/annoStreamTab.c @@ -9,30 +9,32 @@ #include "sqlNum.h" struct annoStreamTab { struct annoStreamer streamer; // Parent class members & methods // Private members char *fileOrUrl; // File name or URL struct lineFile *lf; // file handle char **asWords; // Most recent row's words int chromIx; // Index of chrom-ish col in autoSql or bin-less table int startIx; // Index of chromStart-ish col in autoSql or bin-less table int endIx; // Index of chromEnd-ish col in autoSql or bin-less table int fileWordCount; // Number of columns in file including bin boolean eof; // Set when we have reached end of file. boolean omitBin; // 1 if file has bin and autoSql doesn't have bin + boolean useMaxOutRows; // TRUE if maxOutRows passed to annoStreamTabNew is > 0 + int maxOutRows; // Maximum number of rows we can output. }; static struct lineFile *astLFOpen(char *fileOrUrl) /* Figure out if fileOrUrl is file or URL and open an lf accordingly. */ { if (startsWith("http://", fileOrUrl) || startsWith("https://", fileOrUrl) || startsWith("ftp://", fileOrUrl)) return netLineFileOpen(fileOrUrl); else return lineFileOpen(fileOrUrl, TRUE); } static void unChop(char **words, int wordCount) /* Trust that words were chopped from a contiguous line and add back tabs for '\0's. */ { @@ -187,66 +189,76 @@ { struct annoStreamTab *self = (struct annoStreamTab *)vSelf; char **words = nextRowUnfiltered(self, minChrom, minEnd); if (words == NULL) return NULL; // Skip past any left-join failures until we get a right-join failure, a passing row, or EOF. boolean rightFail = FALSE; while (annoFilterRowFails(vSelf->filters, words, vSelf->numCols, &rightFail)) { if (rightFail) break; words = nextRowUnfiltered(self, minChrom, minEnd); if (words == NULL) return NULL; } +if (self->useMaxOutRows) + { + self->maxOutRows--; + if (self->maxOutRows <= 0) + self->eof = TRUE; + } char *chrom = words[self->chromIx]; uint chromStart = sqlUnsigned(words[self->startIx]); uint chromEnd = sqlUnsigned(words[self->endIx]); return annoRowFromStringArray(chrom, chromStart, chromEnd, rightFail, words, vSelf->numCols, callerLm); } static boolean astInitBed3Fields(struct annoStreamTab *self) /* Use autoSql to figure out which table fields correspond to {chrom, chromStart, chromEnd}. */ { struct annoStreamer *vSelf = &(self->streamer); return annoStreamerFindBed3Columns(vSelf, &(self->chromIx), &(self->startIx), &(self->endIx), NULL, NULL, NULL); } static void astClose(struct annoStreamer **pVSelf) /* Close file and free self. */ { if (pVSelf == NULL) return; struct annoStreamTab *self = *(struct annoStreamTab **)pVSelf; lineFileClose(&(self->lf)); freeMem(self->asWords); freeMem(self->fileOrUrl); annoStreamerFree(pVSelf); } struct annoStreamer *annoStreamTabNew(char *fileOrUrl, struct annoAssembly *aa, - struct asObject *asObj) + struct asObject *asObj, int maxOutRows) /* Create an annoStreamer (subclass) object from a tab-separated text file/URL - * whose columns are described by asObj (possibly excepting bin column at beginning). */ + * whose columns are described by asObj (possibly excepting bin column at beginning). + * If maxOutRows is greater than 0 then it is an upper limit on the number of rows + * that the streamer will produce. */ { struct lineFile *lf = astLFOpen(fileOrUrl); struct annoStreamTab *self = NULL; AllocVar(self); struct annoStreamer *streamer = &(self->streamer); annoStreamerInit(streamer, aa, asObj, fileOrUrl); streamer->rowType = arWords; streamer->setRegion = astSetRegion; streamer->nextRow = astNextRow; streamer->close = astClose; AllocArray(self->asWords, streamer->numCols); self->lf = lf; self->eof = FALSE; self->fileOrUrl = cloneString(fileOrUrl); +self->maxOutRows = maxOutRows; +self->useMaxOutRows = (maxOutRows > 0); if (!astInitBed3Fields(self)) errAbort("annoStreamTabNew: can't figure out which fields of %s to use as " "{chrom, chromStart, chromEnd}.", fileOrUrl); return (struct annoStreamer *)self; }