1d59c79ebf8d7596cf0beed61419bb267d5efb5c
angie
  Wed Dec 19 15:37:45 2012 -0800
Adding annoStreamTab and simple test case.refs #6152
Performance will not be good for a series of queries to small regions
on the same chromosome, because even if the regions don't overlap, we
will have to reopen the file every time and start over just in case
there are some items that start to the left of the region but overlap
it.
To fix that, we could add a queue for use when the region is smaller
than a chromosome.  Items that end to the right of the region would be
kept in a queue in case they're needed in the next region query.  When
a new sub-chrom region query begins, if there are items in the queue
that overlap the new region, they are used first and then we start
reading from the file where we left off at the end of the last region.

diff --git src/hg/lib/annoStreamDb.c src/hg/lib/annoStreamDb.c
index 1fc72be..9172720 100644
--- src/hg/lib/annoStreamDb.c
+++ src/hg/lib/annoStreamDb.c
@@ -230,64 +230,36 @@
 }
 
 static void asdClose(struct annoStreamer **pVSelf)
 /* Close db connection and free self. */
 {
 if (pVSelf == NULL)
     return;
 struct annoStreamDb *self = *(struct annoStreamDb **)pVSelf;
 lmCleanup(&(self->qLm));
 freeMem(self->table);
 sqlFreeResult(&(self->sr));
 hFreeConn(&(self->conn));
 annoStreamerFree(pVSelf);
 }
 
-static boolean asHasFields(struct annoStreamDb *self, char *chromField, char *startField,
-			   char *endField)
-/* If autoSql def has all three columns, remember their names and column indexes and
- * return TRUE. */
-{
-struct asColumn *columns = self->streamer.asObj->columnList;
-int chromIx = asColumnFindIx(columns, chromField);
-int startIx = asColumnFindIx(columns, startField);
-int endIx = asColumnFindIx(columns, endField);
-if (chromIx >= 0 && startIx >= 0 && endIx >= 0)
-    {
-    self->chromField = cloneString(chromField);
-    self->startField = cloneString(startField);
-    self->endField = cloneString(endField);
-    self->chromIx = chromIx;
-    self->startIx = startIx;
-    self->endIx = endIx;
-    return TRUE;
-    }
-return FALSE;
-}
-
 static boolean asdInitBed3Fields(struct annoStreamDb *self)
 /* Use autoSql to figure out which table fields correspond to {chrom, chromStart, chromEnd}. */
 {
-if (asHasFields(self, "chrom", "chromStart", "chromEnd"))
-    return TRUE;
-if (asHasFields(self, "chrom", "txStart", "txEnd"))
-    return TRUE;
-if (asHasFields(self, "tName", "tStart", "tEnd"))
-    return TRUE;
-if (asHasFields(self, "genoName", "genoStart", "genoEnd"))
-    return TRUE;
-return FALSE;
+struct annoStreamer *vSelf = &(self->streamer);
+return annoStreamerFindBed3Columns(vSelf, &(self->chromIx), &(self->startIx), &(self->endIx),
+				   &(self->chromField), &(self->startField), &(self->endField));
 }
 
 char *sqlTableIndexOnField(struct sqlConnection *conn, char *table, char *field)
 /* If table has an index that includes field, return the index name, else NULL. */
 {
 char *indexName = NULL;
 char query[512];
 safef(query, sizeof(query), "show index from %s", table);
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row;
 while ((row = sqlNextRow(sr)) != NULL)
     {
     if (sameString(row[4], field))
 	{
 	indexName = cloneString(row[2]);