Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 26f2cef

Browse files
carlosmnEdward Thomson
authored and
Edward Thomson
committed
tree: re-use the id and filename in the odb object
Instead of copying over the data into the individual entries, point to the originals, which are already in a format we can use.
1 parent 1778908 commit 26f2cef

File tree

8 files changed

+67
-52
lines changed

8 files changed

+67
-52
lines changed

src/index.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2836,7 +2836,7 @@ static int read_tree_cb(
28362836
return -1;
28372837

28382838
entry->mode = tentry->attr;
2839-
entry->id = tentry->oid;
2839+
git_oid_cpy(&entry->id, git_tree_entry_id(tentry));
28402840

28412841
/* look for corresponding old entry and copy data to new entry */
28422842
if (data->old_entries != NULL &&

src/iterator.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ static int tree_iterator__set_next(tree_iterator *ti, tree_iterator_frame *tf)
458458
/* try to load trees for items in [current,next) range */
459459
if (!error && git_tree_entry__is_tree(te))
460460
error = git_tree_lookup(
461-
&tf->entries[tf->next]->tree, ti->base.repo, &te->oid);
461+
&tf->entries[tf->next]->tree, ti->base.repo, te->oid);
462462
}
463463

464464
if (tf->next > tf->current + 1)
@@ -603,7 +603,7 @@ static int tree_iterator__update_entry(tree_iterator *ti)
603603
te = tf->entries[tf->current]->te;
604604

605605
ti->entry.mode = te->attr;
606-
git_oid_cpy(&ti->entry.id, &te->oid);
606+
git_oid_cpy(&ti->entry.id, te->oid);
607607

608608
ti->entry.path = tree_iterator__current_filename(ti, te);
609609
GITERR_CHECK_ALLOC(ti->entry.path);

src/push.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,9 @@ static int enqueue_object(
374374
case GIT_OBJ_COMMIT:
375375
return 0;
376376
case GIT_OBJ_TREE:
377-
return git_packbuilder_insert_tree(pb, &entry->oid);
377+
return git_packbuilder_insert_tree(pb, entry->oid);
378378
default:
379-
return git_packbuilder_insert(pb, &entry->oid, entry->filename);
379+
return git_packbuilder_insert(pb, entry->oid, entry->filename);
380380
}
381381
}
382382

@@ -396,7 +396,7 @@ static int queue_differences(
396396
const git_tree_entry *d_entry = git_tree_entry_byindex(delta, j);
397397
int cmp = 0;
398398

399-
if (!git_oid__cmp(&b_entry->oid, &d_entry->oid))
399+
if (!git_oid__cmp(b_entry->oid, d_entry->oid))
400400
goto loop;
401401

402402
cmp = strcmp(b_entry->filename, d_entry->filename);
@@ -407,15 +407,15 @@ static int queue_differences(
407407
git_tree_entry__is_tree(b_entry) &&
408408
git_tree_entry__is_tree(d_entry)) {
409409
/* Add the right-hand entry */
410-
if ((error = git_packbuilder_insert(pb, &d_entry->oid,
410+
if ((error = git_packbuilder_insert(pb, d_entry->oid,
411411
d_entry->filename)) < 0)
412412
goto on_error;
413413

414414
/* Acquire the subtrees and recurse */
415415
if ((error = git_tree_lookup(&b_child,
416-
git_tree_owner(base), &b_entry->oid)) < 0 ||
416+
git_tree_owner(base), b_entry->oid)) < 0 ||
417417
(error = git_tree_lookup(&d_child,
418-
git_tree_owner(delta), &d_entry->oid)) < 0 ||
418+
git_tree_owner(delta), d_entry->oid)) < 0 ||
419419
(error = queue_differences(b_child, d_child, pb)) < 0)
420420
goto on_error;
421421

src/submodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1417,7 +1417,7 @@ static int submodule_update_head(git_submodule *submodule)
14171417
git_tree_entry_bypath(&te, head, submodule->path) < 0)
14181418
giterr_clear();
14191419
else
1420-
submodule_update_from_head_data(submodule, te->attr, &te->oid);
1420+
submodule_update_from_head_data(submodule, te->attr, git_tree_entry_id(te));
14211421

14221422
git_tree_entry_free(te);
14231423
git_tree_free(head);

src/tree.c

Lines changed: 51 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -87,25 +87,40 @@ int git_tree_entry_icmp(const git_tree_entry *e1, const git_tree_entry *e2)
8787
/**
8888
* Allocate either from the pool or from the system allocator
8989
*/
90-
static git_tree_entry *alloc_entry_base(git_pool *pool, const char *filename, size_t filename_len)
90+
static git_tree_entry *alloc_entry_base(git_pool *pool, const char *filename, size_t filename_len, const git_oid *id)
9191
{
9292
git_tree_entry *entry = NULL;
9393
size_t tree_len;
9494

9595
TREE_ENTRY_CHECK_NAMELEN(filename_len);
96+
tree_len = sizeof(git_tree_entry);
9697

97-
if (GIT_ADD_SIZET_OVERFLOW(&tree_len, sizeof(git_tree_entry), filename_len) ||
98-
GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, 1))
98+
if (!pool && (GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, filename_len) ||
99+
GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, 1) ||
100+
GIT_ADD_SIZET_OVERFLOW(&tree_len, tree_len, GIT_OID_RAWSZ)))
99101
return NULL;
100102

101-
entry = pool ? git_pool_malloc(pool, tree_len) :
102-
git__malloc(tree_len);
103+
entry = pool ? git_pool_mallocz(pool, tree_len) :
104+
git__calloc(1, tree_len);
103105
if (!entry)
104106
return NULL;
105107

106-
memset(entry, 0x0, sizeof(git_tree_entry));
107-
memcpy(entry->filename, filename, filename_len);
108-
entry->filename[filename_len] = 0;
108+
if (pool) {
109+
entry->filename = filename;
110+
entry->oid = (git_oid *) id;
111+
} else {
112+
char *filename_ptr;
113+
void *id_ptr;
114+
115+
filename_ptr = ((char *) entry) + sizeof(git_tree_entry);
116+
memcpy(filename_ptr, filename, filename_len);
117+
entry->filename = filename_ptr;
118+
119+
id_ptr = filename_ptr + filename_len + 1;
120+
git_oid_cpy(id_ptr, id);
121+
entry->oid = id_ptr;
122+
}
123+
109124
entry->filename_len = (uint16_t)filename_len;
110125

111126
return entry;
@@ -116,11 +131,11 @@ static git_tree_entry *alloc_entry_base(git_pool *pool, const char *filename, si
116131
* it. This is useful when reading trees, so we don't allocate a ton
117132
* of small strings but can use the pool.
118133
*/
119-
static git_tree_entry *alloc_entry_pooled(git_pool *pool, const char *filename, size_t filename_len)
134+
static git_tree_entry *alloc_entry_pooled(git_pool *pool, const char *filename, size_t filename_len, const git_oid *id)
120135
{
121136
git_tree_entry *entry = NULL;
122137

123-
if (!(entry = alloc_entry_base(pool, filename, filename_len)))
138+
if (!(entry = alloc_entry_base(pool, filename, filename_len, id)))
124139
return NULL;
125140

126141
entry->pooled = true;
@@ -130,7 +145,8 @@ static git_tree_entry *alloc_entry_pooled(git_pool *pool, const char *filename,
130145

131146
static git_tree_entry *alloc_entry(const char *filename)
132147
{
133-
return alloc_entry_base(NULL, filename, strlen(filename));
148+
git_oid dummy_id = { 0 };
149+
return alloc_entry_base(NULL, filename, strlen(filename), &dummy_id);
134150
}
135151

136152
struct tree_key_search {
@@ -242,22 +258,12 @@ void git_tree_entry_free(git_tree_entry *entry)
242258

243259
int git_tree_entry_dup(git_tree_entry **dest, const git_tree_entry *source)
244260
{
245-
size_t total_size;
246-
git_tree_entry *copy;
247-
248261
assert(source);
249262

250-
GITERR_CHECK_ALLOC_ADD(&total_size, sizeof(git_tree_entry), source->filename_len);
251-
GITERR_CHECK_ALLOC_ADD(&total_size, total_size, 1);
252-
253-
copy = git__malloc(total_size);
254-
GITERR_CHECK_ALLOC(copy);
255-
256-
memcpy(copy, source, total_size);
257-
258-
copy->pooled = 0;
263+
*dest = alloc_entry_base(NULL, source->filename, source->filename_len, source->oid);
264+
if (*dest == NULL)
265+
return -1;
259266

260-
*dest = copy;
261267
return 0;
262268
}
263269

@@ -270,6 +276,7 @@ void git_tree__free(void *_tree)
270276
git_vector_foreach(&tree->entries, i, e)
271277
git_tree_entry_free(e);
272278

279+
git_odb_object_free(tree->odb_obj);
273280
git_vector_free(&tree->entries);
274281
git_pool_clear(&tree->pool);
275282
git__free(tree);
@@ -294,7 +301,7 @@ const char *git_tree_entry_name(const git_tree_entry *entry)
294301
const git_oid *git_tree_entry_id(const git_tree_entry *entry)
295302
{
296303
assert(entry);
297-
return &entry->oid;
304+
return entry->oid;
298305
}
299306

300307
git_otype git_tree_entry_type(const git_tree_entry *entry)
@@ -315,7 +322,7 @@ int git_tree_entry_to_object(
315322
const git_tree_entry *entry)
316323
{
317324
assert(entry && object_out);
318-
return git_object_lookup(object_out, repo, &entry->oid, GIT_OBJ_ANY);
325+
return git_object_lookup(object_out, repo, entry->oid, GIT_OBJ_ANY);
319326
}
320327

321328
static const git_tree_entry *entry_fromname(
@@ -356,7 +363,7 @@ const git_tree_entry *git_tree_entry_byid(
356363
assert(tree);
357364

358365
git_vector_foreach(&tree->entries, i, e) {
359-
if (memcmp(&e->oid.id, &id->id, sizeof(id->id)) == 0)
366+
if (memcmp(&e->oid->id, &id->id, sizeof(id->id)) == 0)
360367
return e;
361368
}
362369

@@ -444,8 +451,14 @@ static int parse_mode(unsigned int *modep, const char *buffer, const char **buff
444451
int git_tree__parse(void *_tree, git_odb_object *odb_obj)
445452
{
446453
git_tree *tree = _tree;
447-
const char *buffer = git_odb_object_data(odb_obj);
448-
const char *buffer_end = buffer + git_odb_object_size(odb_obj);
454+
const char *buffer;
455+
const char *buffer_end;
456+
457+
if (git_odb_object_dup(&tree->odb_obj, odb_obj) < 0)
458+
return -1;
459+
460+
buffer = git_odb_object_data(tree->odb_obj);
461+
buffer_end = buffer + git_odb_object_size(tree->odb_obj);
449462

450463
git_pool_init(&tree->pool, 1);
451464
if (git_vector_init(&tree->entries, DEFAULT_TREE_SIZE, entry_sort_cmp) < 0)
@@ -466,7 +479,9 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
466479
filename_len = nul - buffer;
467480
/** Allocate the entry and store it in the entries vector */
468481
{
469-
entry = alloc_entry_pooled(&tree->pool, buffer, filename_len);
482+
/* Jump to the ID just after the path */
483+
const void *oid_ptr = buffer + filename_len + 1;
484+
entry = alloc_entry_pooled(&tree->pool, buffer, filename_len, oid_ptr);
470485
GITERR_CHECK_ALLOC(entry);
471486

472487
if (git_vector_insert(&tree->entries, entry) < 0)
@@ -475,10 +490,7 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
475490
entry->attr = attr;
476491
}
477492

478-
/* Advance to the ID just after the path */
479493
buffer += filename_len + 1;
480-
481-
git_oid_fromraw(&entry->oid, (const unsigned char *)buffer);
482494
buffer += GIT_OID_RAWSZ;
483495
}
484496

@@ -520,7 +532,7 @@ static int append_entry(
520532
entry = alloc_entry(filename);
521533
GITERR_CHECK_ALLOC(entry);
522534

523-
git_oid_cpy(&entry->oid, id);
535+
git_oid_cpy(entry->oid, id);
524536
entry->attr = (uint16_t)filemode;
525537

526538
git_strmap_insert(bld->map, entry->filename, entry, error);
@@ -712,7 +724,7 @@ int git_treebuilder_new(
712724
git_vector_foreach(&source->entries, i, entry_src) {
713725
if (append_entry(
714726
bld, entry_src->filename,
715-
&entry_src->oid,
727+
entry_src->oid,
716728
entry_src->attr) < 0)
717729
goto on_error;
718730
}
@@ -777,7 +789,7 @@ int git_treebuilder_insert(
777789
}
778790
}
779791

780-
git_oid_cpy(&entry->oid, id);
792+
git_oid_cpy(entry->oid, id);
781793
entry->attr = filemode;
782794

783795
if (entry_out)
@@ -848,7 +860,7 @@ int git_treebuilder_write(git_oid *oid, git_treebuilder *bld)
848860

849861
git_buf_printf(&tree, "%o ", entry->attr);
850862
git_buf_put(&tree, entry->filename, entry->filename_len + 1);
851-
git_buf_put(&tree, (char *)entry->oid.id, GIT_OID_RAWSZ);
863+
git_buf_put(&tree, (char *)entry->oid->id, GIT_OID_RAWSZ);
852864

853865
if (git_buf_oom(&tree))
854866
error = -1;
@@ -960,7 +972,7 @@ int git_tree_entry_bypath(
960972
return git_tree_entry_dup(entry_out, entry);
961973
}
962974

963-
if (git_tree_lookup(&subtree, root->object.repo, &entry->oid) < 0)
975+
if (git_tree_lookup(&subtree, root->object.repo, entry->oid) < 0)
964976
return -1;
965977

966978
error = git_tree_entry_bypath(
@@ -1001,7 +1013,7 @@ static int tree_walk(
10011013
git_tree *subtree;
10021014
size_t path_len = git_buf_len(path);
10031015

1004-
error = git_tree_lookup(&subtree, tree->object.repo, &entry->oid);
1016+
error = git_tree_lookup(&subtree, tree->object.repo, entry->oid);
10051017
if (error < 0)
10061018
break;
10071019

src/tree.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717
struct git_tree_entry {
1818
uint16_t attr;
1919
uint16_t filename_len;
20-
git_oid oid;
20+
git_oid *oid;
2121
bool pooled;
22-
char filename[GIT_FLEX_ARRAY];
22+
const char *filename;
2323
};
2424

2525
struct git_tree {
2626
git_object object;
27+
git_odb_object *odb_obj;
2728
git_vector entries;
2829
git_pool pool;
2930
};

tests/diff/iterator.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ static void check_tree_entry(
268268

269269
cl_git_pass(git_iterator_current_tree_entry(&te, i));
270270
cl_assert(te);
271-
cl_assert(git_oid_streq(&te->oid, oid) == 0);
271+
cl_assert(git_oid_streq(te->oid, oid) == 0);
272272

273273
cl_git_pass(git_iterator_current(&ie, i));
274274
cl_git_pass(git_buf_sets(&path, ie->path));

tests/object/tree/attributes.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ void test_object_tree_attributes__normalize_attributes_when_creating_a_tree_from
8282
cl_git_pass(git_treebuilder_new(&builder, repo, tree));
8383

8484
entry = git_treebuilder_get(builder, "old_mode.txt");
85+
cl_assert(entry != NULL);
8586
cl_assert_equal_i(
8687
GIT_FILEMODE_BLOB,
8788
git_tree_entry_filemode(entry));
@@ -92,6 +93,7 @@ void test_object_tree_attributes__normalize_attributes_when_creating_a_tree_from
9293

9394
cl_git_pass(git_tree_lookup(&tree, repo, &tid2));
9495
entry = git_tree_entry_byname(tree, "old_mode.txt");
96+
cl_assert(entry != NULL);
9597
cl_assert_equal_i(
9698
GIT_FILEMODE_BLOB,
9799
git_tree_entry_filemode(entry));

0 commit comments

Comments
 (0)