87 Position_ query_start,
91 std::vector<Index_>& matches)
94 if (subject.root_children == 0) {
145 Position_ query_width = query_end - query_start;
150 Position_ effective_query_start = query_start;
152 constexpr Position_ maxed = std::numeric_limits<Position_>::max();
156 effective_query_start = query_start + params.
min_overlap;
160 auto find_first_child = [&](Index_ children_start, Index_ children_end) -> Index_ {
161 auto ebegin = subject.ends.begin();
162 auto estart = ebegin + children_start;
163 auto eend = ebegin + children_end;
164 return std::lower_bound(estart, eend, effective_query_start) - ebegin;
167 auto can_skip_search = [&](Position_ subject_start) ->
bool {
168 return subject_start >= effective_query_start;
171 auto is_finished = [&](Position_ subject_start) ->
bool {
173 if (subject_start >= query_end) {
176 return query_end - subject_start < params.
min_overlap;
178 return subject_start > query_end;
182 Index_ root_child_at = 0;
183 bool root_skip_search = can_skip_search(subject.starts[0]);
184 if (!root_skip_search) {
185 root_child_at = find_first_child(0, subject.root_children);
188 workspace.history.clear();
190 Index_ current_subject;
191 bool current_skip_search;
192 if (workspace.history.empty()) {
193 if (root_child_at == subject.root_children || is_finished(subject.starts[root_child_at])) {
196 current_subject = root_child_at;
197 current_skip_search = root_skip_search;
200 auto& current_state = workspace.history.back();
201 if (current_state.child_at == current_state.child_end || is_finished(subject.starts[current_state.child_at])) {
202 workspace.history.pop_back();
205 current_subject = current_state.child_at;
206 current_skip_search = current_state.skip_search;
207 ++(current_state.child_at);
210 const auto& current_node = subject.nodes[current_subject];
211 auto subject_start = subject.starts[current_subject];
212 auto subject_end = subject.ends[current_subject];
213 auto subject_width = subject_end - subject_start;
220 if (params.
max_gap.has_value()) {
221 if (query_width - subject_width > *(params.
max_gap)) {
226 if (query_start <= subject_start && query_end >= subject_end) {
227 matches.push_back(current_node.id);
231 if (current_node.duplicates_start != current_node.duplicates_end) {
232 matches.insert(matches.end(), subject.duplicates.begin() + current_node.duplicates_start, subject.duplicates.begin() + current_node.duplicates_end);
236 if (current_node.children_start != current_node.children_end) {
237 if (current_skip_search) {
238 workspace.history.emplace_back(current_node.children_start, current_node.children_end,
true);
240 Index_ start_pos = find_first_child(current_node.children_start, current_node.children_end);
241 if (start_pos != current_node.children_end) {
242 workspace.history.emplace_back(start_pos, current_node.children_end, can_skip_search(subject.starts[start_pos]));
void overlaps_extend(const Nclist< Index_, Position_ > &subject, Position_ query_start, Position_ query_end, const OverlapsExtendParameters< Position_ > ¶ms, OverlapsExtendWorkspace< Index_ > &workspace, std::vector< Index_ > &matches)
Definition overlaps_extend.hpp:85