src/buffer.c

changeset 1516
95b094472e9a
parent 1515
f024313c08f1
equal deleted inserted replaced
1515:f024313c08f1 1516:95b094472e9a
259 } else { 259 } else {
260 return -1; // LCOV_EXCL_LINE 260 return -1; // LCOV_EXCL_LINE
261 } 261 }
262 } 262 }
263 263
264 int cxBufferMinimumCapacity(CxBuffer *buffer, size_t newcap) { 264 static size_t cx_buffer_calculate_minimum_capacity(size_t mincap) {
265 if (newcap <= buffer->capacity) {
266 return 0;
267 }
268
269 unsigned long pagesize = system_page_size(); 265 unsigned long pagesize = system_page_size();
270 // if page size is larger than 64 KB - for some reason - truncate to 64 KB 266 // if page size is larger than 64 KB - for some reason - truncate to 64 KB
271 if (pagesize > 65536) pagesize = 65536; 267 if (pagesize > 65536) pagesize = 65536;
272 if (newcap < pagesize) { 268 if (mincap < pagesize) {
273 // when smaller as one page, map to the next power of two 269 // when smaller as one page, map to the next power of two
274 newcap--; 270 mincap--;
275 newcap |= newcap >> 1; 271 mincap |= mincap >> 1;
276 newcap |= newcap >> 2; 272 mincap |= mincap >> 2;
277 newcap |= newcap >> 4; 273 mincap |= mincap >> 4;
278 // last operation only needed for pages larger 4096 bytes 274 // last operation only needed for pages larger 4096 bytes
279 // but if/else would be more expensive than just doing this 275 // but if/else would be more expensive than just doing this
280 newcap |= newcap >> 8; 276 mincap |= mincap >> 8;
281 newcap++; 277 mincap++;
282 } else { 278 } else {
283 // otherwise, map to a multiple of the page size 279 // otherwise, map to a multiple of the page size
284 newcap -= newcap % pagesize; 280 mincap -= mincap % pagesize;
285 newcap += pagesize; 281 mincap += pagesize;
286 // note: if newcap is already page aligned, 282 // note: if newcap is already page aligned,
287 // this gives a full additional page (which is good) 283 // this gives a full additional page (which is good)
288 } 284 }
289 285 return mincap;
286 }
287
288 int cxBufferMinimumCapacity(CxBuffer *buffer, size_t newcap) {
289 if (newcap <= buffer->capacity) {
290 return 0;
291 }
292 newcap = cx_buffer_calculate_minimum_capacity(newcap);
290 return cxBufferReserve(buffer, newcap); 293 return cxBufferReserve(buffer, newcap);
291 } 294 }
292 295
293 void cxBufferShrink( 296 void cxBufferShrink(
294 CxBuffer *buffer, 297 CxBuffer *buffer,
390 393
391 size_t required = buffer->pos + len; 394 size_t required = buffer->pos + len;
392 bool perform_flush = false; 395 bool perform_flush = false;
393 if (required > buffer->capacity) { 396 if (required > buffer->capacity) {
394 if (buffer->flags & CX_BUFFER_AUTO_EXTEND) { 397 if (buffer->flags & CX_BUFFER_AUTO_EXTEND) {
395 if (buffer->flush != NULL && required > buffer->flush->threshold) { 398 if (buffer->flush != NULL) {
396 perform_flush = true; 399 size_t newcap = cx_buffer_calculate_minimum_capacity(required);
400 if (newcap > buffer->flush->threshold) {
401 newcap = buffer->flush->threshold;
402 }
403 if (cxBufferReserve(buffer, newcap)) {
404 return total_flushed; // LCOV_EXCL_LINE
405 }
406 if (required > newcap) {
407 perform_flush = true;
408 }
397 } else { 409 } else {
398 if (cxBufferMinimumCapacity(buffer, required)) { 410 if (cxBufferMinimumCapacity(buffer, required)) {
399 return total_flushed; // LCOV_EXCL_LINE 411 return total_flushed; // LCOV_EXCL_LINE
400 } 412 }
401 } 413 }

mercurial