@@ -85,30 +85,26 @@ int git_tree_entry_icmp(const git_tree_entry *e1, const git_tree_entry *e2)
85
85
}
86
86
87
87
/**
88
- * Allocate either from the pool or from the system allocator
88
+ * Allocate a new self-contained entry, with enough space after it to
89
+ * store the filename and the id.
89
90
*/
90
- static git_tree_entry * alloc_entry_base ( git_pool * pool , const char * filename , size_t filename_len , const git_oid * id )
91
+ static git_tree_entry * alloc_entry ( const char * filename , size_t filename_len , const git_oid * id )
91
92
{
92
93
git_tree_entry * entry = NULL ;
93
94
size_t tree_len ;
94
95
95
96
TREE_ENTRY_CHECK_NAMELEN (filename_len );
96
- tree_len = sizeof (git_tree_entry );
97
97
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 ) ))
98
+ if (GIT_ADD_SIZET_OVERFLOW (& tree_len , sizeof ( git_tree_entry ) , filename_len ) ||
99
+ GIT_ADD_SIZET_OVERFLOW (& tree_len , tree_len , 1 ) ||
100
+ GIT_ADD_SIZET_OVERFLOW (& tree_len , tree_len , GIT_OID_RAWSZ ))
101
101
return NULL ;
102
102
103
- entry = pool ? git_pool_mallocz (pool , tree_len ) :
104
- git__calloc (1 , tree_len );
103
+ entry = git__calloc (1 , tree_len );
105
104
if (!entry )
106
105
return NULL ;
107
106
108
- if (pool ) {
109
- entry -> filename = filename ;
110
- entry -> oid = (git_oid * ) id ;
111
- } else {
107
+ {
112
108
char * filename_ptr ;
113
109
void * id_ptr ;
114
110
@@ -126,29 +122,6 @@ static git_tree_entry *alloc_entry_base(git_pool *pool, const char *filename, si
126
122
return entry ;
127
123
}
128
124
129
- /**
130
- * Allocate a tree entry, using the poolin the tree which owns
131
- * it. This is useful when reading trees, so we don't allocate a ton
132
- * of small strings but can use the pool.
133
- */
134
- static git_tree_entry * alloc_entry_pooled (git_pool * pool , const char * filename , size_t filename_len , const git_oid * id )
135
- {
136
- git_tree_entry * entry = NULL ;
137
-
138
- if (!(entry = alloc_entry_base (pool , filename , filename_len , id )))
139
- return NULL ;
140
-
141
- entry -> pooled = true;
142
-
143
- return entry ;
144
- }
145
-
146
- static git_tree_entry * alloc_entry (const char * filename )
147
- {
148
- git_oid dummy_id = { 0 };
149
- return alloc_entry_base (NULL , filename , strlen (filename ), & dummy_id );
150
- }
151
-
152
125
struct tree_key_search {
153
126
const char * filename ;
154
127
uint16_t filename_len ;
@@ -250,35 +223,35 @@ static int tree_key_search(
250
223
251
224
void git_tree_entry_free (git_tree_entry * entry )
252
225
{
253
- if (entry == NULL || entry -> pooled )
226
+ if (entry == NULL )
254
227
return ;
255
228
256
229
git__free (entry );
257
230
}
258
231
259
232
int git_tree_entry_dup (git_tree_entry * * dest , const git_tree_entry * source )
260
233
{
234
+ git_tree_entry * cpy ;
235
+
261
236
assert (source );
262
237
263
- * dest = alloc_entry_base ( NULL , source -> filename , source -> filename_len , source -> oid );
264
- if (* dest == NULL )
238
+ cpy = alloc_entry ( source -> filename , source -> filename_len , source -> oid );
239
+ if (cpy == NULL )
265
240
return -1 ;
266
241
242
+ cpy -> attr = source -> attr ;
243
+
244
+ * dest = cpy ;
267
245
return 0 ;
268
246
}
269
247
270
248
void git_tree__free (void * _tree )
271
249
{
272
250
git_tree * tree = _tree ;
273
- size_t i ;
274
- git_tree_entry * e ;
275
-
276
- git_vector_foreach (& tree -> entries , i , e )
277
- git_tree_entry_free (e );
278
251
279
252
git_odb_object_free (tree -> odb_obj );
280
253
git_vector_free (& tree -> entries );
281
- git_pool_clear ( & tree -> pool );
254
+ git_array_clear ( tree -> entries_arr );
282
255
git__free (tree );
283
256
}
284
257
@@ -450,6 +423,7 @@ static int parse_mode(unsigned int *modep, const char *buffer, const char **buff
450
423
451
424
int git_tree__parse (void * _tree , git_odb_object * odb_obj )
452
425
{
426
+ size_t i ;
453
427
git_tree * tree = _tree ;
454
428
const char * buffer ;
455
429
const char * buffer_end ;
@@ -460,9 +434,8 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
460
434
buffer = git_odb_object_data (tree -> odb_obj );
461
435
buffer_end = buffer + git_odb_object_size (tree -> odb_obj );
462
436
463
- git_pool_init (& tree -> pool , 1 );
464
- if (git_vector_init (& tree -> entries , DEFAULT_TREE_SIZE , entry_sort_cmp ) < 0 )
465
- return -1 ;
437
+ git_array_init_to_size (tree -> entries_arr , DEFAULT_TREE_SIZE );
438
+ GITERR_CHECK_ARRAY (tree -> entries_arr );
466
439
467
440
while (buffer < buffer_end ) {
468
441
git_tree_entry * entry ;
@@ -479,21 +452,28 @@ int git_tree__parse(void *_tree, git_odb_object *odb_obj)
479
452
filename_len = nul - buffer ;
480
453
/** Allocate the entry and store it in the entries vector */
481
454
{
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 );
455
+ entry = git_array_alloc (tree -> entries_arr );
485
456
GITERR_CHECK_ALLOC (entry );
486
457
487
- if (git_vector_insert (& tree -> entries , entry ) < 0 )
488
- return -1 ;
489
-
490
458
entry -> attr = attr ;
459
+ entry -> filename_len = filename_len ;
460
+ entry -> filename = buffer ;
461
+ entry -> oid = (git_oid * ) ((char * ) buffer + filename_len + 1 );
491
462
}
492
463
493
464
buffer += filename_len + 1 ;
494
465
buffer += GIT_OID_RAWSZ ;
495
466
}
496
467
468
+ /* Add the entries to the vector here, as we may reallocate during the loop */
469
+ if (git_vector_init (& tree -> entries , tree -> entries_arr .size , entry_sort_cmp ) < 0 )
470
+ return -1 ;
471
+
472
+ for (i = 0 ; i < tree -> entries_arr .size ; i ++ ) {
473
+ if (git_vector_insert (& tree -> entries , git_array_get (tree -> entries_arr , i )) < 0 )
474
+ return -1 ;
475
+ }
476
+
497
477
/* The tree is sorted by definition. Bad inputs give bad outputs */
498
478
tree -> entries .flags |= GIT_VECTOR_SORTED ;
499
479
@@ -529,10 +509,9 @@ static int append_entry(
529
509
if (!valid_entry_name (bld -> repo , filename ))
530
510
return tree_error ("Failed to insert entry. Invalid name for a tree entry" , filename );
531
511
532
- entry = alloc_entry (filename );
512
+ entry = alloc_entry (filename , strlen ( filename ), id );
533
513
GITERR_CHECK_ALLOC (entry );
534
514
535
- git_oid_cpy (entry -> oid , id );
536
515
entry -> attr = (uint16_t )filemode ;
537
516
538
517
git_strmap_insert (bld -> map , entry -> filename , entry , error );
@@ -776,8 +755,9 @@ int git_treebuilder_insert(
776
755
pos = git_strmap_lookup_index (bld -> map , filename );
777
756
if (git_strmap_valid_index (bld -> map , pos )) {
778
757
entry = git_strmap_value_at (bld -> map , pos );
758
+ git_oid_cpy ((git_oid * ) entry -> oid , id );
779
759
} else {
780
- entry = alloc_entry (filename );
760
+ entry = alloc_entry (filename , strlen ( filename ), id );
781
761
GITERR_CHECK_ALLOC (entry );
782
762
783
763
git_strmap_insert (bld -> map , entry -> filename , entry , error );
@@ -789,7 +769,6 @@ int git_treebuilder_insert(
789
769
}
790
770
}
791
771
792
- git_oid_cpy (entry -> oid , id );
793
772
entry -> attr = filemode ;
794
773
795
774
if (entry_out )
0 commit comments