Skip to content

Commit 6eff8b8

Browse files
pks-tgitster
authored andcommitted
apply: refactor code to drop line_allocated
The `struct image` has two members `line` and `line_allocated`. The former member is the one that should be used throughout the code, whereas the latter one is used to track whether the lines have been allocated or not. In practice, the array of lines is always allocated. The reason why we have `line_allocated` is that `remove_first_line()` will advance the array pointer to drop the first entry, and thus it points into the array instead of to the array header. Refactor the function to use memmove(3P) instead, which allows us to get rid of this double bookkeeping. This is less efficient, but I doubt that this matters much in practice. If this judgement call is found to be wrong at a later point in time we can likely refactor the surrounding loop such that we first calculate the number of leading context lines to remove and then remove them in a single call to memmove(3P). Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7db28d0 commit 6eff8b8

File tree

1 file changed

+14
-19
lines changed

1 file changed

+14
-19
lines changed

apply.c

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,6 @@ struct image {
281281
size_t len;
282282
size_t nr;
283283
size_t alloc;
284-
struct line *line_allocated;
285284
struct line *line;
286285
};
287286
#define IMAGE_INIT { 0 }
@@ -295,7 +294,7 @@ static void image_init(struct image *image)
295294
static void image_clear(struct image *image)
296295
{
297296
free(image->buf);
298-
free(image->line_allocated);
297+
free(image->line);
299298
image_init(image);
300299
}
301300

@@ -313,10 +312,10 @@ static uint32_t hash_line(const char *cp, size_t len)
313312

314313
static void image_add_line(struct image *img, const char *bol, size_t len, unsigned flag)
315314
{
316-
ALLOC_GROW(img->line_allocated, img->nr + 1, img->alloc);
317-
img->line_allocated[img->nr].len = len;
318-
img->line_allocated[img->nr].hash = hash_line(bol, len);
319-
img->line_allocated[img->nr].flag = flag;
315+
ALLOC_GROW(img->line, img->nr + 1, img->alloc);
316+
img->line[img->nr].len = len;
317+
img->line[img->nr].hash = hash_line(bol, len);
318+
img->line[img->nr].flag = flag;
320319
img->nr++;
321320
}
322321

@@ -348,15 +347,15 @@ static void image_prepare(struct image *image, char *buf, size_t len,
348347
image_add_line(image, cp, next - cp, 0);
349348
cp = next;
350349
}
351-
image->line = image->line_allocated;
352350
}
353351

354352
static void image_remove_first_line(struct image *img)
355353
{
356354
img->buf += img->line[0].len;
357355
img->len -= img->line[0].len;
358-
img->line++;
359356
img->nr--;
357+
if (img->nr)
358+
MOVE_ARRAY(img->line, img->line + 1, img->nr);
360359
}
361360

362361
static void image_remove_last_line(struct image *img)
@@ -2335,7 +2334,7 @@ static void update_pre_post_images(struct image *preimage,
23352334
: fixed_preimage.nr <= preimage->nr);
23362335
for (i = 0; i < fixed_preimage.nr; i++)
23372336
fixed_preimage.line[i].flag = preimage->line[i].flag;
2338-
free(preimage->line_allocated);
2337+
free(preimage->line);
23392338
*preimage = fixed_preimage;
23402339

23412340
/*
@@ -2879,14 +2878,12 @@ static void update_image(struct apply_state *state,
28792878

28802879
/* Adjust the line table */
28812880
nr = img->nr + postimage->nr - preimage_limit;
2882-
if (preimage_limit < postimage->nr) {
2881+
if (preimage_limit < postimage->nr)
28832882
/*
28842883
* NOTE: this knows that we never call image_remove_first_line()
28852884
* on anything other than pre/post image.
28862885
*/
28872886
REALLOC_ARRAY(img->line, nr);
2888-
img->line_allocated = img->line;
2889-
}
28902887
if (preimage_limit != postimage->nr)
28912888
MOVE_ARRAY(img->line + applied_pos + postimage->nr,
28922889
img->line + applied_pos + preimage_limit,
@@ -3027,8 +3024,8 @@ static int apply_one_fragment(struct apply_state *state,
30273024
newlines.len > 0 && newlines.buf[newlines.len - 1] == '\n') {
30283025
old--;
30293026
strbuf_setlen(&newlines, newlines.len - 1);
3030-
preimage.line_allocated[preimage.nr - 1].len--;
3031-
postimage.line_allocated[postimage.nr - 1].len--;
3027+
preimage.line[preimage.nr - 1].len--;
3028+
postimage.line[postimage.nr - 1].len--;
30323029
}
30333030

30343031
leading = frag->leading;
@@ -3062,8 +3059,6 @@ static int apply_one_fragment(struct apply_state *state,
30623059
preimage.len = old - oldlines;
30633060
postimage.buf = newlines.buf;
30643061
postimage.len = newlines.len;
3065-
preimage.line = preimage.line_allocated;
3066-
postimage.line = postimage.line_allocated;
30673062

30683063
for (;;) {
30693064

@@ -3151,8 +3146,8 @@ static int apply_one_fragment(struct apply_state *state,
31513146
out:
31523147
free(oldlines);
31533148
strbuf_release(&newlines);
3154-
free(preimage.line_allocated);
3155-
free(postimage.line_allocated);
3149+
free(preimage.line);
3150+
free(postimage.line);
31563151

31573152
return (applied_pos < 0);
31583153
}
@@ -3752,7 +3747,7 @@ static int apply_data(struct apply_state *state, struct patch *patch,
37523747
patch->result = image.buf;
37533748
patch->resultsize = image.len;
37543749
add_to_fn_table(state, patch);
3755-
free(image.line_allocated);
3750+
free(image.line);
37563751

37573752
if (0 < patch->is_delete && patch->resultsize)
37583753
return error(_("removal patch leaves file contents"));

0 commit comments

Comments
 (0)