src/buffer.c

changeset 1516
95b094472e9a
parent 1515
f024313c08f1
--- a/src/buffer.c	Wed Nov 26 23:22:03 2025 +0100
+++ b/src/buffer.c	Wed Nov 26 23:35:25 2025 +0100
@@ -261,32 +261,35 @@
     }
 }
 
+static size_t cx_buffer_calculate_minimum_capacity(size_t mincap) {
+    unsigned long pagesize = system_page_size();
+    // if page size is larger than 64 KB - for some reason - truncate to 64 KB
+    if (pagesize > 65536) pagesize = 65536;
+    if (mincap < pagesize) {
+        // when smaller as one page, map to the next power of two
+        mincap--;
+        mincap |= mincap >> 1;
+        mincap |= mincap >> 2;
+        mincap |= mincap >> 4;
+        // last operation only needed for pages larger 4096 bytes
+        // but if/else would be more expensive than just doing this
+        mincap |= mincap >> 8;
+        mincap++;
+    } else {
+        // otherwise, map to a multiple of the page size
+        mincap -= mincap % pagesize;
+        mincap += pagesize;
+        // note: if newcap is already page aligned,
+        // this gives a full additional page (which is good)
+    }
+    return mincap;
+}
+
 int cxBufferMinimumCapacity(CxBuffer *buffer, size_t newcap) {
     if (newcap <= buffer->capacity) {
         return 0;
     }
-
-    unsigned long pagesize = system_page_size();
-    // if page size is larger than 64 KB - for some reason - truncate to 64 KB
-    if (pagesize > 65536) pagesize = 65536;
-    if (newcap < pagesize) {
-        // when smaller as one page, map to the next power of two
-        newcap--;
-        newcap |= newcap >> 1;
-        newcap |= newcap >> 2;
-        newcap |= newcap >> 4;
-        // last operation only needed for pages larger 4096 bytes
-        // but if/else would be more expensive than just doing this
-        newcap |= newcap >> 8;
-        newcap++;
-    } else {
-        // otherwise, map to a multiple of the page size
-        newcap -= newcap % pagesize;
-        newcap += pagesize;
-        // note: if newcap is already page aligned,
-        // this gives a full additional page (which is good)
-    }
-
+    newcap = cx_buffer_calculate_minimum_capacity(newcap);
     return cxBufferReserve(buffer, newcap);
 }
 
@@ -392,8 +395,17 @@
     bool perform_flush = false;
     if (required > buffer->capacity) {
         if (buffer->flags & CX_BUFFER_AUTO_EXTEND) {
-            if (buffer->flush != NULL && required > buffer->flush->threshold) {
-                perform_flush = true;
+            if (buffer->flush != NULL) {
+                size_t newcap = cx_buffer_calculate_minimum_capacity(required);
+                if (newcap > buffer->flush->threshold) {
+                    newcap = buffer->flush->threshold;
+                }
+                if (cxBufferReserve(buffer, newcap)) {
+                    return total_flushed; // LCOV_EXCL_LINE
+                }
+                if (required > newcap) {
+                    perform_flush = true;
+                }
             } else {
                 if (cxBufferMinimumCapacity(buffer, required)) {
                     return total_flushed; // LCOV_EXCL_LINE

mercurial