]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
include/interval_set: tolerate maps that invalidate iterator on change
authorSage Weil <sage@redhat.com>
Sat, 28 Oct 2017 20:37:03 +0000 (15:37 -0500)
committerIgor Fedotov <ifedotov@suse.com>
Thu, 12 Apr 2018 18:34:28 +0000 (21:34 +0300)
These changes picked out of the diff between the original
btree_interval_set.h and interval_set.h (sadly I had it rolled into the
initial commit so it was tedious to identify these).

Signed-off-by: Sage Weil <sage@redhat.com>
(cherry picked from commit 87aed2026a8f689540a92eeeea6b4054b6c69acd)

src/include/interval_set.h

index 9092b3b3ceb16ca7a62021d52c8d4cc2e7891ec4..fd48c2a2be7cfea377255408b5776977566a8a25 100644 (file)
 
 #include "encoding.h"
 
+/*
+ * *** NOTE ***
+ *
+ * This class is written to work with a variety of map-like containers,
+ * *include* ones that invalidate iterators when they are modified (e.g.,
+ * flat_map and btree_map).
+ */
+
 #ifndef MIN
 # define MIN(a,b)  ((a)<=(b) ? (a):(b))
 #endif
@@ -461,30 +469,34 @@ class interval_set {
         
         typename Map::iterator n = p;
         n++;
+       if (pstart)
+         *pstart = p->first;
         if (n != m.end() && 
             start+len == n->first) {   // combine with next, too!
           p->second += n->second;
+         if (plen)
+           *plen = p->second;
           m.erase(n);
-        }
-       if (pstart)
-         *pstart = p->first;
-       if (plen)
-         *plen = p->second;
+        } else {
+         if (plen)
+           *plen = p->second;
+       }
       } else {
         if (start+len == p->first) {
-          m[start] = len + p->second;  // append to front 
          if (pstart)
            *pstart = start;
          if (plen)
            *plen = len + p->second;
+         T psecond = p->second;
           m.erase(p);
+          m[start] = len + psecond;  // append to front
         } else {
           assert(p->first > start+len);
-          m[start] = len;              // new interval
          if (pstart)
            *pstart = start;
          if (plen)
            *plen = len;
+          m[start] = len;              // new interval
         }
       }
     }