00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef CGATOOLS_UTIL_RANGE_INTERSECTOR_HPP_
00016 #define CGATOOLS_UTIL_RANGE_INTERSECTOR_HPP_ 1
00017
00019
00020 #include "cgatools/core.hpp"
00021 #include "cgatools/util/Exception.hpp"
00022
00023 #include <functional>
00024 #include <map>
00025 #include <vector>
00026
00027 namespace cgatools { namespace util {
00028
00040 template < class TRange, class TValue, class Overlap, class Less = std::less<TRange> >
00041 class RangeIntersector
00042 {
00043 public:
00044 typedef std::map< TRange, TValue, Less > MapType;
00045
00047 RangeIntersector(const Overlap& overlap = Overlap(),
00048 const Less& less = Less())
00049 : overlap_(overlap),
00050 less_(less)
00051 {
00052 }
00053
00055 void put(const TRange& range, const TValue& value)
00056 {
00057
00058
00059 size_t lo = 0, hi = mtrees_.size();
00060 while (lo<hi)
00061 {
00062 size_t mid = (lo+hi)/2;
00063 MapType& tree = mtrees_[mid];
00064
00065 typename MapType::iterator iter = tree.lower_bound(range);
00066 if (iter != tree.end() && overlap_(iter->first, range))
00067 {
00068 lo = mid+1;
00069 continue;
00070 }
00071 if (iter != tree.begin() && overlap_( (--iter)->first, range ))
00072 {
00073 lo = mid+1;
00074 continue;
00075 }
00076
00077
00078 hi = mid;
00079 }
00080
00081 if (lo < mtrees_.size())
00082 {
00083 MapType& tree = mtrees_[lo];
00084 std::pair<typename MapType::iterator, bool> result =
00085 tree.insert(std::make_pair(range, value));
00086 CGA_ASSERT(result.second);
00087 return;
00088 }
00089
00090
00091 mtrees_.push_back(MapType(less_));
00092 std::pair<typename MapType::iterator, bool> result =
00093 mtrees_.back().insert(std::make_pair(range, value));
00094 CGA_ASSERT(result.second);
00095 }
00096
00099 void intersect(const TRange& range,
00100 std::vector< typename MapType::const_iterator >& result) const
00101 {
00102 result.clear();
00103 for(size_t ii=0; ii<mtrees_.size(); ii++)
00104 {
00105 const MapType& tree = mtrees_[ii];
00106
00107 typename MapType::const_iterator iter = tree.lower_bound(range);
00108 typename MapType::const_iterator fiter = iter;
00109 while (fiter != tree.end() && overlap_(fiter->first, range))
00110 result.push_back(fiter++);
00111 typename MapType::const_iterator riter = iter;
00112 while (riter != tree.begin() && overlap_( (--riter)->first, range))
00113 result.push_back(riter);
00114 }
00115 }
00116
00119 bool intersects(const TRange& range) const
00120 {
00121 for(size_t ii=0; ii<mtrees_.size(); ii++)
00122 {
00123 const MapType& tree = mtrees_[ii];
00124
00125 typename MapType::const_iterator iter = tree.lower_bound(range);
00126 if (iter != tree.end() && overlap_(iter->first, range))
00127 return true;
00128 if (iter != tree.begin() && overlap_( (--iter)->first, range ))
00129 return true;
00130 }
00131
00132 return false;
00133 }
00134
00138 size_t getTreeCount() const
00139 {
00140 return mtrees_.size();
00141 }
00142
00143 private:
00144 std::vector< MapType > mtrees_;
00145 Overlap overlap_;
00146 Less less_;
00147 };
00148
00149 } }
00150
00151 #endif // CGATOOLS_UTIL_RANGE_INTERSECTOR_HPP_