d6b2ac470602ae218afa5f39cfad0105041bb837
angie
  Mon Oct 28 16:52:12 2013 -0700
Fixing mem leak (for when annoStreamBigBed does lots of queries that run into the maxItems limit).
diff --git src/lib/bigBed.c src/lib/bigBed.c
index 75130c9..d3bfea3 100644
--- src/lib/bigBed.c
+++ src/lib/bigBed.c
@@ -37,38 +37,39 @@
 struct bigBedInterval *el, *list = NULL;
 int itemCount = 0;
 bbiAttachUnzoomedCir(bbi);
 bits32 chromId;
 struct fileOffsetSize *blockList = bbiOverlappingBlocks(bbi, bbi->unzoomedCir,
 	chrom, start, end, &chromId);
 struct fileOffsetSize *block, *beforeGap, *afterGap;
 struct udcFile *udc = bbi->udc;
 boolean isSwapped = bbi->isSwapped;
 
 /* Set up for uncompression optionally. */
 char *uncompressBuf = NULL;
 if (bbi->uncompressBufSize > 0)
     uncompressBuf = needLargeMem(bbi->uncompressBufSize);
 
+char *mergedBuf = NULL;
 for (block = blockList; block != NULL; )
     {
     /* Find contigious blocks and read them into mergedBuf. */
     fileOffsetSizeFindGap(block, &beforeGap, &afterGap);
     bits64 mergedOffset = block->offset;
     bits64 mergedSize = beforeGap->offset + beforeGap->size - mergedOffset;
     udcSeek(udc, mergedOffset);
-    char *mergedBuf = needLargeMem(mergedSize);
+    mergedBuf = needLargeMem(mergedSize);
     udcMustRead(udc, mergedBuf, mergedSize);
     char *blockBuf = mergedBuf;
 
     /* Loop through individual blocks within merged section. */
     for (;block != afterGap; block = block->next)
         {
 	/* Uncompress if necessary. */
 	char *blockPt, *blockEnd;
 	if (uncompressBuf)
 	    {
 	    blockPt = uncompressBuf;
 	    int uncSize = zUncompress(blockBuf, block->size, uncompressBuf, bbi->uncompressBufSize);
 	    blockEnd = blockPt + uncSize;
 	    }
 	else
@@ -102,30 +103,31 @@
 		el->chromId = chromId;
 		slAddHead(&list, el);
 		}
 
 	    // move blockPt pointer to end of previous bed
 	    blockPt += restLen + 1;
 	    }
 	if (maxItems > 0 && itemCount > maxItems)
 	    break;
 	blockBuf += block->size;
         }
     if (maxItems > 0 && itemCount > maxItems)
         break;
     freez(&mergedBuf);
     }
+freez(&mergedBuf);
 freeMem(uncompressBuf);
 slFreeList(&blockList);
 slReverse(&list);
 return list;
 }
 
 int bigBedIntervalToRow(struct bigBedInterval *interval, char *chrom, char *startBuf, char *endBuf,
 	char **row, int rowSize)
 /* Convert bigBedInterval into an array of chars equivalent to what you'd get by
  * parsing the bed file. The startBuf and endBuf are used to hold the ascii representation of
  * start and end.  Note that the interval->rest string will have zeroes inserted as a side effect.
  */
 {
 int fieldCount = 3;
 sprintf(startBuf, "%u", interval->start);