]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
bufferlist: use iterators for comparison operators 34292/head
authorCasey Bodley <cbodley@redhat.com>
Mon, 30 Mar 2020 16:46:33 +0000 (12:46 -0400)
committerCasey Bodley <cbodley@redhat.com>
Mon, 13 Apr 2020 15:19:24 +0000 (11:19 -0400)
bufferlist's operator[] is not constant time! use iterators to avoid
these costly indexing operations

Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/include/buffer.h
src/test/bufferlist.cc

index 9e0c2fd4d280546b9b6ad43382b3018f24f9166b..c8805cc512059a990d2ac87b4641a6e012f87625 100644 (file)
@@ -1230,44 +1230,40 @@ inline namespace v15_2_0 {
     }
   };
 
-inline bool operator>(const bufferlist& l, const bufferlist& r) {
-  for (unsigned p = 0; ; p++) {
-    if (l.length() > p && r.length() == p) return true;
-    if (l.length() == p) return false;
-    if (l[p] > r[p]) return true;
-    if (l[p] < r[p]) return false;
-  }
+inline bool operator==(const bufferlist &lhs, const bufferlist &rhs) {
+  if (lhs.length() != rhs.length())
+    return false;
+  return std::equal(lhs.begin(), lhs.end(), rhs.begin());
 }
-inline bool operator>=(const bufferlist& l, const bufferlist& r) {
-  for (unsigned p = 0; ; p++) {
-    if (l.length() > p && r.length() == p) return true;
-    if (r.length() == p && l.length() == p) return true;
-    if (l.length() == p && r.length() > p) return false;
-    if (l[p] > r[p]) return true;
-    if (l[p] < r[p]) return false;
+
+inline bool operator<(const bufferlist& lhs, const bufferlist& rhs) {
+  auto l = lhs.begin(), r = rhs.begin();
+  for (; l != lhs.end() && r != rhs.end(); ++l, ++r) {
+    if (*l < *r) return true;
+    if (*l > *r) return false;
   }
+  return (l == lhs.end()) && (r != rhs.end()); // lhs.length() < rhs.length()
 }
 
-inline bool operator==(const bufferlist &l, const bufferlist &r) {
-  if (l.length() != r.length())
-    return false;
-  for (unsigned p = 0; p < l.length(); p++) {
-    if (l[p] != r[p])
-      return false;
+inline bool operator<=(const bufferlist& lhs, const bufferlist& rhs) {
+  auto l = lhs.begin(), r = rhs.begin();
+  for (; l != lhs.end() && r != rhs.end(); ++l, ++r) {
+    if (*l < *r) return true;
+    if (*l > *r) return false;
   }
-  return true;
+  return l == lhs.end(); // lhs.length() <= rhs.length()
 }
+
 inline bool operator!=(const bufferlist &l, const bufferlist &r) {
   return !(l == r);
 }
-inline bool operator<(const bufferlist& l, const bufferlist& r) {
-  return r > l;
+inline bool operator>(const bufferlist& lhs, const bufferlist& rhs) {
+  return rhs < lhs;
 }
-inline bool operator<=(const bufferlist& l, const bufferlist& r) {
-  return r >= l;
+inline bool operator>=(const bufferlist& lhs, const bufferlist& rhs) {
+  return rhs <= lhs;
 }
 
-
 std::ostream& operator<<(std::ostream& out, const buffer::ptr& bp);
 
 std::ostream& operator<<(std::ostream& out, const buffer::raw &r);
index 37de45f0e3156d34a795a1ce1c6a2d5132ff715b..eb40b6483d93a6463cbfb4a7513a90df95c3808a 100644 (file)
@@ -2540,8 +2540,9 @@ TEST(BufferList, crc32c_append_perf) {
 TEST(BufferList, compare) {
   bufferlist a;
   a.append("A");
-  bufferlist ab;
-  ab.append("AB");
+  bufferlist ab; // AB in segments
+  ab.append(bufferptr("A", 1));
+  ab.append(bufferptr("B", 1));
   bufferlist ac;
   ac.append("AC");
   //