| 1 | // ============================================================= // |
|---|
| 2 | // // |
|---|
| 3 | // File : PT_rangeCheck.hxx // |
|---|
| 4 | // Purpose : Check whether probe is inside region // |
|---|
| 5 | // // |
|---|
| 6 | // Coded by Ralf Westram (coder@reallysoft.de) in March 2011 // |
|---|
| 7 | // Institute of Microbiology (Technical University Munich) // |
|---|
| 8 | // http://www.arb-home.de/ // |
|---|
| 9 | // // |
|---|
| 10 | // ============================================================= // |
|---|
| 11 | |
|---|
| 12 | #ifndef PT_RANGECHECK_HXX |
|---|
| 13 | #define PT_RANGECHECK_HXX |
|---|
| 14 | |
|---|
| 15 | #ifndef PROBE_TREE_H |
|---|
| 16 | #include "probe_tree.h" |
|---|
| 17 | #endif |
|---|
| 18 | #ifndef _GLIBCXX_MAP |
|---|
| 19 | #include <map> |
|---|
| 20 | #endif |
|---|
| 21 | |
|---|
| 22 | typedef std::map<int, int> apos_cache; |
|---|
| 23 | typedef apos_cache::iterator apos_iter; |
|---|
| 24 | |
|---|
| 25 | class Range { |
|---|
| 26 | int start; // -1 or minimum absolute position |
|---|
| 27 | int end; // -1 or maximum absolute position |
|---|
| 28 | int probe_len; // length of checked probe |
|---|
| 29 | |
|---|
| 30 | mutable const AbsLoc *curr_match; |
|---|
| 31 | mutable apos_cache cache; |
|---|
| 32 | |
|---|
| 33 | int start_pos() const { return curr_match->get_abs_pos(); } |
|---|
| 34 | int min_end_pos() const { return start_pos()+probe_len-1; } // min abs. probe-end-pos |
|---|
| 35 | |
|---|
| 36 | int calc_max_abs_pos() const; |
|---|
| 37 | int max_abs_pos() const { |
|---|
| 38 | apos_iter found = cache.find(curr_match->get_name()); |
|---|
| 39 | if (found != cache.end()) return found->second; |
|---|
| 40 | |
|---|
| 41 | return cache[curr_match->get_name()] = calc_max_abs_pos(); |
|---|
| 42 | } |
|---|
| 43 | |
|---|
| 44 | bool starts_before_start() const { return start != -1 && start_pos() < start; } |
|---|
| 45 | bool ends_behind_end() const { |
|---|
| 46 | return end != -1 && |
|---|
| 47 | (min_end_pos() > end || // cheap check |
|---|
| 48 | start > max_abs_pos()); // expensive check |
|---|
| 49 | } |
|---|
| 50 | |
|---|
| 51 | public: |
|---|
| 52 | Range(int start_, int end_, int probe_len_) |
|---|
| 53 | : start(start_), |
|---|
| 54 | end(end_), |
|---|
| 55 | probe_len(probe_len_), |
|---|
| 56 | curr_match(NULp) |
|---|
| 57 | {} |
|---|
| 58 | Range(const Range& other) |
|---|
| 59 | : start(other.start), |
|---|
| 60 | end(other.end), |
|---|
| 61 | probe_len(other.probe_len), |
|---|
| 62 | curr_match(other.curr_match) |
|---|
| 63 | {} |
|---|
| 64 | DECLARE_ASSIGNMENT_OPERATOR(Range); |
|---|
| 65 | |
|---|
| 66 | bool contains(const AbsLoc& match) const { |
|---|
| 67 | // check if found 'match' of probe is inside the Range |
|---|
| 68 | curr_match = &match; |
|---|
| 69 | bool inside = !starts_before_start() && !ends_behind_end(); |
|---|
| 70 | curr_match = NULp; |
|---|
| 71 | return inside; |
|---|
| 72 | } |
|---|
| 73 | }; |
|---|
| 74 | |
|---|
| 75 | #else |
|---|
| 76 | #error PT_rangeCheck.hxx included twice |
|---|
| 77 | #endif // PT_RANGECHECK_HXX |
|---|