86 Position_ query_start,
90 std::vector<Index_>& matches)
93 if (subject.root_children == 0) {
152 if (query_end - query_start < params.
min_overlap) {
157 Position_ effective_query_start = query_start;
159 constexpr Position_ maxed = std::numeric_limits<Position_>::max();
163 effective_query_start = query_start + params.
min_overlap;
164 }
else if (params.
max_gap > 0) {
165 effective_query_start = safe_subtract_gap(query_start, params.
max_gap);
168 auto find_first_child = [&](Index_ children_start, Index_ children_end) -> Index_ {
169 auto ebegin = subject.ends.begin();
170 auto estart = ebegin + children_start;
171 auto eend = ebegin + children_end;
172 return std::lower_bound(estart, eend, effective_query_start) - ebegin;
175 auto skip_binary_search = [&](Position_ subject_start) ->
bool {
176 return subject_start >= effective_query_start;
179 auto is_finished = [&](Position_ subject_start) ->
bool {
180 if (subject_start > query_start) {
184 if (subject_start - query_start > params.
max_gap) {
188 if (subject_start >= query_end || query_end - subject_start < params.
min_overlap) {
196 if (query_end - subject_start < params.
min_overlap) {
205 Index_ root_child_at = 0;
206 bool root_skip_search = skip_binary_search(subject.starts[0]);
207 if (!root_skip_search) {
208 root_child_at = find_first_child(0, subject.root_children);
211 workspace.history.clear();
213 Index_ current_subject;
215 if (workspace.history.empty()) {
216 if (root_child_at == subject.root_children || is_finished(subject.starts[root_child_at])) {
219 current_subject = root_child_at;
220 skip_search = root_skip_search;
223 auto& current_state = workspace.history.back();
224 if (current_state.child_at == current_state.child_end || is_finished(subject.starts[current_state.child_at])) {
225 workspace.history.pop_back();
228 current_subject = current_state.child_at;
229 skip_search = current_state.skip_search;
230 ++(current_state.child_at);
233 const auto& current_node = subject.nodes[current_subject];
234 auto subject_start = subject.starts[current_subject];
235 auto subject_end = subject.ends[current_subject];
238 auto common_end = std::min(subject_end, query_end);
239 auto common_start = std::max(subject_start, query_start);
240 if (common_end <= common_start || common_end - common_start < params.
min_overlap) {
249 okay = !diff_above_gap(query_start, subject_start, params.
max_gap);
251 okay = (subject_start == query_start);
254 matches.push_back(current_node.id);
258 if (current_node.duplicates_start != current_node.duplicates_end) {
259 matches.insert(matches.end(), subject.duplicates.begin() + current_node.duplicates_start, subject.duplicates.begin() + current_node.duplicates_end);
263 if (current_node.children_start != current_node.children_end) {
265 workspace.history.emplace_back(current_node.children_start, current_node.children_end,
true);
267 Index_ start_pos = find_first_child(current_node.children_start, current_node.children_end);
268 if (start_pos != current_node.children_end) {
269 workspace.history.emplace_back(start_pos, current_node.children_end, skip_binary_search(subject.starts[start_pos]));
void overlaps_start(const Nclist< Index_, Position_ > &subject, Position_ query_start, Position_ query_end, const OverlapsStartParameters< Position_ > ¶ms, OverlapsStartWorkspace< Index_ > &workspace, std::vector< Index_ > &matches)
Definition overlaps_start.hpp:84