BlastSeqLoc* BlastSeqLocFree(BlastSeqLoc* loc)
{
    while (loc) {
        BlastSeqLoc* next_loc = loc->next;
        loc = BlastSeqLocNodeFree(loc);
        loc = next_loc;
    }
    return NULL;
}
Exemple #2
0
void
BlastSeqLocCombine(BlastSeqLoc** mask_loc, Int4 link_value)
{
    BlastSeqLoc** ptrs = NULL;
    Int4 i = 0, num_elems = 0;

    /* Break up the list into an array of pointers and sort it */
    ptrs = s_BlastSeqLocListToArrayOfPointers(*mask_loc, &num_elems);
    if (num_elems == 0) {
        return;
    }
    ASSERT(ptrs);
    qsort(ptrs, (size_t)num_elems, sizeof(*ptrs), 
          s_SeqRangeSortByStartPosition);

    /* Merge the overlapping elements */
    {
        BlastSeqLoc* curr_tail = *mask_loc = ptrs[0];
        for (i = 0; i < num_elems - 1; i++) {
            const SSeqRange* next_ssr = ptrs[i+1]->ssr;
            const Int4 stop = curr_tail->ssr->right;

            if ((stop + link_value) > next_ssr->left) {
                curr_tail->ssr->right = MAX(stop, next_ssr->right);
                ptrs[i+1] = BlastSeqLocNodeFree(ptrs[i+1]);
            } else {
                curr_tail = ptrs[i+1];
            }
        }
    }

    /* Rebuild the linked list */
    {
        BlastSeqLoc* tail = *mask_loc;
        for (i = 1; i < num_elems; i++) {
            if (ptrs[i]) {
                tail->next = ptrs[i];
                tail = ptrs[i];
            }
        }
        tail->next = NULL;
    }
    sfree(ptrs);
}