diff options
| author | Jiang Xin <worldhello.net@gmail.com> | 2023-05-16 10:19:48 +0800 |
|---|---|---|
| committer | Jiang Xin <worldhello.net@gmail.com> | 2023-05-16 10:19:48 +0800 |
| commit | 03d05937a70900819a5a73583a96bcb1fd06eb68 (patch) | |
| tree | d952758a83872e5da54abd45fc8463037fb329ee /alloc.h | |
| parent | f66ad35508e31c80fb0a7c235bdadfb76fc8ffaf (diff) | |
| parent | 0df2c180904f6b709766f9c24669a9d01543f915 (diff) | |
| download | git-03d05937a70900819a5a73583a96bcb1fd06eb68.tar.xz | |
Merge tag 'v2.41.0-rc0'
Git 2.41-rc0
* tag 'v2.41.0-rc0': (508 commits)
Git 2.41-rc0
t5583: fix shebang line
merge-tree: load default git config
fetch: introduce machine-parseable "porcelain" output format
fetch: move option related variables into main function
fetch: lift up parsing of "fetch.output" config variable
fetch: introduce `display_format` enum
fetch: refactor calculation of the display table width
fetch: print left-hand side when fetching HEAD:foo
fetch: add a test to exercise invalid output formats
fetch: split out tests for output format
fetch: fix `--no-recurse-submodules` with multi-remote fetches
The eighteenth batch
The seventeenth batch
diff-files: integrate with sparse index
t1092: add tests for `git diff-files`
test: rev-parse-upstream: add missing cmp
t: drop "verbose" helper function
t7001: use "ls-files --format" instead of "cut"
t7001: avoid git on upstream of pipe
...
Diffstat (limited to 'alloc.h')
| -rw-r--r-- | alloc.h | 75 |
1 files changed, 75 insertions, 0 deletions
@@ -17,4 +17,79 @@ void *alloc_object_node(struct repository *r); struct alloc_state *allocate_alloc_state(void); void clear_alloc_state(struct alloc_state *s); +#define alloc_nr(x) (((x)+16)*3/2) + +/** + * Dynamically growing an array using realloc() is error prone and boring. + * + * Define your array with: + * + * - a pointer (`item`) that points at the array, initialized to `NULL` + * (although please name the variable based on its contents, not on its + * type); + * + * - an integer variable (`alloc`) that keeps track of how big the current + * allocation is, initialized to `0`; + * + * - another integer variable (`nr`) to keep track of how many elements the + * array currently has, initialized to `0`. + * + * Then before adding `n`th element to the item, call `ALLOC_GROW(item, n, + * alloc)`. This ensures that the array can hold at least `n` elements by + * calling `realloc(3)` and adjusting `alloc` variable. + * + * ------------ + * sometype *item; + * size_t nr; + * size_t alloc + * + * for (i = 0; i < nr; i++) + * if (we like item[i] already) + * return; + * + * // we did not like any existing one, so add one + * ALLOC_GROW(item, nr + 1, alloc); + * item[nr++] = value you like; + * ------------ + * + * You are responsible for updating the `nr` variable. + * + * If you need to specify the number of elements to allocate explicitly + * then use the macro `REALLOC_ARRAY(item, alloc)` instead of `ALLOC_GROW`. + * + * Consider using ALLOC_GROW_BY instead of ALLOC_GROW as it has some + * added niceties. + * + * DO NOT USE any expression with side-effect for 'x', 'nr', or 'alloc'. + */ +#define ALLOC_GROW(x, nr, alloc) \ + do { \ + if ((nr) > alloc) { \ + if (alloc_nr(alloc) < (nr)) \ + alloc = (nr); \ + else \ + alloc = alloc_nr(alloc); \ + REALLOC_ARRAY(x, alloc); \ + } \ + } while (0) + +/* + * Similar to ALLOC_GROW but handles updating of the nr value and + * zeroing the bytes of the newly-grown array elements. + * + * DO NOT USE any expression with side-effect for any of the + * arguments. + */ +#define ALLOC_GROW_BY(x, nr, increase, alloc) \ + do { \ + if (increase) { \ + size_t new_nr = nr + (increase); \ + if (new_nr < nr) \ + BUG("negative growth in ALLOC_GROW_BY"); \ + ALLOC_GROW(x, new_nr, alloc); \ + memset((x) + nr, 0, sizeof(*(x)) * (increase)); \ + nr = new_nr; \ + } \ + } while (0) + #endif |
