]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
include/interval_set: templating map used
authorSage Weil <sage@redhat.com>
Sat, 28 Oct 2017 20:27:47 +0000 (15:27 -0500)
committerSage Weil <sage@redhat.com>
Sat, 28 Oct 2017 21:21:38 +0000 (16:21 -0500)
Default to std::map for backward compat.

Signed-off-by: Sage Weil <sage@redhat.com>
src/include/interval_set.h

index ee6da3a87dd92cd849459d76d1545b4ce123fca2..d46121302bfe534e183713f3387cca4ca6d83c9c 100644 (file)
@@ -30,7 +30,7 @@
 #endif
 
 
-template<typename T>
+template<typename T, typename Map = std::map<T,T>>
 class interval_set {
  public:
 
@@ -39,7 +39,7 @@ class interval_set {
   class iterator : public std::iterator <std::forward_iterator_tag, T>
   {
     public:
-        explicit iterator(typename std::map<T,T>::iterator iter)
+        explicit iterator(typename Map::iterator iter)
           : _iter(iter)
         { }
 
@@ -89,17 +89,17 @@ class interval_set {
                 return prev;
         }
 
-    friend class interval_set<T>::const_iterator;
+    friend class interval_set<T,Map>::const_iterator;
 
     protected:
-        typename std::map<T,T>::iterator _iter;
-    friend class interval_set<T>;
+        typename Map::iterator _iter;
+    friend class interval_set<T,Map>;
   };
 
   class const_iterator : public std::iterator <std::forward_iterator_tag, T>
   {
     public:
-        explicit const_iterator(typename std::map<T,T>::const_iterator iter)
+        explicit const_iterator(typename Map::const_iterator iter)
           : _iter(iter)
         { }
 
@@ -149,11 +149,11 @@ class interval_set {
         }
 
     protected:
-        typename std::map<T,T>::const_iterator _iter;
+        typename Map::const_iterator _iter;
   };
 
   interval_set() : _size(0) {}
-  interval_set(std::map<T,T>& other) {
+  interval_set(Map& other) {
     m.swap(other);
     _size = 0;
     for (auto& i : m) {
@@ -166,34 +166,34 @@ class interval_set {
     return m.size();
   }
 
-  typename interval_set<T>::iterator begin() {
-    return typename interval_set<T>::iterator(m.begin());
+  typename interval_set<T,Map>::iterator begin() {
+    return typename interval_set<T,Map>::iterator(m.begin());
   }
 
-  typename interval_set<T>::iterator lower_bound(T start) {
-    return typename interval_set<T>::iterator(find_inc_m(start));
+  typename interval_set<T,Map>::iterator lower_bound(T start) {
+    return typename interval_set<T,Map>::iterator(find_inc_m(start));
   }
 
-  typename interval_set<T>::iterator end() {
-    return typename interval_set<T>::iterator(m.end());
+  typename interval_set<T,Map>::iterator end() {
+    return typename interval_set<T,Map>::iterator(m.end());
   }
 
-  typename interval_set<T>::const_iterator begin() const {
-    return typename interval_set<T>::const_iterator(m.begin());
+  typename interval_set<T,Map>::const_iterator begin() const {
+    return typename interval_set<T,Map>::const_iterator(m.begin());
   }
 
-  typename interval_set<T>::const_iterator lower_bound(T start) const {
-    return typename interval_set<T>::const_iterator(find_inc(start));
+  typename interval_set<T,Map>::const_iterator lower_bound(T start) const {
+    return typename interval_set<T,Map>::const_iterator(find_inc(start));
   }
 
-  typename interval_set<T>::const_iterator end() const {
-    return typename interval_set<T>::const_iterator(m.end());
+  typename interval_set<T,Map>::const_iterator end() const {
+    return typename interval_set<T,Map>::const_iterator(m.end());
   }
 
   // helpers
  private:
-  typename std::map<T,T>::const_iterator find_inc(T start) const {
-    typename std::map<T,T>::const_iterator p = m.lower_bound(start);  // p->first >= start
+  typename Map::const_iterator find_inc(T start) const {
+    typename Map::const_iterator p = m.lower_bound(start);  // p->first >= start
     if (p != m.begin() &&
         (p == m.end() || p->first > start)) {
       p--;   // might overlap?
@@ -203,8 +203,8 @@ class interval_set {
     return p;
   }
   
-  typename std::map<T,T>::iterator find_inc_m(T start) {
-    typename std::map<T,T>::iterator p = m.lower_bound(start);
+  typename Map::iterator find_inc_m(T start) {
+    typename Map::iterator p = m.lower_bound(start);
     if (p != m.begin() &&
         (p == m.end() || p->first > start)) {
       p--;   // might overlap?
@@ -214,8 +214,8 @@ class interval_set {
     return p;
   }
   
-  typename std::map<T,T>::const_iterator find_adj(T start) const {
-    typename std::map<T,T>::const_iterator p = m.lower_bound(start);
+  typename Map::const_iterator find_adj(T start) const {
+    typename Map::const_iterator p = m.lower_bound(start);
     if (p != m.begin() &&
         (p == m.end() || p->first > start)) {
       p--;   // might touch?
@@ -225,8 +225,8 @@ class interval_set {
     return p;
   }
   
-  typename std::map<T,T>::iterator find_adj_m(T start) {
-    typename std::map<T,T>::iterator p = m.lower_bound(start);
+  typename Map::iterator find_adj_m(T start) {
+    typename Map::iterator p = m.lower_bound(start);
     if (p != m.begin() &&
         (p == m.end() || p->first > start)) {
       p--;   // might touch?
@@ -329,7 +329,7 @@ class interval_set {
   }
 
   void bound_encode(size_t& p) const {
-    denc_traits<std::map<T,T>>::bound_encode(m, p);
+    denc_traits<Map>::bound_encode(m, p);
   }
   void encode(bufferlist::contiguous_appender& p) const {
     denc(m, p);
@@ -350,10 +350,10 @@ class interval_set {
   }
 
   void encode_nohead(bufferlist::contiguous_appender& p) const {
-    denc_traits<std::map<T,T>>::encode_nohead(m, p);
+    denc_traits<Map>::encode_nohead(m, p);
   }
   void decode_nohead(int n, bufferptr::iterator& p) {
-    denc_traits<std::map<T,T>>::decode_nohead(n, m, p);
+    denc_traits<Map>::decode_nohead(n, m, p);
     _size = 0;
     for (const auto& i : m) {
       _size += i.second;
@@ -366,7 +366,7 @@ class interval_set {
   }
 
   bool contains(T i, T *pstart=0, T *plen=0) const {
-    typename std::map<T,T>::const_iterator p = find_inc(i);
+    typename Map::const_iterator p = find_inc(i);
     if (p == m.end()) return false;
     if (p->first > i) return false;
     if (p->first+p->second <= i) return false;
@@ -378,7 +378,7 @@ class interval_set {
     return true;
   }
   bool contains(T start, T len) const {
-    typename std::map<T,T>::const_iterator p = find_inc(start);
+    typename Map::const_iterator p = find_inc(start);
     if (p == m.end()) return false;
     if (p->first > start) return false;
     if (p->first+p->second <= start) return false;
@@ -401,12 +401,12 @@ class interval_set {
   }
   T range_start() const {
     assert(!empty());
-    typename std::map<T,T>::const_iterator p = m.begin();
+    typename Map::const_iterator p = m.begin();
     return p->first;
   }
   T range_end() const {
     assert(!empty());
-    typename std::map<T,T>::const_iterator p = m.end();
+    typename Map::const_iterator p = m.end();
     p--;
     return p->first+p->second;
   }
@@ -414,20 +414,20 @@ class interval_set {
   // interval start after p (where p not in set)
   bool starts_after(T i) const {
     assert(!contains(i));
-    typename std::map<T,T>::const_iterator p = find_inc(i);
+    typename Map::const_iterator p = find_inc(i);
     if (p == m.end()) return false;
     return true;
   }
   T start_after(T i) const {
     assert(!contains(i));
-    typename std::map<T,T>::const_iterator p = find_inc(i);
+    typename Map::const_iterator p = find_inc(i);
     return p->first;
   }
 
   // interval end that contains start
   T end_after(T start) const {
     assert(contains(start));
-    typename std::map<T,T>::const_iterator p = find_inc(start);
+    typename Map::const_iterator p = find_inc(start);
     return p->first+p->second;
   }
   
@@ -439,7 +439,7 @@ class interval_set {
     //cout << "insert " << start << "~" << len << endl;
     assert(len > 0);
     _size += len;
-    typename std::map<T,T>::iterator p = find_adj_m(start);
+    typename Map::iterator p = find_adj_m(start);
     if (p == m.end()) {
       m[start] = len;                  // new interval
       if (pstart)
@@ -456,7 +456,7 @@ class interval_set {
         
         p->second += len;               // append to end
         
-        typename std::map<T,T>::iterator n = p;
+        typename Map::iterator n = p;
         n++;
         if (n != m.end() && 
             start+len == n->first) {   // combine with next, too!
@@ -487,7 +487,7 @@ class interval_set {
     }
   }
 
-  void swap(interval_set<T>& other) {
+  void swap(interval_set<T,Map>& other) {
     m.swap(other.m);
     std::swap(_size, other._size);
   }    
@@ -503,7 +503,7 @@ class interval_set {
   }
 
   void erase(T start, T len) {
-    typename std::map<T,T>::iterator p = find_inc_m(start);
+    typename Map::iterator p = find_inc_m(start);
 
     _size -= len;
     assert(_size >= 0);
@@ -525,14 +525,14 @@ class interval_set {
 
 
   void subtract(const interval_set &a) {
-    for (typename std::map<T,T>::const_iterator p = a.m.begin();
+    for (typename Map::const_iterator p = a.m.begin();
          p != a.m.end();
          p++)
       erase(p->first, p->second);
   }
 
   void insert(const interval_set &a) {
-    for (typename std::map<T,T>::const_iterator p = a.m.begin();
+    for (typename Map::const_iterator p = a.m.begin();
          p != a.m.end();
          p++)
       insert(p->first, p->second);
@@ -567,8 +567,8 @@ class interval_set {
       return;
     }
 
-    typename std::map<T,T>::const_iterator pa = a.m.begin();
-    typename std::map<T,T>::const_iterator pb = b.m.begin();
+    typename Map::const_iterator pa = a.m.begin();
+    typename Map::const_iterator pb = b.m.begin();
     typename decltype(m)::iterator mi = m.begin();
 
     while (pa != a.m.end() && pb != b.m.end()) {
@@ -653,7 +653,7 @@ class interval_set {
     if (big.size() / size() < 10)
       return subset_size_sym(big);
 
-    for (typename std::map<T,T>::const_iterator i = m.begin();
+    for (typename Map::const_iterator i = m.begin();
          i != m.end();
          i++) 
       if (!big.contains(i->first, i->second)) return false;
@@ -674,7 +674,7 @@ class interval_set {
     if (end == start) {
       return;
     }
-    typename std::map<T,T>::const_iterator p = other.find_inc(start);
+    typename Map::const_iterator p = other.find_inc(start);
     if (p == other.m.end())
       return;
     if (p->first < start) {
@@ -709,7 +709,7 @@ class interval_set {
    */
   void span_of(const interval_set &other, T start, T len) {
     clear();
-    typename std::map<T,T>::const_iterator p = other.find_inc(start);
+    typename Map::const_iterator p = other.find_inc(start);
     if (p == other.m.end())
       return;
     if (p->first < start) {
@@ -738,58 +738,58 @@ class interval_set {
   }
 
   /*
-   * Move contents of m into another std::map<T,T>. Use that instead of
-   * encoding interval_set into bufferlist then decoding it back into std::map.
+   * Move contents of m into another Map. Use that instead of
+   * encoding interval_set into bufferlist then decoding it back into Map.
    */
-  void move_into(std::map<T,T>& other) {
+  void move_into(Map& other) {
     other = std::move(m);
   }
 
 private:
   // data
   int64_t _size;
-  std::map<T,T> m;   // map start -> len
+  Map m;   // map start -> len
 };
 
 // declare traits explicitly because (1) it's templatized, and (2) we
 // want to include _nohead variants.
-template<typename T>
-struct denc_traits<interval_set<T>> {
+template<typename T, typename Map>
+struct denc_traits<interval_set<T,Map>> {
   static constexpr bool supported = true;
   static constexpr bool bounded = false;
   static constexpr bool featured = false;
-  static constexpr bool need_contiguous = denc_traits<T>::need_contiguous;
-  static void bound_encode(const interval_set<T>& v, size_t& p) {
+  static constexpr bool need_contiguous = denc_traits<T,Map>::need_contiguous;
+  static void bound_encode(const interval_set<T,Map>& v, size_t& p) {
     v.bound_encode(p);
   }
-  static void encode(const interval_set<T>& v,
+  static void encode(const interval_set<T,Map>& v,
                     bufferlist::contiguous_appender& p) {
     v.encode(p);
   }
-  static void decode(interval_set<T>& v, bufferptr::iterator& p) {
+  static void decode(interval_set<T,Map>& v, bufferptr::iterator& p) {
     v.decode(p);
   }
   template<typename U=T>
     static typename std::enable_if<sizeof(U) && !need_contiguous>::type
-    decode(interval_set<T>& v, bufferlist::iterator& p) {
+    decode(interval_set<T,Map>& v, bufferlist::iterator& p) {
     v.decode(p);
   }
-  static void encode_nohead(const interval_set<T>& v,
+  static void encode_nohead(const interval_set<T,Map>& v,
                            bufferlist::contiguous_appender& p) {
     v.encode_nohead(p);
   }
-  static void decode_nohead(size_t n, interval_set<T>& v,
+  static void decode_nohead(size_t n, interval_set<T,Map>& v,
                            bufferptr::iterator& p) {
     v.decode_nohead(n, p);
   }
 };
 
 
-template<class T>
-inline std::ostream& operator<<(std::ostream& out, const interval_set<T> &s) {
+template<class T, typename Map>
+inline std::ostream& operator<<(std::ostream& out, const interval_set<T,Map> &s) {
   out << "[";
   const char *prequel = "";
-  for (typename interval_set<T>::const_iterator i = s.begin();
+  for (typename interval_set<T,Map>::const_iterator i = s.begin();
        i != s.end();
        ++i)
   {