void rt1dFindOld(char *tabFile, char *treeFile, bits32 chromIx, bits32 start, bits32 end) /* rt1dCreate - find items in 1-D range tree. */ { struct lineFile *lf = lineFileOpen(tabFile, TRUE); struct cirTreeFile *crf = cirTreeFileOpen(treeFile); struct fileOffsetSize *block, *blockList = cirTreeFindOverlappingBlocks(crf, chromIx, start, end); uglyf("Got %d overlapping blocks\n", slCount(blockList)); for (block = blockList; block != NULL; block = block->next) { uglyf("block->offset %llu, block->size %llu\n", block->offset, block->size); lineFileSeek(lf, block->offset, SEEK_SET); bits64 sizeUsed = 0; while (sizeUsed < block->size) { char *line; int size; if (!lineFileNext(lf, &line, &size)) errAbort("Couldn't read %s\n", lf->fileName); char *parsedLine = cloneString(line); char *row[3]; if (chopLine(parsedLine, row) != ArraySize(row)) errAbort("Badly formatted line of %s\n%s", lf->fileName, line); bits32 bedChromIx = sqlUnsigned(row[0]); bits32 bedStart = sqlUnsigned(row[1]); bits32 bedEnd = sqlUnsigned(row[2]); if (bedChromIx == chromIx && rangeIntersection(bedStart, bedEnd, start, end) > 0) fprintf(stdout, "%s\n", line); freeMem(parsedLine); sizeUsed += size; } } }
struct fileOffsetSize *crTreeFindOverlappingBlocks(struct crTreeFile *crt, char *chrom, bits32 start, bits32 end) /* Return list of file blocks that between them contain all items that overlap * start/end on chromIx. Also there will be likely some non-overlapping items * in these blocks too. When done, use slListFree to dispose of the result. */ { /* Find chromosome index. Return NULL if no such chromosome*/ bits32 chromIx; if (!bptFileFind(crt->chromBpt, chrom, strlen(chrom), &chromIx, sizeof(chromIx))) return NULL; return cirTreeFindOverlappingBlocks(crt->cir, chromIx, start, end); }
struct fileOffsetSize *bbiOverlappingBlocks(struct bbiFile *bbi, struct cirTreeFile *ctf, char *chrom, bits32 start, bits32 end, bits32 *retChromId) /* Fetch list of file blocks that contain items overlapping chromosome range. */ { struct bbiChromIdSize idSize; if (!bptFileFind(bbi->chromBpt, chrom, strlen(chrom), &idSize, sizeof(idSize))) return NULL; if (bbi->isSwapped) idSize.chromId = byteSwap32(idSize.chromId); if (retChromId != NULL) *retChromId = idSize.chromId; return cirTreeFindOverlappingBlocks(ctf, idSize.chromId, start, end); }
static struct bbiSummary *bbiSummariesInRegion(struct bbiZoomLevel *zoom, struct bbiFile *bbi, int chromId, bits32 start, bits32 end) /* Return list of all summaries in region at given zoom level of bbiFile. */ { struct bbiSummary *sumList = NULL, *sum; struct udcFile *udc = bbi->udc; udcSeek(udc, zoom->indexOffset); struct cirTreeFile *ctf = cirTreeFileAttach(bbi->fileName, bbi->udc); struct fileOffsetSize *blockList = cirTreeFindOverlappingBlocks(ctf, chromId, start, end); struct fileOffsetSize *block, *beforeGap, *afterGap; /* Set up for uncompression optionally. */ char *uncompressBuf = NULL; if (bbi->uncompressBufSize > 0) uncompressBuf = needLargeMem(bbi->uncompressBufSize); /* This loop is a little complicated because we merge the read requests for efficiency, but we * have to then go back through the data one unmerged block at a time. */ 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); 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 { blockPt = blockBuf; blockEnd = blockPt + block->size; } /* Figure out bounds and number of items in block. */ int blockSize = blockEnd - blockPt; struct bbiSummaryOnDisk *dSum; int itemSize = sizeof(*dSum); assert(blockSize % itemSize == 0); int itemCount = blockSize / itemSize; /* Read in items and convert to memory list format. */ int i; for (i=0; i<itemCount; ++i) { dSum = (void *)blockPt; blockPt += sizeof(*dSum); if (dSum->chromId == chromId) { int s = max(dSum->start, start); int e = min(dSum->end, end); if (s < e) { sum = bbiSummaryFromOnDisk(dSum); slAddHead(&sumList, sum); } } } assert(blockPt == blockEnd); blockBuf += block->size; } freeMem(mergedBuf); } freeMem(uncompressBuf); slFreeList(&blockList); cirTreeFileDetach(&ctf); slReverse(&sumList); return sumList; }