BlastSeqLoc* BlastSeqLocFree(BlastSeqLoc* loc) { while (loc) { BlastSeqLoc* next_loc = loc->next; loc = BlastSeqLocNodeFree(loc); loc = next_loc; } return NULL; }
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); }