commit dd29967c8be9311a99ae3310d49789c65989498e from: Stefan Sperling date: Sun Aug 22 12:53:22 2021 UTC make got_deltify() rellocate the deltas array less often commit - 9ca26ac322eae778bdfe032617ce9f6af859bb7a commit + dd29967c8be9311a99ae3310d49789c65989498e blob - e16e734249903eb0b7588c2328c8ca29db9b48c1 blob + 11fc8f8ed2734cf2d8a8b6d4fab38a2d55751418 --- lib/deltify.c +++ lib/deltify.c @@ -296,17 +296,20 @@ got_deltify_free(struct got_delta_table *dt) } static const struct got_error * -emitdelta(struct got_delta_instruction **deltas, int *ndeltas, int copy, - off_t offset, off_t len) +emitdelta(struct got_delta_instruction **deltas, size_t *nalloc, int *ndeltas, + const size_t alloc_chunk_size, int copy, off_t offset, off_t len) { struct got_delta_instruction *d, *p; + if (*nalloc < *ndeltas + alloc_chunk_size) { + p = reallocarray(*deltas, *nalloc + alloc_chunk_size, + sizeof(struct got_delta_instruction)); + if (p == NULL) + return got_error_from_errno("realloc"); + *deltas = p; + *nalloc += alloc_chunk_size; + } *ndeltas += 1; - p = reallocarray(*deltas, *ndeltas, - sizeof(struct got_delta_instruction)); - if (p == NULL) - return got_error_from_errno("realloc"); - *deltas = p; d = &(*deltas)[*ndeltas - 1]; d->copy = copy; d->offset = offset; @@ -358,6 +361,8 @@ got_deltify(struct got_delta_instruction **deltas, int { const struct got_error *err = NULL; const off_t offset0 = fileoffset; + size_t nalloc = 0; + const size_t alloc_chunk_size = 64; *deltas = NULL; *ndeltas = 0; @@ -370,6 +375,12 @@ got_deltify(struct got_delta_instruction **deltas, int if (fseeko(f, offset0, SEEK_SET) == -1) return got_error_from_errno("fseeko"); + *deltas = reallocarray(NULL, alloc_chunk_size, + sizeof(struct got_delta_instruction)); + if (*deltas == NULL) + return got_error_from_errno("reallocarray"); + nalloc = alloc_chunk_size; + while (fileoffset < filesize) { uint8_t buf[GOT_DELTIFY_MAXCHUNK]; off_t blocklen; @@ -380,8 +391,8 @@ got_deltify(struct got_delta_instruction **deltas, int if (blocklen == 0) { /* Source remainder from the file itself. */ if (fileoffset < filesize) { - err = emitdelta(deltas, ndeltas, 0, - fileoffset - offset0, + err = emitdelta(deltas, &nalloc, ndeltas, + alloc_chunk_size, 0, fileoffset - offset0, filesize - fileoffset); } break; @@ -400,7 +411,8 @@ got_deltify(struct got_delta_instruction **deltas, int f, filesize, &blocklen); if (err) break; - err = emitdelta(deltas, ndeltas, 1, block->offset, blocklen); + err = emitdelta(deltas, &nalloc, ndeltas, + alloc_chunk_size, 1, block->offset, blocklen); if (err) break; } else { @@ -408,8 +420,8 @@ got_deltify(struct got_delta_instruction **deltas, int * No match. * This block needs to be sourced from the file itself. */ - err = emitdelta(deltas, ndeltas, 0, fileoffset - offset0, - blocklen); + err = emitdelta(deltas, &nalloc, ndeltas, + alloc_chunk_size, 0, fileoffset - offset0, blocklen); if (err) break; }