in server/catgenome/src/main/java/com/epam/catgenome/util/feature/reader/TabixReader.java [558:631]
public Iterator query(final int tid, final int beg, final int end) {
TPair64[] off, chunks;
long minOff;
if (tid < 0 || tid >= this.mIndex.length) {
return EOF_ITERATOR;
}
TIndex idx = mIndex[tid];
int[] bins = new int[MAX_BIN];
int i, l, nOff, nBins = reg2bins(beg, end, bins);
if (idx.l.length > 0) {
minOff = (beg >> TAD_LIDX_SHIFT >= idx.l.length) ? idx.l[idx.l.length - 1] : idx.l[beg >> TAD_LIDX_SHIFT];
} else {
minOff = 0;
}
for (i = 0, nOff = 0; i < nBins; ++i) {
chunks = idx.b.get(bins[i]);
if (chunks != null) {
nOff += chunks.length;
}
}
if (nOff == 0) {
return EOF_ITERATOR;
}
off = new TPair64[nOff];
for (i = 0, nOff = 0; i < nBins; ++i) {
chunks = idx.b.get(bins[i]);
if (chunks != null) {
for (int j = 0; j < chunks.length; ++j) {
if (less64(minOff, chunks[j].v)) {
off[nOff++] = new TPair64(chunks[j]);
}
}
}
}
Arrays.sort(off, 0, nOff);
// resolve completely contained adjacent blocks
for (i = 1, l = 0; i < nOff; ++i) {
if (less64(off[l].v, off[i].v)) {
++l;
off[l].u = off[i].u;
off[l].v = off[i].v;
}
}
nOff = l + 1;
// resolve overlaps between adjacent blocks; this may happen due to the merge in indexing
for (i = 1; i < nOff; ++i) {
if (!less64(off[i - 1].v, off[i].u)) {
off[i - 1].v = off[i].u;
}
}
// merge adjacent blocks
for (i = 1, l = 0; i < nOff; ++i) {
if (off[l].v >> 16 == off[i].u >> 16) {
off[l].v = off[i].v;
} else {
++l;
off[l].u = off[i].u;
off[l].v = off[i].v;
}
}
nOff = l + 1;
// return
TPair64[] ret = new TPair64[nOff];
for (i = 0; i < nOff; ++i) {
if (off[i] != null) {
ret[i] = new TPair64(off[i].u, off[i].v); // in C, this is inefficient
}
}
if (ret.length == 0 || (ret.length == 1 && ret[0] == null)) {
return EOF_ITERATOR;
}
return new TabixReader.IteratorImpl(tid, beg, end, ret);
}