From 6a9314c82befb6f237e898774103508b137f6a52f1c7f1c80c969bb6674b7f4b Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Mon, 16 Dec 2024 18:21:42 +0300 Subject: [PATCH] Explicitly set items initial capacity --- c/cmd/print-items/print-items.c | 18 +++++++++++++++++- c/lib/items.c | 9 ++++----- c/lib/items.h | 5 +++-- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/c/cmd/print-items/print-items.c b/c/cmd/print-items/print-items.c index 9d6eaa6..d3ad628 100644 --- a/c/cmd/print-items/print-items.c +++ b/c/cmd/print-items/print-items.c @@ -271,12 +271,14 @@ main(int argc, char **argv) { bool doEncode = false; bool noTotals = false; + ptrdiff_t itemsInitialLen = 2048; NoColour = getenv("NO_COLOR") != NULL; struct option longopts[] = { {"max-str-len", required_argument, NULL, 'a'}, {"do-encode", no_argument, NULL, 'b'}, {"no-offsets", no_argument, NULL, 'c'}, {"no-totals", no_argument, NULL, 'd'}, + {"items-initial-len", required_argument, NULL, 'f'}, {NULL, 0, NULL, 0}}; int ch = 0; for (;;) { @@ -308,6 +310,20 @@ main(int argc, char **argv) case 'd': // no-totals noTotals = true; break; + case 'f': { // items-initial-len + errno = 0; + long tmp = strtol(optarg, NULL, 10); + if (errno != 0) { + fprintf(stderr, "--items-initial-len: %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + if (tmp < 0) { + fputs("--items-initial-len: is negative\n", stderr); + exit(EXIT_FAILURE); + } + itemsInitialLen = (ptrdiff_t)tmp; + break; + } case '?': default: usage(); @@ -328,7 +344,7 @@ main(int argc, char **argv) snprintf(OffFmt, sizeof OffFmt, "%%s%%0%dzd%%s ", OffDigits); struct KEKSItems items; - enum KEKSErr err = KEKSItemsInit(&items); + enum KEKSErr err = KEKSItemsInit(&items, itemsInitialLen); if (err != KEKSErrNo) { fprintf(stderr, "err: %s\n", KEKSErr2Str(err)); return EXIT_FAILURE; diff --git a/c/lib/items.c b/c/lib/items.c index 015a568..c32574a 100644 --- a/c/lib/items.c +++ b/c/lib/items.c @@ -25,14 +25,13 @@ #include "err.h" #include "items.h" -static const ptrdiff_t keksItemsPoolGrowLen = 64; static const size_t parseMaxRecursionDepth = 1024; enum KEKSErr -KEKSItemsInit(struct KEKSItems *items) +KEKSItemsInit(struct KEKSItems *items, const ptrdiff_t initialLen) { items->len = 0; - items->cap = keksItemsPoolGrowLen; + items->cap = initialLen; items->list = calloc((size_t)(items->cap), sizeof(struct KEKSItem)); if (items->list == NULL) { return KEKSErrNoMem; @@ -50,10 +49,10 @@ KEKSItemsGrow(struct KEKSItems *items) if (items->cap == -1) { return KEKSErrNoMem; } - if ((SIZE_MAX - keksItemsPoolGrowLen) < (size_t)(items->cap)) { + if ((size_t)(items->cap) >= (SIZE_MAX / 2)) { return KEKSErrNoMem; } - items->cap += keksItemsPoolGrowLen; + items->cap *= 2; { const ptrdiff_t possibleN = SIZE_MAX / sizeof(struct KEKSItem); if (items->cap > possibleN) { diff --git a/c/lib/items.h b/c/lib/items.h index 8c09624..c085484 100644 --- a/c/lib/items.h +++ b/c/lib/items.h @@ -56,7 +56,8 @@ struct KEKSItems { }; // TEXINFO: KEKSItemsInit -// @deftypefun {enum KEKSErr} KEKSItemsInit (struct KEKSItems *items) +// @deftypefun {enum KEKSErr} KEKSItemsInit @ +// (struct KEKSItems *items, const ptrdiff_t initialLen) // Initialise the @ref{KEKSItems} structure by allocating an initial // capacity for the underlying storage. // @@ -69,7 +70,7 @@ struct KEKSItems { // to NULL (do not forget to free it, if it was initialised before). // @end deftypefun enum KEKSErr -KEKSItemsInit(struct KEKSItems *); +KEKSItemsInit(struct KEKSItems *, const ptrdiff_t initialLen); // TEXINFO: KEKSItemsGrow // @deftypefun {enum KEKSErr} KEKSItemsGrow (struct KEKSItems *items) -- 2.48.1