Blame SOURCES/0020-common-urils-vector.c-Optimize-vector-append.patch

7084e2
From 5454ced7c8cfc2ba278c2635eecb9a5e4841e613 Mon Sep 17 00:00:00 2001
7084e2
From: Nir Soffer <nsoffer@redhat.com>
7084e2
Date: Fri, 5 Nov 2021 22:16:26 +0200
7084e2
Subject: [PATCH] common/urils/vector.c: Optimize vector append
7084e2
7084e2
Minimize reallocs by growing the backing array by factor of 1.5.
7084e2
7084e2
Testing show that now append() is fast without calling reserve()
7084e2
upfront, simplifying code using vector.
7084e2
7084e2
    NBDKIT_BENCH=1 ./test-vector
7084e2
    bench_reserve: 1000000 appends in 0.004496 s
7084e2
    bench_append: 1000000 appends in 0.004180 s
7084e2
7084e2
This can make a difference in code appending millions of items.
7084e2
7084e2
Ported from libnbd commit 985dfa72ae2e41901f0af21e7205ef85428cd4bd.
7084e2
7084e2
(cherry picked from commit 12356fa97a840de19bb61e0abedd6e7c7e578e5a)
7084e2
---
7084e2
 common/utils/vector.c | 14 ++++++++++++--
7084e2
 1 file changed, 12 insertions(+), 2 deletions(-)
7084e2
7084e2
diff --git a/common/utils/vector.c b/common/utils/vector.c
7084e2
index 00cd2546..7df17e1b 100644
7084e2
--- a/common/utils/vector.c
7084e2
+++ b/common/utils/vector.c
7084e2
@@ -41,11 +41,21 @@ int
7084e2
 generic_vector_reserve (struct generic_vector *v, size_t n, size_t itemsize)
7084e2
 {
7084e2
   void *newptr;
7084e2
+  size_t reqalloc, newalloc;
7084e2
 
7084e2
-  newptr = realloc (v->ptr, (n + v->alloc) * itemsize);
7084e2
+  reqalloc = v->alloc + n;
7084e2
+  if (reqalloc < v->alloc)
7084e2
+    return -1; /* overflow */
7084e2
+
7084e2
+  newalloc = (v->alloc * 3 + 1) / 2;
7084e2
+
7084e2
+  if (newalloc < reqalloc)
7084e2
+    newalloc = reqalloc;
7084e2
+
7084e2
+  newptr = realloc (v->ptr, newalloc * itemsize);
7084e2
   if (newptr == NULL)
7084e2
     return -1;
7084e2
   v->ptr = newptr;
7084e2
-  v->alloc += n;
7084e2
+  v->alloc = newalloc;
7084e2
   return 0;
7084e2
 }
7084e2
-- 
7084e2
2.31.1
7084e2